{"$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":"D7","name":"Architectural Integrity","shortDescription":{"text":"Architectural Integrity"},"helpUri":"https://codehealth.canine.dev/dimensions/D7"},{"id":"D8","name":"Code Coverage","shortDescription":{"text":"Code Coverage"},"helpUri":"https://codehealth.canine.dev/dimensions/D8"},{"id":"D9","name":"Test Distribution","shortDescription":{"text":"Test Distribution"},"helpUri":"https://codehealth.canine.dev/dimensions/D9"},{"id":"D10","name":"Test Quality","shortDescription":{"text":"Test Quality"},"helpUri":"https://codehealth.canine.dev/dimensions/D10"},{"id":"D12","name":"Dependency Hygiene","shortDescription":{"text":"Dependency Hygiene"},"helpUri":"https://codehealth.canine.dev/dimensions/D12"},{"id":"D13","name":"Secret Scanning","shortDescription":{"text":"Secret Scanning"},"helpUri":"https://codehealth.canine.dev/dimensions/D13","relationships":[{"target":{"id":"CWE-798","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},"kinds":["relevant"]},{"target":{"id":"CWE-259","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},"kinds":["relevant"]}],"properties":{"cwe":["CWE-798","CWE-259"]}},{"id":"D14","name":"License Compliance","shortDescription":{"text":"License Compliance"},"helpUri":"https://codehealth.canine.dev/dimensions/D14"},{"id":"D15","name":"Churn \u00D7 Complexity Hotspots","shortDescription":{"text":"Churn \u00D7 Complexity Hotspots"},"helpUri":"https://codehealth.canine.dev/dimensions/D15"},{"id":"D17","name":"Explicit Debt","shortDescription":{"text":"Explicit Debt"},"helpUri":"https://codehealth.canine.dev/dimensions/D17"},{"id":"D19","name":"Documentation Quality","shortDescription":{"text":"Documentation Quality"},"helpUri":"https://codehealth.canine.dev/dimensions/D19"},{"id":"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":"D22","name":"Internal API Consistency","shortDescription":{"text":"Internal API Consistency"},"helpUri":"https://codehealth.canine.dev/dimensions/D22"},{"id":"D28","name":"Secrets (history)","shortDescription":{"text":"Secrets (history)"},"helpUri":"https://codehealth.canine.dev/dimensions/D28","relationships":[{"target":{"id":"CWE-798","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},"kinds":["relevant"]},{"target":{"id":"CWE-259","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},"kinds":["relevant"]}],"properties":{"cwe":["CWE-798","CWE-259"]}},{"id":"D29","name":"Static Analysis (SAST)","shortDescription":{"text":"Static Analysis (SAST)"},"helpUri":"https://codehealth.canine.dev/dimensions/D29","relationships":[{"target":{"id":"CWE-79","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},"kinds":["relevant"]},{"target":{"id":"CWE-89","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},"kinds":["relevant"]},{"target":{"id":"CWE-78","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},"kinds":["relevant"]},{"target":{"id":"CWE-94","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},"kinds":["relevant"]},{"target":{"id":"CWE-77","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},"kinds":["relevant"]}],"properties":{"cwe":["CWE-79","CWE-89","CWE-78","CWE-94","CWE-77"]}},{"id":"D30","name":"Dependency Vulnerabilities","shortDescription":{"text":"Dependency Vulnerabilities"},"helpUri":"https://codehealth.canine.dev/dimensions/D30","relationships":[{"target":{"id":"CWE-1395","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},"kinds":["relevant"]},{"target":{"id":"CWE-937","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},"kinds":["relevant"]}],"properties":{"cwe":["CWE-1395","CWE-937"]}},{"id":"D34","name":"Knowledge Freshness","shortDescription":{"text":"Knowledge Freshness"},"helpUri":"https://codehealth.canine.dev/dimensions/D34"},{"id":"D35","name":"Change Coupling","shortDescription":{"text":"Change Coupling"},"helpUri":"https://codehealth.canine.dev/dimensions/D35"},{"id":"D36","name":"Supply-chain Provenance \u0026 Signing","shortDescription":{"text":"Supply-chain Provenance \u0026 Signing"},"helpUri":"https://codehealth.canine.dev/dimensions/D36","relationships":[{"target":{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},"kinds":["relevant"]},{"target":{"id":"CWE-494","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},"kinds":["relevant"]}],"properties":{"cwe":["CWE-1357","CWE-494"]}},{"id":"D37","name":"Vulnerability-disclosure Policy","shortDescription":{"text":"Vulnerability-disclosure Policy"},"helpUri":"https://codehealth.canine.dev/dimensions/D37","relationships":[{"target":{"id":"CWE-1059","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},"kinds":["relevant"]}],"properties":{"cwe":["CWE-1059"]}},{"id":"D43","name":"Malicious Dependencies","shortDescription":{"text":"Malicious Dependencies"},"helpUri":"https://codehealth.canine.dev/dimensions/D43","relationships":[{"target":{"id":"CWE-506","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},"kinds":["relevant"]}],"properties":{"cwe":["CWE-506"]}},{"id":"D44","name":"Platform End-of-Life","shortDescription":{"text":"Platform End-of-Life"},"helpUri":"https://codehealth.canine.dev/dimensions/D44"},{"id":"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":"AC4","name":"Keyboard semantics","shortDescription":{"text":"Keyboard semantics"},"helpUri":"https://codehealth.canine.dev/dimensions/AC4"},{"id":"AC5","name":"ARIA correctness","shortDescription":{"text":"ARIA correctness"},"helpUri":"https://codehealth.canine.dev/dimensions/AC5"},{"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":"AX9","name":"CQS / query purity","shortDescription":{"text":"CQS / query purity"},"helpUri":"https://codehealth.canine.dev/dimensions/AX9"},{"id":"AXB2","name":"Runtime readiness","shortDescription":{"text":"Runtime readiness"},"helpUri":"https://codehealth.canine.dev/dimensions/AXB2"},{"id":"M1","name":"Documentation (README)","shortDescription":{"text":"Documentation (README)"},"helpUri":"https://codehealth.canine.dev/dimensions/M1"},{"id":"M2","name":"Architecture documentation","shortDescription":{"text":"Architecture documentation"},"helpUri":"https://codehealth.canine.dev/dimensions/M2"},{"id":"M3","name":"Folder \u0026 project structure","shortDescription":{"text":"Folder \u0026 project structure"},"helpUri":"https://codehealth.canine.dev/dimensions/M3"},{"id":"M4","name":"Documentation accuracy","shortDescription":{"text":"Documentation accuracy"},"helpUri":"https://codehealth.canine.dev/dimensions/M4"},{"id":"P1","name":"CI/CD gates","shortDescription":{"text":"CI/CD gates"},"helpUri":"https://codehealth.canine.dev/dimensions/P1"},{"id":"P12","name":"CI test-gate honesty","shortDescription":{"text":"CI test-gate honesty"},"helpUri":"https://codehealth.canine.dev/dimensions/P12"},{"id":"P3","name":"Security \u0026 performance tooling","shortDescription":{"text":"Security \u0026 performance tooling"},"helpUri":"https://codehealth.canine.dev/dimensions/P3"},{"id":"P4","name":"Deployment \u0026 Rollback","shortDescription":{"text":"Deployment \u0026 Rollback"},"helpUri":"https://codehealth.canine.dev/dimensions/P4"},{"id":"P5","name":"DR \u0026 Backup","shortDescription":{"text":"DR \u0026 Backup"},"helpUri":"https://codehealth.canine.dev/dimensions/P5"},{"id":"P6","name":"Release Hygiene","shortDescription":{"text":"Release Hygiene"},"helpUri":"https://codehealth.canine.dev/dimensions/P6"},{"id":"R1","name":"Type Safety","shortDescription":{"text":"Type Safety"},"helpUri":"https://codehealth.canine.dev/dimensions/R1"},{"id":"R10","name":"Code Duplication","shortDescription":{"text":"Code Duplication"},"helpUri":"https://codehealth.canine.dev/dimensions/R10"},{"id":"R2","name":"Cyclomatic Complexity","shortDescription":{"text":"Cyclomatic Complexity"},"helpUri":"https://codehealth.canine.dev/dimensions/R2"},{"id":"R3","name":"Large Files","shortDescription":{"text":"Large Files"},"helpUri":"https://codehealth.canine.dev/dimensions/R3"},{"id":"R4","name":"Test Coverage","shortDescription":{"text":"Test Coverage"},"helpUri":"https://codehealth.canine.dev/dimensions/R4"},{"id":"R5","name":"Dependency Freshness","shortDescription":{"text":"Dependency Freshness"},"helpUri":"https://codehealth.canine.dev/dimensions/R5"},{"id":"R6","name":"Tooling","shortDescription":{"text":"Tooling"},"helpUri":"https://codehealth.canine.dev/dimensions/R6"},{"id":"R7","name":"Dead Code","shortDescription":{"text":"Dead Code"},"helpUri":"https://codehealth.canine.dev/dimensions/R7"},{"id":"R8","name":"Dependency Hygiene","shortDescription":{"text":"Dependency Hygiene"},"helpUri":"https://codehealth.canine.dev/dimensions/R8"},{"id":"R9","name":"Circular Imports","shortDescription":{"text":"Circular Imports"},"helpUri":"https://codehealth.canine.dev/dimensions/R9"},{"id":"S1","name":"Web-Security Posture","shortDescription":{"text":"Web-Security Posture"},"helpUri":"https://codehealth.canine.dev/dimensions/S1"},{"id":"SC1","name":"Supply-chain hygiene","shortDescription":{"text":"Supply-chain hygiene"},"helpUri":"https://codehealth.canine.dev/dimensions/SC1"},{"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":"useChatStreamingLifecycle.useChatStreamingLifecycle (cyclomatic 587): useChatStreamingLifecycle.useChatStreamingLifecycle has cyclomatic complexity 587 (threshold 15). Most of this is not in the body itself: 8 of the 587 points are its own statements and the rest belongs to 60 function literals inside it that branch (lines 2302, 1235, 3756, \u2026). The decisions are inside those literals, which nothing outside this body can call, review or test on its own, so splitting the enclosing body is not the move available here. To reduce it, lift the literals\u0027 work into a named function or method at the enclosing scope and have each literal call it, then reduce whichever part then reads as the largest."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/hooks/useChatStreamingLifecycle.ts"},"region":{"startLine":1030}}}],"partialFingerprints":{"codehealthFindingId/v1":"b0f3ea9c18e6867ec144fbcbf98381417b68a88ee4c0f87144204fcea2f9436c"}},{"ruleId":"D1","level":"warning","message":{"text":"ChatPage.ChatPage (cyclomatic 470): ChatPage.ChatPage has cyclomatic complexity 470 (threshold 15). Of this number, 20 points are the body\u0027s own statements and 450 belong to 87 function literals inside it that branch. 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":"desktop/src/pages/ChatPage.tsx"},"region":{"startLine":129}}}],"partialFingerprints":{"codehealthFindingId/v1":"b4d805d885b2a6bc93fef5c76456f905693fb1afb8fd6b211e03441075cf6196"}},{"ruleId":"D1","level":"warning","message":{"text":"FileEditorCore.FileEditorCore (cyclomatic 220): FileEditorCore.FileEditorCore has cyclomatic complexity 220 (threshold 15). Of this number, 94 points are the body\u0027s own statements and 126 belong to 47 function literals inside it that branch. 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":"desktop/src/components/common/FileEditorCore.tsx"},"region":{"startLine":606}}}],"partialFingerprints":{"codehealthFindingId/v1":"c7bb2de5fe95d0c86fe1e6648bc01aa53316dadf2a807a240f8849736a5376ee"}},{"ruleId":"D1","level":"warning","message":{"text":"pipeline_validator.validate (cyclomatic 214): pipeline_validator.validate has cyclomatic complexity 214 (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":"backend/scripts/pipeline_validator.py"},"region":{"startLine":2603}}}],"partialFingerprints":{"codehealthFindingId/v1":"433c5f4c88dff9385ffcfaa8baf052c488d9b0db40d50123a20ee746a63c4fac"}},{"ruleId":"D1","level":"warning","message":{"text":"StreamingOrchestrator._read_formatted_response (cyclomatic 190): StreamingOrchestrator._read_formatted_response has cyclomatic complexity 190 (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":"backend/core/streaming_orchestrator.py"},"region":{"startLine":525}}}],"partialFingerprints":{"codehealthFindingId/v1":"a6d0d05febe6b8f6fc314dd3dbd69533e6393891b2a198ea6942066ca16c1936"}},{"ruleId":"D1","level":"warning","message":{"text":"artifact_cli.cmd_run_report (cyclomatic 177): artifact_cli.cmd_run_report has cyclomatic complexity 177 (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":"backend/scripts/artifact_cli.py"},"region":{"startLine":3992}}}],"partialFingerprints":{"codehealthFindingId/v1":"9e47703fa17406a665a7a5aec7f49bd1932a4bc613c4188e688c22c4f8fa1d17"}},{"ruleId":"D1","level":"warning","message":{"text":"ChatInput.ChatInput (cyclomatic 161): ChatInput.ChatInput has cyclomatic complexity 161 (threshold 15). Of this number, 54 points are the body\u0027s own statements and 107 belong to 38 function literals inside it that branch. 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":"desktop/src/pages/chat/components/ChatInput.tsx"},"region":{"startLine":164}}}],"partialFingerprints":{"codehealthFindingId/v1":"bcc7bcae833869f92116460cb85e6900b4d5db80b7f0390ecee3a5efccbd08c8"}},{"ruleId":"D1","level":"warning","message":{"text":"ChannelGateway._handle_conversation (cyclomatic 158): ChannelGateway._handle_conversation has cyclomatic complexity 158 (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":"backend/channels/gateway.py"},"region":{"startLine":1619}}}],"partialFingerprints":{"codehealthFindingId/v1":"0218e9440c79cfdd5d2b126dfcaccc7e8a92004e7f346f34434672e487b0eb6a"}},{"ruleId":"D1","level":"warning","message":{"text":"html2pptx.extractSlideData (cyclomatic 157): html2pptx.extractSlideData has cyclomatic complexity 157 (threshold 15). Most of this is not in the body itself: 1 of the 157 points is its own statement and the rest belongs to 15 function literals inside it that branch (lines 534, 422, 365, \u2026). The decisions are inside those literals, which nothing outside this body can call, review or test on its own, so splitting the enclosing body is not the move available here. To reduce it, lift the literals\u0027 work into a named function or method at the enclosing scope and have each literal call it, then reduce whichever part then reads as the largest."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/skills/s_pptx/scripts/html2pptx.js"},"region":{"startLine":244}}}],"partialFingerprints":{"codehealthFindingId/v1":"8068cb45077f4b20436fb6cc206597f9a9b6b90614e6c6150f84d2103bada676"}},{"ruleId":"D1","level":"warning","message":{"text":"artifact_cli.cmd_run_update (cyclomatic 148): artifact_cli.cmd_run_update has cyclomatic complexity 148 (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":"backend/scripts/artifact_cli.py"},"region":{"startLine":1797}}}],"partialFingerprints":{"codehealthFindingId/v1":"e7e40e3651b1c953446096e9a325b92919c05b18f0418cc4c9ef629263259b9f"}},{"ruleId":"D1","level":"warning","message":{"text":"SkillsPage.GenerateSkillForm (cyclomatic 108): SkillsPage.GenerateSkillForm has cyclomatic complexity 108 (threshold 15). Of this number, 27 points are the body\u0027s own statements and 81 belong to 20 function literals inside it that branch. 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":"desktop/src/pages/SkillsPage.tsx"},"region":{"startLine":327}}}],"partialFingerprints":{"codehealthFindingId/v1":"accb4f36bbb2ac21c9f949cb79e940b82008dffc3b495ee895f09cd8a2da874c"}},{"ruleId":"D1","level":"warning","message":{"text":"FileViewer.FileViewerImpl (cyclomatic 105): FileViewer.FileViewerImpl has cyclomatic complexity 105 (threshold 15). Of this number, 34 points are the body\u0027s own statements and 71 belong to 14 function literals inside it that branch. 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":"desktop/src/components/file-viewer/FileViewer.tsx"},"region":{"startLine":126}}}],"partialFingerprints":{"codehealthFindingId/v1":"813ebf1fcf9c0dfc8954e41b7c2aab33c86e16de0011e9d68ac77b388293aa18"}},{"ruleId":"D1","level":"warning","message":{"text":"evolution_optimizer._run_evolution_cycle_locked (cyclomatic 97): evolution_optimizer._run_evolution_cycle_locked has cyclomatic complexity 97 (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":"backend/core/evolution_optimizer.py"},"region":{"startLine":1148}}}],"partialFingerprints":{"codehealthFindingId/v1":"1d0e037bf2aa368cb7baeccccd2868f7a18e44b31a4c8c696d4125c824c7ce27"}},{"ruleId":"D1","level":"warning","message":{"text":"main (cyclomatic 96): main has cyclomatic complexity 96 (threshold 15). Of this number, 93 points are the body\u0027s own statements and 3 belong to 8 function literals inside it that branch. 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":"backend/skills/s_browser-agent/browser-agent.mjs"},"region":{"startLine":304}}}],"partialFingerprints":{"codehealthFindingId/v1":"a646b454fd88539fefbf6fa5de76bb51a1eac43c026f64bb564564079132dc0d"}},{"ruleId":"D1","level":"warning","message":{"text":"SessionRouter.run_conversation (cyclomatic 90): SessionRouter.run_conversation has cyclomatic complexity 90 (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":"backend/core/session_router.py"},"region":{"startLine":2782}}}],"partialFingerprints":{"codehealthFindingId/v1":"8e70b64f6e475387b792221b5dec7569f385078f1a0afdcd8f8d69998f526d15"}},{"ruleId":"D1","level":"warning","message":{"text":"eval_runner.generate_html_report (cyclomatic 86): eval_runner.generate_html_report has cyclomatic complexity 86 (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":"backend/scripts/eval_runner.py"},"region":{"startLine":2163}}}],"partialFingerprints":{"codehealthFindingId/v1":"56b91b681083369ba597f0f7d17bc16f363a977450669a8e9cf43b84fa859690"}},{"ruleId":"D1","level":"warning","message":{"text":"TabView.TabViewImpl (cyclomatic 81): TabView.TabViewImpl has cyclomatic complexity 81 (threshold 15). Of this number, 22 points are the body\u0027s own statements and 59 belong to 10 function literals inside it that branch. 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":"desktop/src/pages/chat/components/TabView.tsx"},"region":{"startLine":208}}}],"partialFingerprints":{"codehealthFindingId/v1":"ac373068339fa33fa460364e51bfd34b1da800c0a3ce11247edd5ddbd4826f47"}},{"ruleId":"D1","level":"warning","message":{"text":"AuthConfigPanel.AuthConfigPanel (cyclomatic 75): AuthConfigPanel.AuthConfigPanel has cyclomatic complexity 75 (threshold 15). Of this number, 32 points are the body\u0027s own statements and 43 belong to 8 function literals inside it that branch. 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":"desktop/src/components/settings/AuthConfigPanel.tsx"},"region":{"startLine":29}}}],"partialFingerprints":{"codehealthFindingId/v1":"984ff45c4f448d9cd579774dc57eee2e3e766b8c1fdc583d9496aa01651ce162"}},{"ruleId":"D1","level":"warning","message":{"text":"proactive_intelligence.build_session_briefing_data (cyclomatic 69): proactive_intelligence.build_session_briefing_data 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":"backend/core/proactive_intelligence.py"},"region":{"startLine":1884}}}],"partialFingerprints":{"codehealthFindingId/v1":"eba8c2e77334e071c9e87e9aac16225e66406a2a39639e176db0999a00194401"}},{"ruleId":"D1","level":"warning","message":{"text":"DistillationTriggerHook._distill_files (cyclomatic 69): DistillationTriggerHook._distill_files 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":"backend/hooks/distillation_hook.py"},"region":{"startLine":451}}}],"partialFingerprints":{"codehealthFindingId/v1":"6dc7ffc5045f4bcbb041ca7548c1e73cf14ae212b58a1868aa1c5f55afb94f87"}},{"ruleId":"D1","level":"warning","message":{"text":"AssistantMessageView.AssistantMessageView (cyclomatic 68): AssistantMessageView.AssistantMessageView has cyclomatic complexity 68 (threshold 15). Of this number, 47 points are the body\u0027s own statements and 21 belong to 6 function literals inside it that branch. 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":"desktop/src/pages/chat/components/AssistantMessageView.tsx"},"region":{"startLine":77}}}],"partialFingerprints":{"codehealthFindingId/v1":"1572d22dccdb7ee03f540db6b828aa58f61937bf956fd1517c4ec1f4bcbb4e9c"}},{"ruleId":"D1","level":"warning","message":{"text":"confidence_score.calculate_score (cyclomatic 66): confidence_score.calculate_score has cyclomatic complexity 66 (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":"backend/skills/s_autonomous-pipeline/scripts/confidence_score.py"},"region":{"startLine":71}}}],"partialFingerprints":{"codehealthFindingId/v1":"a1ecf817a7509c7975e0baba8093c82fa50998187615fcee76a9eced13182a5e"}},{"ruleId":"D1","level":"warning","message":{"text":"SessionUnit.send (cyclomatic 65): SessionUnit.send has cyclomatic complexity 65 (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":"backend/core/session_unit.py"},"region":{"startLine":1867}}}],"partialFingerprints":{"codehealthFindingId/v1":"662e32104f4c0a3e94bf1ba87a6f9e5854b807109e3717c4a8c29069bd07a3dd"}},{"ruleId":"D1","level":"warning","message":{"text":"executor.execute_job (cyclomatic 64): executor.execute_job 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":"backend/jobs/executor.py"},"region":{"startLine":154}}}],"partialFingerprints":{"codehealthFindingId/v1":"ead64ccd54b7001b24ab2b74d7599ca63334428c7d34e11d21ca5103397e87dd"}},{"ruleId":"D1","level":"warning","message":{"text":"proactive_intelligence._advance_pipeline_recovery_state (cyclomatic 63): proactive_intelligence._advance_pipeline_recovery_state has cyclomatic complexity 63 (threshold 15). To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/core/proactive_intelligence.py"},"region":{"startLine":816}}}],"partialFingerprints":{"codehealthFindingId/v1":"14e2b4800e82bc9df634326a3b72d0804353d868c82bce4b7adffc6551e41e36"}},{"ruleId":"D1","level":"warning","message":{"text":"PromptBuilder.build_system_prompt (cyclomatic 61): PromptBuilder.build_system_prompt has cyclomatic complexity 61 (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":"backend/core/prompt_builder.py"},"region":{"startLine":825}}}],"partialFingerprints":{"codehealthFindingId/v1":"dabc2900590db325f81bf0087fac052b936977ab04cc6f26f5c3a61ecd1a95b3"}},{"ruleId":"D1","level":"warning","message":{"text":"pipeline_validator._check_depth (cyclomatic 59): pipeline_validator._check_depth 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":"backend/scripts/pipeline_validator.py"},"region":{"startLine":1995}}}],"partialFingerprints":{"codehealthFindingId/v1":"7f1c848c79d9efb4172f112286b3510329b58d599c0a490962b7497a9fd3877b"}},{"ruleId":"D1","level":"warning","message":{"text":"BackendStartupOverlay.BackendStartupOverlay (cyclomatic 59): BackendStartupOverlay.BackendStartupOverlay has cyclomatic complexity 59 (threshold 15). Most of this is not in the body itself: 14 of the 59 points are its own statements and the rest belongs to 14 function literals inside it that branch (lines 438, 403, 358, \u2026). The decisions are inside those literals, which nothing outside this body can call, review or test on its own, so splitting the enclosing body is not the move available here. To reduce it, lift the literals\u0027 work into a named function or method at the enclosing scope and have each literal call it, then reduce whichever part then reads as the largest."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/common/BackendStartupOverlay.tsx"},"region":{"startLine":241}}}],"partialFingerprints":{"codehealthFindingId/v1":"1c07ac9825c71232b75adefe0c2c070fcaccef05308cf6c0df73e8109107e7d2"}},{"ruleId":"D1","level":"warning","message":{"text":"security_hooks._segment_is_irreversible (cyclomatic 58): security_hooks._segment_is_irreversible 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":"backend/core/security_hooks.py"},"region":{"startLine":284}}}],"partialFingerprints":{"codehealthFindingId/v1":"7098fd87b7b387ce93221f990fb2e6c60a7d38f64ce1d59357c4f44cd5d5f504"}},{"ruleId":"D1","level":"warning","message":{"text":"browser-agent.compressDOM (cyclomatic 58): browser-agent.compressDOM has cyclomatic complexity 58 (threshold 15). Most of this is not in the body itself: 1 of the 58 points is its own statement and the rest belongs to one function literal inside it that branches (line 128). The decisions are inside the literal, which nothing outside this body can call, review or test on its own, so splitting the enclosing body is not the move available here. To reduce it, lift the literal\u0027s work into a named function or method at the enclosing scope and have the literal call it, then reduce whichever part then reads as the largest."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/skills/s_browser-agent/browser-agent.mjs"},"region":{"startLine":127}}}],"partialFingerprints":{"codehealthFindingId/v1":"91c1f3ebc99462f3e31daf8d5bc25e355fe2e2f33edb8c250ffcd3e6449cc3c2"}},{"ruleId":"D1","level":"warning","message":{"text":"useVoiceRecorder.useVoiceRecorder (cyclomatic 57): useVoiceRecorder.useVoiceRecorder has cyclomatic complexity 57 (threshold 15). Most of this is not in the body itself: 3 of the 57 points are its own statements and the rest belongs to 8 function literals inside it that branch (lines 245, 99, 78, \u2026). The decisions are inside those literals, which nothing outside this body can call, review or test on its own, so splitting the enclosing body is not the move available here. To reduce it, lift the literals\u0027 work into a named function or method at the enclosing scope and have each literal call it, then reduce whichever part then reads as the largest."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/hooks/useVoiceRecorder.ts"},"region":{"startLine":48}}}],"partialFingerprints":{"codehealthFindingId/v1":"ed6046a40dbfa9976acf88024c0e41d1aad0773eff36ca2d3b3b2fb5ea7aa378"}},{"ruleId":"D1","level":"warning","message":{"text":"swarmai_monthly_report._generate_monthly_report (cyclomatic 56): swarmai_monthly_report._generate_monthly_report has cyclomatic complexity 56 (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":"backend/jobs/handlers/swarmai_monthly_report.py"},"region":{"startLine":589}}}],"partialFingerprints":{"codehealthFindingId/v1":"15937f56db9ac61beeddb541c37d49c083906f6010ca70d67f1d786292831ccd"}},{"ruleId":"D1","level":"warning","message":{"text":"AgentFormModal.AgentFormModal (cyclomatic 55): AgentFormModal.AgentFormModal has cyclomatic complexity 55 (threshold 15). Of this number, 26 points are the body\u0027s own statements and 29 belong to 7 function literals inside it that branch. 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":"desktop/src/components/common/AgentFormModal.tsx"},"region":{"startLine":36}}}],"partialFingerprints":{"codehealthFindingId/v1":"ce608a3f5ae8d192c7ba979d2b6d953c2ff2e58dc28711f5490edd4fe4b980e6"}},{"ruleId":"D1","level":"warning","message":{"text":"streaming-machine.streamingReducer (cyclomatic 53): streaming-machine.streamingReducer has cyclomatic complexity 53 (threshold 15). To reduce it, keep the dispatch but shrink the arms: move each non-trivial case body into its own named function (or onto the value being matched) so the dispatch reads one line per case, and group related cases into a sub-dispatch. Where every arm is uniform \u2014 the same kind of value, with no behaviour of its own \u2014 a table keyed by the case is the shorter form; wherever the arms carry different data or different behaviour, keep them as cases, because collapsing those trades an explicit, reviewable set of cases for nothing."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/hooks/streaming-machine.ts"},"region":{"startLine":110}}}],"partialFingerprints":{"codehealthFindingId/v1":"0fa4804687a06aa7028fad5d783e7684ab3a4cc00ad625f9a4542376ad52d478"}},{"ruleId":"D1","level":"warning","message":{"text":"CsvRenderer.CsvRenderer (cyclomatic 53): CsvRenderer.CsvRenderer has cyclomatic complexity 53 (threshold 15). Of this number, 19 points are the body\u0027s own statements and 34 belong to 13 function literals inside it that branch. 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":"desktop/src/components/file-viewer/renderers/CsvRenderer.tsx"},"region":{"startLine":48}}}],"partialFingerprints":{"codehealthFindingId/v1":"979053806d9e5c3d68b4a4cd2b6200e883cf2075573b8acec61bd615ef34561e"}},{"ruleId":"D1","level":"warning","message":{"text":"tool_summarizer.summarize_tool_use (cyclomatic 52): tool_summarizer.summarize_tool_use has cyclomatic complexity 52 (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":"backend/core/tool_summarizer.py"},"region":{"startLine":150}}}],"partialFingerprints":{"codehealthFindingId/v1":"c2c855e42f246097ac322efbe9f4453a7312fd3a549eb56d0e58a45da94fbd89"}},{"ruleId":"D1","level":"warning","message":{"text":"artifact_cli._extract_run_metrics (cyclomatic 51): artifact_cli._extract_run_metrics 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":"backend/scripts/artifact_cli.py"},"region":{"startLine":4783}}}],"partialFingerprints":{"codehealthFindingId/v1":"ae0b1db55977f6488bbf51123f97b349702dc0d5786cf191e1b8f4973cb819eb"}},{"ruleId":"D1","level":"warning","message":{"text":"useUnifiedTabState.useUnifiedTabState (cyclomatic 48): useUnifiedTabState.useUnifiedTabState has cyclomatic complexity 48 (threshold 15). Most of this is not in the body itself: 2 of the 48 points are its own statements and the rest belongs to 19 function literals inside it that branch (lines 767, 559, 477, \u2026). The decisions are inside those literals, which nothing outside this body can call, review or test on its own, so splitting the enclosing body is not the move available here. To reduce it, lift the literals\u0027 work into a named function or method at the enclosing scope and have each literal call it, then reduce whichever part then reads as the largest."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/hooks/useUnifiedTabState.ts"},"region":{"startLine":419}}}],"partialFingerprints":{"codehealthFindingId/v1":"a9258ff2901b964c783ae713c8cc67eb4fdfd8c36eef092159de5b3a11baad8d"}},{"ruleId":"D1","level":"warning","message":{"text":"FileViewerPanel.FileViewerPanelImpl (cyclomatic 48): FileViewerPanel.FileViewerPanelImpl has cyclomatic complexity 48 (threshold 15). Of this number, 37 points are the body\u0027s own statements and 11 belong to 7 function literals inside it that branch. 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":"desktop/src/components/file-viewer/FileViewerPanel.tsx"},"region":{"startLine":139}}}],"partialFingerprints":{"codehealthFindingId/v1":"de0b172c16109c54ae80cffde3edb499e2cd550cb3a90cc4e663c1341fffb18f"}},{"ruleId":"D1","level":"warning","message":{"text":"AIModelsTab.AIModelsTab (cyclomatic 46): AIModelsTab.AIModelsTab has cyclomatic complexity 46 (threshold 15). Most of this is not in the body itself: 9 of the 46 points are its own statements and the rest belongs to 14 function literals inside it that branch (lines 83, 46, 56, \u2026). The decisions are inside those literals, which nothing outside this body can call, review or test on its own, so splitting the enclosing body is not the move available here. To reduce it, lift the literals\u0027 work into a named function or method at the enclosing scope and have each literal call it, then reduce whichever part then reads as the largest."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/settings/AIModelsTab.tsx"},"region":{"startLine":15}}}],"partialFingerprints":{"codehealthFindingId/v1":"a3974e9eebb10ad13a98676eb311877b6d23338811a55be401227a3df7cca03b"}},{"ruleId":"D1","level":"warning","message":{"text":"main.lifespan (cyclomatic 45): main.lifespan has cyclomatic complexity 45 (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":"backend/main.py"},"region":{"startLine":938}}}],"partialFingerprints":{"codehealthFindingId/v1":"5589860499bc0824c36cb9ca095ccf1e13d68b0e37af0b34fe6bd07a816b2861"}},{"ruleId":"D1","level":"warning","message":{"text":"pipeline_validator.validate_artifact_data (cyclomatic 45): pipeline_validator.validate_artifact_data has cyclomatic complexity 45 (threshold 15). To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/scripts/pipeline_validator.py"},"region":{"startLine":1270}}}],"partialFingerprints":{"codehealthFindingId/v1":"d79f75efd886c6136b0b833a6288df988f37bcd333577dd9b97e5121e676ef9c"}},{"ruleId":"D1","level":"warning","message":{"text":"CapabilitiesOverlay.CapabilitiesContent (cyclomatic 45): CapabilitiesOverlay.CapabilitiesContent has cyclomatic complexity 45 (threshold 15). Of this number, 23 points are the body\u0027s own statements and 22 belong to 14 function literals inside it that branch. 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":"desktop/src/components/layout/CapabilitiesOverlay.tsx"},"region":{"startLine":173}}}],"partialFingerprints":{"codehealthFindingId/v1":"4ac624622a606d9602a7897f1eceb1fc534599233aa86edbde9ef5a3c023f020"}},{"ruleId":"D1","level":"warning","message":{"text":"security_hooks._pending_commit_paths (cyclomatic 44): security_hooks._pending_commit_paths 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":"backend/core/security_hooks.py"},"region":{"startLine":1729}}}],"partialFingerprints":{"codehealthFindingId/v1":"3941bc94e5a5991877ac14ef9b559dc53e10cd9a833e1527493e62e63856b9ed"}},{"ruleId":"D1","level":"warning","message":{"text":"scheduler.run_scheduler (cyclomatic 44): scheduler.run_scheduler 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":"backend/jobs/scheduler.py"},"region":{"startLine":472}}}],"partialFingerprints":{"codehealthFindingId/v1":"0fe6c18789d3fde4e39b035a1c63810777b1db73eeaf979ebf5172f766d77da9"}},{"ruleId":"D1","level":"warning","message":{"text":"useVoiceConversation.useVoiceConversation (cyclomatic 44): useVoiceConversation.useVoiceConversation has cyclomatic complexity 44 (threshold 15). Most of this is not in the body itself: 1 of the 44 points is its own statement and the rest belongs to 13 function literals inside it that branch (lines 179, 264, 149, \u2026). The decisions are inside those literals, which nothing outside this body can call, review or test on its own, so splitting the enclosing body is not the move available here. To reduce it, lift the literals\u0027 work into a named function or method at the enclosing scope and have each literal call it, then reduce whichever part then reads as the largest."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/hooks/useVoiceConversation.ts"},"region":{"startLine":75}}}],"partialFingerprints":{"codehealthFindingId/v1":"df18ced0cd3ef5afe75d090b5980ebdd41e15a7dddf7494fa3b5fed4560df8e2"}},{"ruleId":"D1","level":"warning","message":{"text":"memory_health._compress_evolution_entries (cyclomatic 43): memory_health._compress_evolution_entries 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":"backend/jobs/handlers/memory_health.py"},"region":{"startLine":614}}}],"partialFingerprints":{"codehealthFindingId/v1":"ebeca11773807193e9dc4bb2e89bf9024c720f3725f484d0a5702e0396444a12"}},{"ruleId":"D1","level":"warning","message":{"text":"code_intel_reindex.reindex_projects (cyclomatic 40): code_intel_reindex.reindex_projects 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":"backend/jobs/handlers/code_intel_reindex.py"},"region":{"startLine":20}}}],"partialFingerprints":{"codehealthFindingId/v1":"c8fae7709aa08fd95b96f32883e4dfeeee4d43ee22d0eebf4dce492ecefb9373"}},{"ruleId":"D1","level":"warning","message":{"text":"workspace_api.resolve_path_to_physical (cyclomatic 40): workspace_api.resolve_path_to_physical 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":"backend/routers/workspace_api.py"},"region":{"startLine":992}}}],"partialFingerprints":{"codehealthFindingId/v1":"b1e9dd8f644eafba39c2546fef6078cc1cdd81f3f19e2e71d68b3a529db97c96"}},{"ruleId":"D1","level":"warning","message":{"text":"ai_ready_helpers.extract_import_graph (cyclomatic 40): ai_ready_helpers.extract_import_graph 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":"backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py"},"region":{"startLine":2388}}}],"partialFingerprints":{"codehealthFindingId/v1":"d6f40fad422a0783c359a8a3aa998b1902e9b2d5351719742555d0048901f193"}},{"ruleId":"D1","level":"warning","message":{"text":"ai_ready_helpers.extract_import_graph (cyclomatic 40): ai_ready_helpers.extract_import_graph 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":"backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py"},"region":{"startLine":2041}}}],"partialFingerprints":{"codehealthFindingId/v1":"694806463cf8f6e693306ea249555fdb28d0386b9fa0d102198e7fc8b51f328b"}},{"ruleId":"D1","level":"warning","message":{"text":"AskUserQuestion.AskUserQuestion (cyclomatic 40): AskUserQuestion.AskUserQuestion has cyclomatic complexity 40 (threshold 15). Most of this is not in the body itself: 7 of the 40 points are its own statements and the rest belongs to 9 function literals inside it that branch (lines 176, 163, 113, \u2026). The decisions are inside those literals, which nothing outside this body can call, review or test on its own, so splitting the enclosing body is not the move available here. To reduce it, lift the literals\u0027 work into a named function or method at the enclosing scope and have each literal call it, then reduce whichever part then reads as the largest."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/common/AskUserQuestion.tsx"},"region":{"startLine":19}}}],"partialFingerprints":{"codehealthFindingId/v1":"0a67ae1840187c87bbaa666170ab72157c094b1374d6432ca3534bec4e83a8cb"}},{"ruleId":"D1","level":"warning","message":{"text":"useChatStreamingLifecycle.updateMessages (cyclomatic 40): useChatStreamingLifecycle.updateMessages has cyclomatic complexity 40 (threshold 15). Most of this is not in the body itself: 1 of the 40 points is its own statement and the rest belongs to one function literal inside it that branches (line 372). The decisions are inside the literal, which nothing outside this body can call, review or test on its own, so splitting the enclosing body is not the move available here. To reduce it, lift the literal\u0027s work into a named function or method at the enclosing scope and have the literal call it, then reduce whichever part then reads as the largest."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/hooks/useChatStreamingLifecycle.ts"},"region":{"startLine":366}}}],"partialFingerprints":{"codehealthFindingId/v1":"9888f2160e1d01160e8adf99229c917543dd79d6af0812175d1b717a5b537c4c"}},{"ruleId":"D1","level":"warning","message":{"text":"compressDOM::(anonymous)::compress (cyclomatic 40): compressDOM::(anonymous)::compress 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":"backend/skills/s_browser-agent/browser-agent.mjs"},"region":{"startLine":199}}}],"partialFingerprints":{"codehealthFindingId/v1":"4d76b824eb9355266edbcd61d2828ef28bf0ddebf43e545200165afe19815990"}},{"ruleId":"D1","level":"warning","message":{"text":"json_exporter.export_code_intel_json (cyclomatic 39): json_exporter.export_code_intel_json 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":"backend/core/code_intel/json_exporter.py"},"region":{"startLine":36}}}],"partialFingerprints":{"codehealthFindingId/v1":"9ca605e3daa3fae2dbab2e23c56865304af6664b6da4421d96bfb7a008e40c17"}},{"ruleId":"D1","level":"warning","message":{"text":"VirtualizedTree.flattenTree (cyclomatic 39): VirtualizedTree.flattenTree has cyclomatic complexity 39 (threshold 15). Of this number, 38 points are the body\u0027s own statements and 1 belongs to one function literal inside it that branches. 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":"desktop/src/components/workspace-explorer/VirtualizedTree.tsx"},"region":{"startLine":255}}}],"partialFingerprints":{"codehealthFindingId/v1":"f117732dc278d92769b1aff2ab3a348a2020a5e674771f47fe231d7e61c92457"}},{"ruleId":"D1","level":"warning","message":{"text":"PromptBuilder.build_options (cyclomatic 38): PromptBuilder.build_options 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":"backend/core/prompt_builder.py"},"region":{"startLine":1775}}}],"partialFingerprints":{"codehealthFindingId/v1":"3339c6444d84bf812886cab753e63c8322b4c7ef6221e3367aef079a2d6d52ca"}},{"ruleId":"D1","level":"warning","message":{"text":"eval_scheduled.run_eval_scheduled (cyclomatic 38): eval_scheduled.run_eval_scheduled has cyclomatic complexity 38 (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":"backend/jobs/handlers/eval_scheduled.py"},"region":{"startLine":138}}}],"partialFingerprints":{"codehealthFindingId/v1":"fdad69337511199be92654763ee16feb15f66177b249998a477f07b504703c43"}},{"ruleId":"D1","level":"warning","message":{"text":"artifact_cli.cmd_run_observe (cyclomatic 38): artifact_cli.cmd_run_observe 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":"backend/scripts/artifact_cli.py"},"region":{"startLine":5539}}}],"partialFingerprints":{"codehealthFindingId/v1":"31f6542bb1195c8f430eb30b7270fbac20153c0a144717acb2de25fdd2dc7f17"}},{"ruleId":"D1","level":"warning","message":{"text":"useUnifiedAttachments.useUnifiedAttachments (cyclomatic 38): useUnifiedAttachments.useUnifiedAttachments has cyclomatic complexity 38 (threshold 15). Most of this is not in the body itself: 1 of the 38 points is its own statement and the rest belongs to 9 function literals inside it that branch (lines 173, 307, 146, \u2026). The decisions are inside those literals, which nothing outside this body can call, review or test on its own, so splitting the enclosing body is not the move available here. To reduce it, lift the literals\u0027 work into a named function or method at the enclosing scope and have each literal call it, then reduce whichever part then reads as the largest."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/hooks/useUnifiedAttachments.ts"},"region":{"startLine":117}}}],"partialFingerprints":{"codehealthFindingId/v1":"ce04c88abcb51533380fd7cde48b1fda6a150a70ce465e959a4471ef4c546767"}},{"ruleId":"D1","level":"warning","message":{"text":"skill_metrics_hook._detect_skill_invocations (cyclomatic 37): skill_metrics_hook._detect_skill_invocations 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":"backend/hooks/skill_metrics_hook.py"},"region":{"startLine":112}}}],"partialFingerprints":{"codehealthFindingId/v1":"e9ef3eb1dbc0cf3f10522c2999d8c61446f60f422f21729a63409d4c76156e2c"}},{"ruleId":"D1","level":"warning","message":{"text":"ai_ready_helpers.select_verification_tasks (cyclomatic 37): ai_ready_helpers.select_verification_tasks 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":"backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py"},"region":{"startLine":2905}}}],"partialFingerprints":{"codehealthFindingId/v1":"3ac9dcd8a2973a502d5a55da0619849358248cad5778e7b2b67eb872abfa61ee"}},{"ruleId":"D1","level":"warning","message":{"text":"swarmai::spawn_daemon_health_watchdog (cyclomatic 37): swarmai::spawn_daemon_health_watchdog 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":"desktop/src-tauri/src/lib.rs"},"region":{"startLine":1856}}}],"partialFingerprints":{"codehealthFindingId/v1":"09adaa1ca1fb44653b3d8779f4f2167b77d955ff3775dc90a116ee9c4b6fad4c"}},{"ruleId":"D1","level":"warning","message":{"text":"ToDoOverlay.TodoForm (cyclomatic 37): ToDoOverlay.TodoForm has cyclomatic complexity 37 (threshold 15). Most of this is not in the body itself: 11 of the 37 points are its own statements and the rest belongs to 6 function literals inside it that branch (lines 1057, 1022, 1014, \u2026). The decisions are inside those literals, which nothing outside this body can call, review or test on its own, so splitting the enclosing body is not the move available here. To reduce it, lift the literals\u0027 work into a named function or method at the enclosing scope and have each literal call it, then reduce whichever part then reads as the largest."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/layout/ToDoOverlay.tsx"},"region":{"startLine":993}}}],"partialFingerprints":{"codehealthFindingId/v1":"8971830d3eaffd5afe9c0324970a0d587ec016452ef9bc00cfeebf05e4c69398"}},{"ruleId":"D1","level":"warning","message":{"text":"pollinate_validator.validate_delivery (cyclomatic 36): pollinate_validator.validate_delivery 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":"backend/skills/s_pollinate/scripts/pollinate_validator.py"},"region":{"startLine":182}}}],"partialFingerprints":{"codehealthFindingId/v1":"3320898ff7eee963b74e3382b3c3ba5365ff45af9644ac5b48334e3c5fdf6f50"}},{"ruleId":"D1","level":"warning","message":{"text":"TreeNodeRow.TreeNodeRow (cyclomatic 36): TreeNodeRow.TreeNodeRow has cyclomatic complexity 36 (threshold 15). Of this number, 30 points are the body\u0027s own statements and 6 belong to 2 function literals inside it that branch. 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":"desktop/src/components/workspace-explorer/TreeNodeRow.tsx"},"region":{"startLine":188}}}],"partialFingerprints":{"codehealthFindingId/v1":"52affe87dbcc4cbdc64eace7eed1bfa378c02d878906224364ff23ee4c44c22b"}},{"ruleId":"D1","level":"warning","message":{"text":"PollinateOverlay.AssetDrawer (cyclomatic 36): PollinateOverlay.AssetDrawer has cyclomatic complexity 36 (threshold 15). Of this number, 28 points are the body\u0027s own statements and 8 belong to 5 function literals inside it that branch. 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":"desktop/src/components/layout/PollinateOverlay.tsx"},"region":{"startLine":494}}}],"partialFingerprints":{"codehealthFindingId/v1":"1996d9588a1843d7d64d817c262fa7a3cb4e70a1731cd4f9b052b51e8549a321"}},{"ruleId":"D1","level":"warning","message":{"text":"ProjectionLayer.project_skills (cyclomatic 35): ProjectionLayer.project_skills 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":"backend/core/projection_layer.py"},"region":{"startLine":227}}}],"partialFingerprints":{"codehealthFindingId/v1":"923a1b5c00c9c89ab60da08e9226a1db274fd7c15b80bb4ce3a51e5a226e9941"}},{"ruleId":"D1","level":"warning","message":{"text":"ContextHealthHook._auto_cultivate_session_signals (cyclomatic 35): ContextHealthHook._auto_cultivate_session_signals 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":"backend/hooks/context_health_hook.py"},"region":{"startLine":1163}}}],"partialFingerprints":{"codehealthFindingId/v1":"cf62e53672a156fc1ccfeec4d920bcb9941a3bf54021f9e24c8d2985a7fec747"}},{"ruleId":"D1","level":"warning","message":{"text":"pipelines.pipeline_analytics (cyclomatic 35): pipelines.pipeline_analytics 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":"backend/routers/pipelines.py"},"region":{"startLine":444}}}],"partialFingerprints":{"codehealthFindingId/v1":"9881a369fbb3b6977a0909bc07b5d10261c8f6fcf0436bbb89ed1023f287c612"}},{"ruleId":"D1","level":"warning","message":{"text":"SelfLoopsHealthEngine.to_markdown (cyclomatic 35): SelfLoopsHealthEngine.to_markdown 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":"backend/skills/s_loops-health/scripts/loops_health_check.py"},"region":{"startLine":1228}}}],"partialFingerprints":{"codehealthFindingId/v1":"40db73fae0dd88800a44c2c29768f9afa6123ac7a832ee20c5b52dee0790d6c0"}},{"ruleId":"D1","level":"warning","message":{"text":"VirtualizedTree.VirtualizedTree (cyclomatic 35): VirtualizedTree.VirtualizedTree has cyclomatic complexity 35 (threshold 15). Most of this is not in the body itself: 3 of the 35 points are its own statements and the rest belongs to 11 function literals inside it that branch (lines 881, 813, 925, \u2026). The decisions are inside those literals, which nothing outside this body can call, review or test on its own, so splitting the enclosing body is not the move available here. To reduce it, lift the literals\u0027 work into a named function or method at the enclosing scope and have each literal call it, then reduce whichever part then reads as the largest."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/workspace-explorer/VirtualizedTree.tsx"},"region":{"startLine":688}}}],"partialFingerprints":{"codehealthFindingId/v1":"573ff9814372a8aa84a304dfd267a450342ec40c6e9a5eff1be6ea18909cc9f6"}},{"ruleId":"D1","level":"warning","message":{"text":"MergedToolBlock.MergedToolBlock (cyclomatic 35): MergedToolBlock.MergedToolBlock has cyclomatic complexity 35 (threshold 15). Of this number, 31 points are the body\u0027s own statements and 4 belong to 4 function literals inside it that branch. 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":"desktop/src/pages/chat/components/MergedToolBlock.tsx"},"region":{"startLine":122}}}],"partialFingerprints":{"codehealthFindingId/v1":"00351c1ce2b066725d43b471ef86207f388a27295d639a751efc87828ac5009e"}},{"ruleId":"D1","level":"warning","message":{"text":"PollinateOverlay.PollinateContent (cyclomatic 35): PollinateOverlay.PollinateContent has cyclomatic complexity 35 (threshold 15). Most of this is not in the body itself: 13 of the 35 points are its own statements and the rest belongs to 11 function literals inside it that branch (lines 168, 148, 213, \u2026). The decisions are inside those literals, which nothing outside this body can call, review or test on its own, so splitting the enclosing body is not the move available here. To reduce it, lift the literals\u0027 work into a named function or method at the enclosing scope and have each literal call it, then reduce whichever part then reads as the largest."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/layout/PollinateOverlay.tsx"},"region":{"startLine":108}}}],"partialFingerprints":{"codehealthFindingId/v1":"cad13d2b8f54e8f3fd327fa5a12dea31b862bdf2e8be01f26550137baa7c8841"}},{"ruleId":"D1","level":"warning","message":{"text":"ChannelGateway.handle_inbound_message (cyclomatic 34): ChannelGateway.handle_inbound_message 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":"backend/channels/gateway.py"},"region":{"startLine":1248}}}],"partialFingerprints":{"codehealthFindingId/v1":"5b8e49a70a46f77825a017d6bc2373ca7bd572a04eb65059b01c54f017160621"}},{"ruleId":"D1","level":"warning","message":{"text":"ui_actions.build_surface_events (cyclomatic 34): ui_actions.build_surface_events 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":"backend/core/ui_actions.py"},"region":{"startLine":287}}}],"partialFingerprints":{"codehealthFindingId/v1":"9255ae92f139a31498ef5ee6409449f3a22f40f4eb85ffc760718c8ba0e7f01c"}},{"ruleId":"D1","level":"warning","message":{"text":"ddd_weekly_report._generate_report (cyclomatic 34): ddd_weekly_report._generate_report 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":"backend/jobs/handlers/ddd_weekly_report.py"},"region":{"startLine":207}}}],"partialFingerprints":{"codehealthFindingId/v1":"d966b331a2c44433b542e8855c9d316fc44423d464a35f7634ab458be15ed18c"}},{"ruleId":"D1","level":"warning","message":{"text":"artifact_cli.cmd_publish (cyclomatic 34): artifact_cli.cmd_publish 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":"backend/scripts/artifact_cli.py"},"region":{"startLine":337}}}],"partialFingerprints":{"codehealthFindingId/v1":"204a786ab1eb5f457bcc62c24f81ab131989c3b4828b6cd6b2f130b9774c2646"}},{"ruleId":"D1","level":"warning","message":{"text":"pipeline_validator._check_semantic_depth (cyclomatic 34): pipeline_validator._check_semantic_depth 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":"backend/scripts/pipeline_validator.py"},"region":{"startLine":2242}}}],"partialFingerprints":{"codehealthFindingId/v1":"d80992aedcd0d32003c1fa6b1e779cf9d892bc5e11160b7509ff847b5992327e"}},{"ruleId":"D1","level":"warning","message":{"text":"ai_ready_helpers.validate_code_intel_json (cyclomatic 34): ai_ready_helpers.validate_code_intel_json 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":"backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py"},"region":{"startLine":113}}}],"partialFingerprints":{"codehealthFindingId/v1":"3324951ceb5fcbaa7e4b283e54fed1f61e32e16e7d17060ab04a3efbc957c478"}},{"ruleId":"D1","level":"warning","message":{"text":"ai_ready_helpers.validate_code_intel_json (cyclomatic 34): ai_ready_helpers.validate_code_intel_json 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":"backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py"},"region":{"startLine":113}}}],"partialFingerprints":{"codehealthFindingId/v1":"eb2eeb550b8d62b3cb9feaf851b4445029fea9c6f59b773636e943059640793e"}},{"ruleId":"D1","level":"warning","message":{"text":"FileContextMenu.FileContextMenu (cyclomatic 34): FileContextMenu.FileContextMenu has cyclomatic complexity 34 (threshold 15). Most of this is not in the body itself: 10 of the 34 points are its own statements and the rest belongs to 8 function literals inside it that branch (lines 101, 423, 141, \u2026). The decisions are inside those literals, which nothing outside this body can call, review or test on its own, so splitting the enclosing body is not the move available here. To reduce it, lift the literals\u0027 work into a named function or method at the enclosing scope and have each literal call it, then reduce whichever part then reads as the largest."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/workspace-explorer/FileContextMenu.tsx"},"region":{"startLine":58}}}],"partialFingerprints":{"codehealthFindingId/v1":"6fe6d203a79fb6402fad33e1add3a91c7935e4912161ba56e5d5fc607f2fb39c"}},{"ruleId":"D1","level":"warning","message":{"text":"EngineMetricsTab.EngineMetricsTab (cyclomatic 34): EngineMetricsTab.EngineMetricsTab has cyclomatic complexity 34 (threshold 15). Of this number, 18 points are the body\u0027s own statements and 16 belong to 6 function literals inside it that branch. 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":"desktop/src/components/settings/EngineMetricsTab.tsx"},"region":{"startLine":54}}}],"partialFingerprints":{"codehealthFindingId/v1":"203060cc3b21f9fab72013c9f07c4a3844e7b45641596b909d19cb5d09dd5000"}},{"ruleId":"D1","level":"warning","message":{"text":"EvalDashboard.GoldenSetTab (cyclomatic 34): EvalDashboard.GoldenSetTab has cyclomatic complexity 34 (threshold 15). Most of this is not in the body itself: 12 of the 34 points are its own statements and the rest belongs to 7 function literals inside it that branch (lines 519, 607, 531, \u2026). The decisions are inside those literals, which nothing outside this body can call, review or test on its own, so splitting the enclosing body is not the move available here. To reduce it, lift the literals\u0027 work into a named function or method at the enclosing scope and have each literal call it, then reduce whichever part then reads as the largest."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/pages/EvalDashboard.tsx"},"region":{"startLine":495}}}],"partialFingerprints":{"codehealthFindingId/v1":"e24064e016f8fcd68fef6eeedeaf5773466f5aeb8878034ff8dd99528215a071"}},{"ruleId":"D1","level":"warning","message":{"text":"ReviewModeGutter.ReviewModeGutter (cyclomatic 34): ReviewModeGutter.ReviewModeGutter has cyclomatic complexity 34 (threshold 15). Of this number, 17 points are the body\u0027s own statements and 17 belong to 3 function literals inside it that branch. 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":"desktop/src/components/common/ReviewModeGutter.tsx"},"region":{"startLine":42}}}],"partialFingerprints":{"codehealthFindingId/v1":"5c33ab7e5f2acfad54a306f0ed57b9b335d3da403cb882c8b082d53a0ca2ebc9"}},{"ruleId":"D1","level":"warning","message":{"text":"useHealthMonitor.useHealthMonitor (cyclomatic 33): useHealthMonitor.useHealthMonitor has cyclomatic complexity 33 (threshold 15). Most of this is not in the body itself: 1 of the 33 points is its own statement and the rest belongs to 13 function literals inside it that branch (lines 222, 293, 176, \u2026). The decisions are inside those literals, which nothing outside this body can call, review or test on its own, so splitting the enclosing body is not the move available here. To reduce it, lift the literals\u0027 work into a named function or method at the enclosing scope and have each literal call it, then reduce whichever part then reads as the largest."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/hooks/useHealthMonitor.ts"},"region":{"startLine":134}}}],"partialFingerprints":{"codehealthFindingId/v1":"eaa4f99cbedbd884fbd14d87897f22b786af108a23ac96e0b269a748cdfd78fa"}},{"ruleId":"D1","level":"warning","message":{"text":"MultiSelect.MultiSelect (cyclomatic 33): MultiSelect.MultiSelect has cyclomatic complexity 33 (threshold 15). Of this number, 19 points are the body\u0027s own statements and 14 belong to 7 function literals inside it that branch. To reduce it, name the conditions: bind each compound test to a well-named local or a small predicate function, so the body reads as a sequence of named decisions rather than a chain of operators."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/common/MultiSelect.tsx"},"region":{"startLine":25}}}],"partialFingerprints":{"codehealthFindingId/v1":"7c7e89503a48991d4112135e19cbd4628ee7f016764b664dc9ab13dd9f26a545"}},{"ruleId":"D1","level":"warning","message":{"text":"ContentBlockRenderer.ContentBlockRenderer (cyclomatic 33): ContentBlockRenderer.ContentBlockRenderer has cyclomatic complexity 33 (threshold 15). Of this number, 32 points are the body\u0027s own statements and 1 belongs to one function literal inside it that branches. 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":"desktop/src/pages/chat/components/ContentBlockRenderer.tsx"},"region":{"startLine":122}}}],"partialFingerprints":{"codehealthFindingId/v1":"8aec69d38bfeed0896f378d8e9bb67b1248e38e7f4b2a1501a3b922dde2dbd03"}},{"ruleId":"D1","level":"warning","message":{"text":"adversarial_meta.check_adversarial_health (cyclomatic 32): adversarial_meta.check_adversarial_health 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":"backend/core/adversarial_meta.py"},"region":{"startLine":21}}}],"partialFingerprints":{"codehealthFindingId/v1":"4096b817538a9dbce90becc06d5baddc5cd41afaa12b1e97725d90f1d41309b3"}},{"ruleId":"D1","level":"warning","message":{"text":"parser.parse_repo_with_coverage (cyclomatic 32): parser.parse_repo_with_coverage 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":"backend/core/code_intel/parser.py"},"region":{"startLine":1952}}}],"partialFingerprints":{"codehealthFindingId/v1":"bbfba6b843a04193149116d50e74c7e57563d27156b955ca1a761b80dc5afcd0"}},{"ruleId":"D1","level":"warning","message":{"text":"SummarizationPipeline._extract_files_modified (cyclomatic 32): SummarizationPipeline._extract_files_modified 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":"backend/core/summarization.py"},"region":{"startLine":422}}}],"partialFingerprints":{"codehealthFindingId/v1":"fda6feeaca1703a4289c2d688fbb3f59309e5ed78850998cd9c1adca72a8db7c"}},{"ruleId":"D1","level":"warning","message":{"text":"executor._format_briefing_slack_message (cyclomatic 32): executor._format_briefing_slack_message 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":"backend/jobs/executor.py"},"region":{"startLine":1357}}}],"partialFingerprints":{"codehealthFindingId/v1":"9b7ba2a2627f7f2e9fd6212c1cb9bde4024403e1b9649b5a89ed536013446851"}},{"ruleId":"D1","level":"warning","message":{"text":"artifact_cli.cmd_run_commit (cyclomatic 32): artifact_cli.cmd_run_commit 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":"backend/scripts/artifact_cli.py"},"region":{"startLine":2920}}}],"partialFingerprints":{"codehealthFindingId/v1":"4a60b452feb6964c927d07f605eec9cc04ce384003cd48fee42166426b13bf43"}},{"ruleId":"D1","level":"warning","message":{"text":"backfill_cjk_escapes.backfill (cyclomatic 32): backfill_cjk_escapes.backfill 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":"backend/scripts/backfill_cjk_escapes.py"},"region":{"startLine":576}}}],"partialFingerprints":{"codehealthFindingId/v1":"5ce1888ac5e27c8b965984a073069b50aa38cc30013ef883a8d0e5def5b6af4b"}},{"ruleId":"D1","level":"warning","message":{"text":"style-extract.extract_shapes_summary (cyclomatic 32): style-extract.extract_shapes_summary 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":"backend/skills/s_pptx/scripts/style-extract.py"},"region":{"startLine":81}}}],"partialFingerprints":{"codehealthFindingId/v1":"cff9c595d53510a649ff2b1b272e20f4b8ef4735a34e51b837f3c00029ccc186"}},{"ruleId":"D1","level":"warning","message":{"text":"ai_ready_helpers.compute_subsystem_coverage (cyclomatic 32): ai_ready_helpers.compute_subsystem_coverage 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":"backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py"},"region":{"startLine":845}}}],"partialFingerprints":{"codehealthFindingId/v1":"df3f1f540a9b7b28ef5ac7b2358eabf7b7e9f1633b812749359d443ce1d2e4ee"}},{"ruleId":"D1","level":"warning","message":{"text":"ExplorerContext.ExplorerProvider (cyclomatic 32): ExplorerContext.ExplorerProvider has cyclomatic complexity 32 (threshold 15). Most of this is not in the body itself: 1 of the 32 points is its own statement and the rest belongs to 11 function literals inside it that branch (lines 616, 489, 531, \u2026). The decisions are inside those literals, which nothing outside this body can call, review or test on its own, so splitting the enclosing body is not the move available here. To reduce it, lift the literals\u0027 work into a named function or method at the enclosing scope and have each literal call it, then reduce whichever part then reads as the largest."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/contexts/ExplorerContext.tsx"},"region":{"startLine":369}}}],"partialFingerprints":{"codehealthFindingId/v1":"5881e28d4949c9764d0dbb622f5dc445d6ebc115967da6d4820ea5426ef16126"}},{"ruleId":"D1","level":"warning","message":{"text":"ExplorerToolbar.ExplorerToolbar (cyclomatic 32): ExplorerToolbar.ExplorerToolbar has cyclomatic complexity 32 (threshold 15). Most of this is not in the body itself: 11 of the 32 points are its own statements and the rest belongs to 9 function literals inside it that branch (lines 89, 146, 127, \u2026). The decisions are inside those literals, which nothing outside this body can call, review or test on its own, so splitting the enclosing body is not the move available here. To reduce it, lift the literals\u0027 work into a named function or method at the enclosing scope and have each literal call it, then reduce whichever part then reads as the largest."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/workspace-explorer/ExplorerToolbar.tsx"},"region":{"startLine":34}}}],"partialFingerprints":{"codehealthFindingId/v1":"8520a26d7f4a5430ab6a3b3e1d4be54622cfea0f88bf22ea141c32e60e8a77c5"}},{"ruleId":"D1","level":"warning","message":{"text":"MessageStore._applyMerge (cyclomatic 32): MessageStore._applyMerge has cyclomatic complexity 32 (threshold 15). Of this number, 30 points are the body\u0027s own statements and 2 belong to 2 function literals inside it that branch. 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":"desktop/src/stores/MessageStore.ts"},"region":{"startLine":892}}}],"partialFingerprints":{"codehealthFindingId/v1":"0bbc402c76007382894b0ef1aed716b238baa6d5afd66ac339ab6bddf8552860"}},{"ruleId":"D1","level":"warning","message":{"text":"BackupTab.BackupTab (cyclomatic 32): BackupTab.BackupTab has cyclomatic complexity 32 (threshold 15). Most of this is not in the body itself: 15 of the 32 points are its own statements and the rest belongs to 6 function literals inside it that branch (lines 176, 55, 206, \u2026). The decisions are inside those literals, which nothing outside this body can call, review or test on its own, so splitting the enclosing body is not the move available here. To reduce it, lift the literals\u0027 work into a named function or method at the enclosing scope and have each literal call it, then reduce whichever part then reads as the largest."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/settings/BackupTab.tsx"},"region":{"startLine":15}}}],"partialFingerprints":{"codehealthFindingId/v1":"c3e77d1a51caafd90eddb5d9be53d3d56e5d325d89adb3d0d6b6b196e1c9eb5b"}},{"ruleId":"D1","level":"warning","message":{"text":"OnboardingPage.OnboardingPage (cyclomatic 32): OnboardingPage.OnboardingPage has cyclomatic complexity 32 (threshold 15). Most of this is not in the body itself: 11 of the 32 points are its own statements and the rest belongs to 7 function literals inside it that branch (lines 59, 144, 58, \u2026). The decisions are inside those literals, which nothing outside this body can call, review or test on its own, so splitting the enclosing body is not the move available here. To reduce it, lift the literals\u0027 work into a named function or method at the enclosing scope and have each literal call it, then reduce whichever part then reads as the largest."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/pages/OnboardingPage.tsx"},"region":{"startLine":40}}}],"partialFingerprints":{"codehealthFindingId/v1":"7f7103153b97940562ed5e04ca1b1fccd6c0dbef858667fd22f923c325ed0588"}},{"ruleId":"D1","level":"warning","message":{"text":"security_hooks._targets_irreplaceable_store (cyclomatic 31): security_hooks._targets_irreplaceable_store 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":"backend/core/security_hooks.py"},"region":{"startLine":430}}}],"partialFingerprints":{"codehealthFindingId/v1":"a11dc6e7936a3f1a6310938910d2ea5efa0fb698abf94d77154353f062b35a21"}},{"ruleId":"D1","level":"warning","message":{"text":"ChannelsTab.ChannelsTab (cyclomatic 31): ChannelsTab.ChannelsTab has cyclomatic complexity 31 (threshold 15). Of this number, 26 points are the body\u0027s own statements and 5 belong to 3 function literals inside it that branch. To reduce it, name the conditions: bind each compound test to a well-named local or a small predicate function, so the body reads as a sequence of named decisions rather than a chain of operators."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/settings/ChannelsTab.tsx"},"region":{"startLine":13}}}],"partialFingerprints":{"codehealthFindingId/v1":"3da02a08611799732176e24ae6854d9ed445bd08f9ddcdf2cddb083744194bba"}},{"ruleId":"D1","level":"warning","message":{"text":"clustering.compute_graph_clusters (cyclomatic 30): clustering.compute_graph_clusters 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":"backend/core/code_intel/clustering.py"},"region":{"startLine":75}}}],"partialFingerprints":{"codehealthFindingId/v1":"075db656e61903370ac27315eeeb41ff657b6f03380ade0b76b833c0f988a4b4"}},{"ruleId":"D1","level":"warning","message":{"text":"ContextDirectoryLoader.ensure_directory (cyclomatic 30): ContextDirectoryLoader.ensure_directory 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":"backend/core/context_directory_loader.py"},"region":{"startLine":543}}}],"partialFingerprints":{"codehealthFindingId/v1":"28c0679373497fa072a33d5c61dbd4636be35d7d2f47222fa290c85e877e4625"}},{"ruleId":"D1","level":"warning","message":{"text":"daily_activity_writer._format_session_entry (cyclomatic 30): daily_activity_writer._format_session_entry has cyclomatic complexity 30 (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":"backend/core/daily_activity_writer.py"},"region":{"startLine":134}}}],"partialFingerprints":{"codehealthFindingId/v1":"14b8737578d329e80e3997e3ce20946612cad4578ba73e3ef48427f8fa89fb09"}},{"ruleId":"D1","level":"warning","message":{"text":"PluginManager.install_plugin (cyclomatic 30): PluginManager.install_plugin 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":"backend/core/plugin_manager.py"},"region":{"startLine":696}}}],"partialFingerprints":{"codehealthFindingId/v1":"44edb43642a00ef0336827194d5e60aaa1fe06d424522d4de30c852a79b5df53"}},{"ruleId":"D1","level":"warning","message":{"text":"recall_multi._recall_ddd (cyclomatic 30): recall_multi._recall_ddd 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":"backend/core/recall_multi.py"},"region":{"startLine":701}}}],"partialFingerprints":{"codehealthFindingId/v1":"7265c52349be6f200dda63be3d4fd28ea0aad89278eb39acf720a7e9cc28124f"}},{"ruleId":"D1","level":"warning","message":{"text":"session_router._maybe_inject_recall_inner (cyclomatic 30): session_router._maybe_inject_recall_inner has cyclomatic complexity 30 (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":"backend/core/session_router.py"},"region":{"startLine":969}}}],"partialFingerprints":{"codehealthFindingId/v1":"0493b0f2535dbef3a8030e1420c410de4ef962f95448b56aea2ffb64986d5ce1"}},{"ruleId":"D1","level":"warning","message":{"text":"ContextHealthHook._track_memory_usage_locked (cyclomatic 30): ContextHealthHook._track_memory_usage_locked 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":"backend/hooks/context_health_hook.py"},"region":{"startLine":1593}}}],"partialFingerprints":{"codehealthFindingId/v1":"e5601f4f419637c0c5abb367c759a365e52389f82a19c67f9aff9720985cb7f7"}},{"ruleId":"D1","level":"warning","message":{"text":"Video.SectionComponent (cyclomatic 30): Video.SectionComponent has cyclomatic complexity 30 (threshold 15). Of this number, 28 points are the body\u0027s own statements and 2 belong to one function literal inside it that branches. 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":"backend/skills/s_pollinate/templates/remotion/Video.tsx"},"region":{"startLine":43}}}],"partialFingerprints":{"codehealthFindingId/v1":"e619d51ce0b26fdfc015d8327e25be37d3fbea141af6951b8bad9b74a10c61f8"}},{"ruleId":"D1","level":"warning","message":{"text":"LibraryTree.LibraryTree (cyclomatic 30): LibraryTree.LibraryTree has cyclomatic complexity 30 (threshold 15). Most of this is not in the body itself: 12 of the 30 points are its own statements and the rest belongs to 8 function literals inside it that branch (lines 236, 278, 297, \u2026). The decisions are inside those literals, which nothing outside this body can call, review or test on its own, so splitting the enclosing body is not the move available here. To reduce it, lift the literals\u0027 work into a named function or method at the enclosing scope and have each literal call it, then reduce whichever part then reads as the largest."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/layout/LibraryTree.tsx"},"region":{"startLine":218}}}],"partialFingerprints":{"codehealthFindingId/v1":"75214bd582a440571b5db0acb28a98aa5032b89d6c0f5abaed1fff1c7941dec0"}},{"ruleId":"D1","level":"warning","message":{"text":"InlinePermissionRequest.InlinePermissionRequest (cyclomatic 30): InlinePermissionRequest.InlinePermissionRequest has cyclomatic complexity 30 (threshold 15). Of this number, 16 points are the body\u0027s own statements and 14 belong to 6 function literals inside it that branch. 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":"desktop/src/pages/chat/components/InlinePermissionRequest.tsx"},"region":{"startLine":40}}}],"partialFingerprints":{"codehealthFindingId/v1":"1f5a5e41093bfbacba983cfec44a3e3c2549cd7488e49633d4d6ca6033e1b1d2"}},{"ruleId":"D1","level":"warning","message":{"text":"FilePreviewModal.FilePreviewModal (cyclomatic 30): FilePreviewModal.FilePreviewModal has cyclomatic complexity 30 (threshold 15). Most of this is not in the body itself: 12 of the 30 points are its own statements and the rest belongs to 2 function literals inside it that branch (lines 102, 79). The decisions are inside those literals, which nothing outside this body can call, review or test on its own, so splitting the enclosing body is not the move available here. To reduce it, lift the literals\u0027 work into a named function or method at the enclosing scope and have each literal call it, then reduce whichever part then reads as the largest."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/workspace/FilePreviewModal.tsx"},"region":{"startLine":48}}}],"partialFingerprints":{"codehealthFindingId/v1":"a9c9de41c73faa493dec6eb27349ede491c1fd4bd3f4a404d66482e56828602a"}},{"ruleId":"D1","level":"warning","message":{"text":"FileEditorCore.DiffView (cyclomatic 30): FileEditorCore.DiffView has cyclomatic complexity 30 (threshold 15). Most of this is not in the body itself: 10 of the 30 points are its own statements and the rest belongs to 3 function literals inside it that branch (lines 415, 399, 480). The decisions are inside those literals, which nothing outside this body can call, review or test on its own, so splitting the enclosing body is not the move available here. To reduce it, lift the literals\u0027 work into a named function or method at the enclosing scope and have each literal call it, then reduce whichever part then reads as the largest."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/common/FileEditorCore.tsx"},"region":{"startLine":380}}}],"partialFingerprints":{"codehealthFindingId/v1":"87d5a8a7f8e623007aff9ffdc286af4813816349870e4f7b94149676f4e09a76"}},{"ruleId":"D1","level":"warning","message":{"text":"ChatErrorMessage.ChatErrorMessage (cyclomatic 30): ChatErrorMessage.ChatErrorMessage has cyclomatic complexity 30 (threshold 15). Of this number, 29 points are the body\u0027s own statements and 1 belongs to one function literal inside it that branches. 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":"desktop/src/components/chat/ChatErrorMessage.tsx"},"region":{"startLine":35}}}],"partialFingerprints":{"codehealthFindingId/v1":"c7fe0b21b426565865a338a7beb6bff54e0d480ec84d6817b68b3333c907583e"}},{"ruleId":"D1","level":"warning","message":{"text":"DddCultivationOrchestrator._auto_apply_ddd_proposals (cyclomatic 29): DddCultivationOrchestrator._auto_apply_ddd_proposals 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":"backend/core/ddd_orchestrator.py"},"region":{"startLine":582}}}],"partialFingerprints":{"codehealthFindingId/v1":"ffa108b48e57a28afb513e78626ed2461ee2b199ce4581dbc003a25c377eb6d0"}},{"ruleId":"D1","level":"warning","message":{"text":"ingestion_gate.ingestion_gate (cyclomatic 29): ingestion_gate.ingestion_gate 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":"backend/core/ingestion_gate.py"},"region":{"startLine":633}}}],"partialFingerprints":{"codehealthFindingId/v1":"6660def27325017b49617278f75b793d8da44225316b41436ba0588328426f87"}},{"ruleId":"D1","level":"warning","message":{"text":"memory_extractor.extract_and_save (cyclomatic 29): memory_extractor.extract_and_save 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":"backend/core/memory_extractor.py"},"region":{"startLine":367}}}],"partialFingerprints":{"codehealthFindingId/v1":"9f3c80657ad32bbe117a129e82340afc9e17a216c7d3ca9a2712e5e6cb5a4bd0"}},{"ruleId":"D1","level":"warning","message":{"text":"persist_routing.classify_content (cyclomatic 29): persist_routing.classify_content has cyclomatic complexity 29 (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":"backend/core/persist_routing.py"},"region":{"startLine":248}}}],"partialFingerprints":{"codehealthFindingId/v1":"7b9da4ce4505c31a369c2555446c19f23559014d61682d4e0056256d599d21c7"}},{"ruleId":"D1","level":"warning","message":{"text":"PluginManager._install_from_marketplace_json (cyclomatic 29): PluginManager._install_from_marketplace_json 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":"backend/core/plugin_manager.py"},"region":{"startLine":522}}}],"partialFingerprints":{"codehealthFindingId/v1":"23f234574e61c77460815a254f99e05d6052fc16012ecf0e3382c5b125135710"}},{"ruleId":"D1","level":"warning","message":{"text":"SQLiteDatabase._run_versioned_migrations (cyclomatic 29): SQLiteDatabase._run_versioned_migrations 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":"backend/database/sqlite.py"},"region":{"startLine":2386}}}],"partialFingerprints":{"codehealthFindingId/v1":"b6dce431b151f42358e54ee194572d907a6773de2685abd8bc129ed18872c1ed"}},{"ruleId":"D1","level":"warning","message":{"text":"SQLiteDatabase._run_legacy_migrations (cyclomatic 29): SQLiteDatabase._run_legacy_migrations has cyclomatic complexity 29 (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":"backend/database/sqlite.py"},"region":{"startLine":2885}}}],"partialFingerprints":{"codehealthFindingId/v1":"cd12cc556df854317be2a89d90f4d7607da765f601181cdc0899c228021849ea"}},{"ruleId":"D1","level":"warning","message":{"text":"memory_health.run_memory_health (cyclomatic 29): memory_health.run_memory_health 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":"backend/jobs/handlers/memory_health.py"},"region":{"startLine":150}}}],"partialFingerprints":{"codehealthFindingId/v1":"31229144cf5670bc924eed8cdd5ce9e5a53bbf01cc90e8c19f3160f703899737"}},{"ruleId":"D1","level":"warning","message":{"text":"memory_health._apply_report (cyclomatic 29): memory_health._apply_report 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":"backend/jobs/handlers/memory_health.py"},"region":{"startLine":493}}}],"partialFingerprints":{"codehealthFindingId/v1":"5a595d0d9991b115e86e4072efdb843049f05c543b13f76a5552ff0ee499275d"}},{"ruleId":"D1","level":"warning","message":{"text":"recalc.recalc (cyclomatic 29): recalc.recalc 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":"backend/skills/s_xlsx/recalc.py"},"region":{"startLine":53}}}],"partialFingerprints":{"codehealthFindingId/v1":"e00cb921a1987ce408d5e71b22a9bd8782bcb5d55babb758f5c43ffe4b4facba"}},{"ruleId":"D1","level":"warning","message":{"text":"UpdateNotification.UpdateNotification (cyclomatic 29): UpdateNotification.UpdateNotification has cyclomatic complexity 29 (threshold 15). Of this number, 22 points are the body\u0027s own statements and 7 belong to 3 function literals inside it that branch. To reduce it, name the conditions: bind each compound test to a well-named local or a small predicate function, so the body reads as a sequence of named decisions rather than a chain of operators."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/common/UpdateNotification.tsx"},"region":{"startLine":16}}}],"partialFingerprints":{"codehealthFindingId/v1":"662816accdae602a555470482a2ddc8e4decab5daa359c92ffa42aa5896a1bd9"}},{"ruleId":"D1","level":"warning","message":{"text":"CodeGraph.CodeGraph (cyclomatic 29): CodeGraph.CodeGraph has cyclomatic complexity 29 (threshold 15). Most of this is not in the body itself: 10 of the 29 points are its own statements and the rest belongs to 10 function literals inside it that branch (lines 168, 156, 100, \u2026). The decisions are inside those literals, which nothing outside this body can call, review or test on its own, so splitting the enclosing body is not the move available here. To reduce it, lift the literals\u0027 work into a named function or method at the enclosing scope and have each literal call it, then reduce whichever part then reads as the largest."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/code-intel/CodeGraph.tsx"},"region":{"startLine":76}}}],"partialFingerprints":{"codehealthFindingId/v1":"42bdb78eee1354eec1a8f27eeebccbad96dd93deaff7cc65e3bb72fdf13d4249"}},{"ruleId":"D1","level":"warning","message":{"text":"EvalDashboard.OverviewTab (cyclomatic 29): EvalDashboard.OverviewTab has cyclomatic complexity 29 (threshold 15). Of this number, 26 points are the body\u0027s own statements and 3 belong to 2 function literals inside it that branch. 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":"desktop/src/pages/EvalDashboard.tsx"},"region":{"startLine":289}}}],"partialFingerprints":{"codehealthFindingId/v1":"aad88e9bbcb59a61426cded2c51fdfba6d6ff7d5b1e23613e569543851ea75ba"}},{"ruleId":"D1","level":"warning","message":{"text":"ddd_cultivation.apply_to_ddd (cyclomatic 28): ddd_cultivation.apply_to_ddd 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":"backend/core/ddd_cultivation.py"},"region":{"startLine":984}}}],"partialFingerprints":{"codehealthFindingId/v1":"00ad68ae3a139efb94e1d949d17a312e96b4e30e0ae6e5bc6df0d425425d8f82"}},{"ruleId":"D1","level":"warning","message":{"text":"SessionMiner._extract_skill_invocations (cyclomatic 28): SessionMiner._extract_skill_invocations 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":"backend/core/session_miner.py"},"region":{"startLine":287}}}],"partialFingerprints":{"codehealthFindingId/v1":"bb950719d09b969f750abde3f066503ae85b33099f221f8caf4947a2b74c4a13"}},{"ruleId":"D1","level":"warning","message":{"text":"ContextHealthHook._auto_cultivate_pipeline_lessons (cyclomatic 28): ContextHealthHook._auto_cultivate_pipeline_lessons 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":"backend/hooks/context_health_hook.py"},"region":{"startLine":788}}}],"partialFingerprints":{"codehealthFindingId/v1":"56642b2188b43ac2f0c2cc8196be0c0a894abf5ba3e88b723ebdf39a1b14bb0b"}},{"ruleId":"D1","level":"warning","message":{"text":"DistillationTriggerHook._enforce_size_valve (cyclomatic 28): DistillationTriggerHook._enforce_size_valve 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":"backend/hooks/distillation_hook.py"},"region":{"startLine":2571}}}],"partialFingerprints":{"codehealthFindingId/v1":"bce01aac44790ca0d6ac6287a7aa30373c7f18132181252c52dc9efc15034f39"}},{"ruleId":"D1","level":"warning","message":{"text":"channels.update_channel (cyclomatic 28): channels.update_channel has cyclomatic complexity 28 (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":"backend/routers/channels.py"},"region":{"startLine":180}}}],"partialFingerprints":{"codehealthFindingId/v1":"94a5075a1b815d420e4da1bcb0658dc12ccc3299dbb2b428cbf48f8976c61d10"}},{"ruleId":"D1","level":"warning","message":{"text":"design_system.format_ascii_box (cyclomatic 28): design_system.format_ascii_box has cyclomatic complexity 28 (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":"backend/skills/s_frontend-design/scripts/design_system.py"},"region":{"startLine":282}}}],"partialFingerprints":{"codehealthFindingId/v1":"b0f6743332c0b6e0d7ee007f97b0ee057bf05d361d519688256cc96ca23b1b32"}},{"ruleId":"D1","level":"warning","message":{"text":"ParagraphData.__init__ (cyclomatic 28): ParagraphData.__init__ 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":"backend/skills/s_pptx/scripts/inventory.py"},"region":{"startLine":140}}}],"partialFingerprints":{"codehealthFindingId/v1":"dcb25118b42aedd3493715bb2a422a9ae0664143f72ec681b7e5b1bbd5428c48"}},{"ruleId":"D1","level":"warning","message":{"text":"PipelineOverlay.PipelineContent (cyclomatic 28): PipelineOverlay.PipelineContent has cyclomatic complexity 28 (threshold 15). Of this number, 19 points are the body\u0027s own statements and 9 belong to 8 function literals inside it that branch. To reduce it, name the conditions: bind each compound test to a well-named local or a small predicate function, so the body reads as a sequence of named decisions rather than a chain of operators."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/layout/PipelineOverlay.tsx"},"region":{"startLine":89}}}],"partialFingerprints":{"codehealthFindingId/v1":"3c326bfb804b2519f86867ff57e6fcfb977ea3528da2fd4704b46996df661a27"}},{"ruleId":"D1","level":"warning","message":{"text":"TSCCModules.SystemPromptModule (cyclomatic 28): TSCCModules.SystemPromptModule has cyclomatic complexity 28 (threshold 15). Most of this is not in the body itself: 10 of the 28 points are its own statements and the rest belongs to 11 function literals inside it that branch (lines 713, 663, 726, \u2026). The decisions are inside those literals, which nothing outside this body can call, review or test on its own, so splitting the enclosing body is not the move available here. To reduce it, lift the literals\u0027 work into a named function or method at the enclosing scope and have each literal call it, then reduce whichever part then reads as the largest."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/pages/chat/components/TSCCModules.tsx"},"region":{"startLine":655}}}],"partialFingerprints":{"codehealthFindingId/v1":"05905b5e210653eac79b04da2d932cb791ab16b1ed0878cfb4758cbd9d6e1478"}},{"ruleId":"D1","level":"warning","message":{"text":"ddd_entry_lifecycle.parse_entries (cyclomatic 27): ddd_entry_lifecycle.parse_entries 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":"backend/core/ddd_entry_lifecycle.py"},"region":{"startLine":521}}}],"partialFingerprints":{"codehealthFindingId/v1":"56b31d8bbbc07129f0c63a7a656786119d2962993631247686b289930e82cef5"}},{"ruleId":"D1","level":"warning","message":{"text":"ddd_entry_lifecycle.inject_entry_metadata (cyclomatic 27): ddd_entry_lifecycle.inject_entry_metadata 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":"backend/core/ddd_entry_lifecycle.py"},"region":{"startLine":642}}}],"partialFingerprints":{"codehealthFindingId/v1":"23996d03496127dbfcfafd5d5ce6aed3fca73665c6496c04ebc5dde32336c386"}},{"ruleId":"D1","level":"warning","message":{"text":"ddd_packager.package_ddd (cyclomatic 27): ddd_packager.package_ddd 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":"backend/core/ddd_packager.py"},"region":{"startLine":1838}}}],"partialFingerprints":{"codehealthFindingId/v1":"50c7a54ccf41197e23105270850515bb475ced6064c2454d4e89fdb3ec2b3271"}},{"ruleId":"D1","level":"warning","message":{"text":"engine_metrics.collect_ddd_change_suggestions (cyclomatic 27): engine_metrics.collect_ddd_change_suggestions has cyclomatic complexity 27 (threshold 15). To reduce it, split the body: these branches sit side by side rather than nested inside one another, so extracting each one on its own would leave a function per branch. Group the statements between the checks into named steps and move each step into its own function, so the body reads as a short sequence of named stages."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/core/engine_metrics.py"},"region":{"startLine":154}}}],"partialFingerprints":{"codehealthFindingId/v1":"29cf1d0cf9720aba0559b7a2ce395a7335260bed0f8e4d9ae5c25ff519229de2"}},{"ruleId":"D1","level":"warning","message":{"text":"executor._handle_agent_task (cyclomatic 27): executor._handle_agent_task has cyclomatic complexity 27 (threshold 15). To reduce it, split the body: these branches sit side by side rather than nested inside one another, so extracting each one on its own would leave a function per branch. Group the statements between the checks into named steps and move each step into its own function, so the body reads as a short sequence of named stages."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/jobs/executor.py"},"region":{"startLine":739}}}],"partialFingerprints":{"codehealthFindingId/v1":"c08b2af150adddf1fa8f57ee8eb8c0689ab7029a1c036f0a49f8f4c94042b438"}},{"ruleId":"D1","level":"warning","message":{"text":"chat.sse_with_heartbeat (cyclomatic 27): chat.sse_with_heartbeat 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":"backend/routers/chat.py"},"region":{"startLine":336}}}],"partialFingerprints":{"codehealthFindingId/v1":"7ffcf173a4beeda2632b58bc718423572dbd3085e4ecaa649cbb678c2de11f7b"}},{"ruleId":"D1","level":"warning","message":{"text":"SelfLoopsHealthEngine._check_memory (cyclomatic 27): SelfLoopsHealthEngine._check_memory 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":"backend/skills/s_loops-health/scripts/loops_health_check.py"},"region":{"startLine":269}}}],"partialFingerprints":{"codehealthFindingId/v1":"f6874df02da1aae7d454e53cddfc7a02e1623d968c4335dce9f4777cb20a7547"}},{"ruleId":"D1","level":"warning","message":{"text":"EvalDashboard.CaseDetailDrawer (cyclomatic 27): EvalDashboard.CaseDetailDrawer has cyclomatic complexity 27 (threshold 15). Of this number, 25 points are the body\u0027s own statements and 2 belong to one function literal inside it that branches. To reduce it, name the conditions: bind each compound test to a well-named local or a small predicate function, so the body reads as a sequence of named decisions rather than a chain of operators."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/pages/EvalDashboard.tsx"},"region":{"startLine":2191}}}],"partialFingerprints":{"codehealthFindingId/v1":"7764b397b9b6e36e3b44f839b2c40c73c066f60e492bf7eee0bcd52aa1b6e2a5"}},{"ruleId":"D1","level":"warning","message":{"text":"useCanvasHost.useCanvasHost (cyclomatic 27): useCanvasHost.useCanvasHost has cyclomatic complexity 27 (threshold 15). Most of this is not in the body itself: 2 of the 27 points are its own statements and the rest belongs to 7 function literals inside it that branch (lines 311, 233, 251, \u2026). The decisions are inside those literals, which nothing outside this body can call, review or test on its own, so splitting the enclosing body is not the move available here. To reduce it, lift the literals\u0027 work into a named function or method at the enclosing scope and have each literal call it, then reduce whichever part then reads as the largest."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/hooks/useCanvasHost.ts"},"region":{"startLine":148}}}],"partialFingerprints":{"codehealthFindingId/v1":"b108f622d91a7d1296de0ac12a36297e941ac8fe38d91d0d116bd5a9ddb76ead"}},{"ruleId":"D1","level":"warning","message":{"text":"FolderPickerModal.FolderPickerModal (cyclomatic 27): FolderPickerModal.FolderPickerModal has cyclomatic complexity 27 (threshold 15). Most of this is not in the body itself: 12 of the 27 points are its own statements and the rest belongs to 10 function literals inside it that branch (lines 97, 34, 120, \u2026). The decisions are inside those literals, which nothing outside this body can call, review or test on its own, so splitting the enclosing body is not the move available here. To reduce it, lift the literals\u0027 work into a named function or method at the enclosing scope and have each literal call it, then reduce whichever part then reads as the largest."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/workspace/FolderPickerModal.tsx"},"region":{"startLine":21}}}],"partialFingerprints":{"codehealthFindingId/v1":"5382843061de897f0338eb0dcc50270666401a69fce02079b8e082bc7d0e046c"}},{"ruleId":"D1","level":"warning","message":{"text":"context_injector._extract_key_tool_results (cyclomatic 26): context_injector._extract_key_tool_results 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":"backend/core/context_injector.py"},"region":{"startLine":654}}}],"partialFingerprints":{"codehealthFindingId/v1":"e422e3059e6f9b0d6bf8ef5f44b6a25bc6f576ce58a162b1757dc1bf3eb471f8"}},{"ruleId":"D1","level":"warning","message":{"text":"file_change_classifier.parse_bash_delete_targets (cyclomatic 26): file_change_classifier.parse_bash_delete_targets 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":"backend/core/file_change_classifier.py"},"region":{"startLine":122}}}],"partialFingerprints":{"codehealthFindingId/v1":"69ce5926c44166c808f809bde9e25d225ab0e2ccbe27dcb3ffd8675aa66284a1"}},{"ruleId":"D1","level":"warning","message":{"text":"SessionUnit._emit_post_stream_metadata (cyclomatic 26): SessionUnit._emit_post_stream_metadata 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":"backend/core/session_unit.py"},"region":{"startLine":2976}}}],"partialFingerprints":{"codehealthFindingId/v1":"116d121de9b4b42ae7e8329389c94e909f2b007b424143de1db80ac3eaab9e80"}},{"ruleId":"D1","level":"warning","message":{"text":"artifact_cli.cmd_run_analytics (cyclomatic 26): artifact_cli.cmd_run_analytics 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":"backend/scripts/artifact_cli.py"},"region":{"startLine":5272}}}],"partialFingerprints":{"codehealthFindingId/v1":"af6a1ef5328ae0bef2de9aa3317dc4bc89abbcd0a15760c6a906ab3a9ea006e3"}},{"ruleId":"D1","level":"warning","message":{"text":"polly.synthesize (cyclomatic 26): polly.synthesize 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":"backend/skills/s_pollinate/scripts/tts/backends/polly.py"},"region":{"startLine":246}}}],"partialFingerprints":{"codehealthFindingId/v1":"c1bdfcfb480397a025525c7740fd1d0f04dec24b1b5c06bba42002b78743179b"}},{"ruleId":"D1","level":"warning","message":{"text":"NewBrainOverlay.NewBrainContent (cyclomatic 26): NewBrainOverlay.NewBrainContent has cyclomatic complexity 26 (threshold 15). Most of this is not in the body itself: 2 of the 26 points are its own statements and the rest belongs to 9 function literals inside it that branch (lines 215, 142, 185, \u2026). The decisions are inside those literals, which nothing outside this body can call, review or test on its own, so splitting the enclosing body is not the move available here. To reduce it, lift the literals\u0027 work into a named function or method at the enclosing scope and have each literal call it, then reduce whichever part then reads as the largest."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/layout/NewBrainOverlay.tsx"},"region":{"startLine":92}}}],"partialFingerprints":{"codehealthFindingId/v1":"b33653064ff7560c1ca7ea7420ce1e2dd32885dc0a2ac625960c06d0a565653e"}},{"ruleId":"D1","level":"warning","message":{"text":"ActivityFeed.extractActivities (cyclomatic 26): ActivityFeed.extractActivities 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":"desktop/src/pages/chat/components/ActivityFeed.tsx"},"region":{"startLine":24}}}],"partialFingerprints":{"codehealthFindingId/v1":"f55fda75ac1fc907f6a84bc740ec29f1371c025dd8c2bb315361f21f50e5d598"}},{"ruleId":"D1","level":"warning","message":{"text":"EvalDashboard.GuideTab (cyclomatic 26): EvalDashboard.GuideTab has cyclomatic complexity 26 (threshold 15). Of this number, 21 points are the body\u0027s own statements and 5 belong to one function literal inside it that branches. 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":"desktop/src/pages/EvalDashboard.tsx"},"region":{"startLine":1698}}}],"partialFingerprints":{"codehealthFindingId/v1":"d3b22a823d3d9018c3741377f5de09a607f893694880dbded15bb0bc06aa5607"}},{"ruleId":"D1","level":"warning","message":{"text":"PdfRenderer.PdfRenderer (cyclomatic 26): PdfRenderer.PdfRenderer has cyclomatic complexity 26 (threshold 15). Most of this is not in the body itself: 9 of the 26 points are its own statements and the rest belongs to 7 function literals inside it that branch (lines 167, 59, 92, \u2026). The decisions are inside those literals, which nothing outside this body can call, review or test on its own, so splitting the enclosing body is not the move available here. To reduce it, lift the literals\u0027 work into a named function or method at the enclosing scope and have each literal call it, then reduce whichever part then reads as the largest."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/file-viewer/renderers/PdfRenderer.tsx"},"region":{"startLine":44}}}],"partialFingerprints":{"codehealthFindingId/v1":"c765a6f83b9e05a8e562eadb7263bf94295ee7ea151eed5c748cd7c1e4017087"}},{"ruleId":"D1","level":"warning","message":{"text":"OverlayHost.OverlayHost (cyclomatic 26): OverlayHost.OverlayHost has cyclomatic complexity 26 (threshold 15). Most of this is not in the body itself: 9 of the 26 points are its own statements and the rest belongs to 8 function literals inside it that branch (lines 77, 153, 106, \u2026). The decisions are inside those literals, which nothing outside this body can call, review or test on its own, so splitting the enclosing body is not the move available here. To reduce it, lift the literals\u0027 work into a named function or method at the enclosing scope and have each literal call it, then reduce whichever part then reads as the largest."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/layout/OverlayHost.tsx"},"region":{"startLine":58}}}],"partialFingerprints":{"codehealthFindingId/v1":"13c9f867236e29303b84d7d5add6973844f41e26417e0060c0694f126d02a4b3"}},{"ruleId":"D1","level":"warning","message":{"text":"blast_radius.analyze_diff (cyclomatic 25): blast_radius.analyze_diff 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":"backend/core/code_intel/blast_radius.py"},"region":{"startLine":180}}}],"partialFingerprints":{"codehealthFindingId/v1":"d784ea28b6c1f24ecf233ec91be8df973209b4c319f7c6c02a2b84619f12b5c0"}},{"ruleId":"D1","level":"warning","message":{"text":"ddd_cultivation.detect_contradiction (cyclomatic 25): ddd_cultivation.detect_contradiction 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":"backend/core/ddd_cultivation.py"},"region":{"startLine":1446}}}],"partialFingerprints":{"codehealthFindingId/v1":"fd7ecd886fbef4fe930c4c2f212b4560138d8057e3caad0c796efc835d99edcb"}},{"ruleId":"D1","level":"warning","message":{"text":"RetryManager._retry_with_resume (cyclomatic 25): RetryManager._retry_with_resume 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":"backend/core/retry_manager.py"},"region":{"startLine":265}}}],"partialFingerprints":{"codehealthFindingId/v1":"342ad3e6aaa09f4837e2ea97ad854670fbb22cd5695f9dff5450e2224d29f443"}},{"ruleId":"D1","level":"warning","message":{"text":"SessionUnit._check_mcp_health (cyclomatic 25): SessionUnit._check_mcp_health 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":"backend/core/session_unit.py"},"region":{"startLine":3111}}}],"partialFingerprints":{"codehealthFindingId/v1":"d2213c313ba07ee1b4580e3c4466cab52f6251205491d638e96c2bc00084ffc3"}},{"ruleId":"D1","level":"warning","message":{"text":"EvolutionMaintenanceHook.execute (cyclomatic 25): EvolutionMaintenanceHook.execute 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":"backend/hooks/evolution_maintenance_hook.py"},"region":{"startLine":196}}}],"partialFingerprints":{"codehealthFindingId/v1":"a8f126b17e621f07550e135b40274c492d53537cebe954ac3784892c440a95d6"}},{"ruleId":"D1","level":"warning","message":{"text":"settings.update_app_configuration (cyclomatic 25): settings.update_app_configuration 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":"backend/routers/settings.py"},"region":{"startLine":263}}}],"partialFingerprints":{"codehealthFindingId/v1":"7324de519377cac156537ae9cad1fc49674b5676e8b7d43f87ebdd29abcc745d"}},{"ruleId":"D1","level":"warning","message":{"text":"locked_write.locked_read_modify_write (cyclomatic 25): locked_write.locked_read_modify_write 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":"backend/scripts/locked_write.py"},"region":{"startLine":515}}}],"partialFingerprints":{"codehealthFindingId/v1":"2d2ab051f76c109d1dcb576c2832c667bb4b60bf3df8ff77c21d8cc7897a0aa0"}},{"ruleId":"D1","level":"warning","message":{"text":"pipeline_validator.check_ddd_consistency (cyclomatic 25): pipeline_validator.check_ddd_consistency 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":"backend/scripts/pipeline_validator.py"},"region":{"startLine":1787}}}],"partialFingerprints":{"codehealthFindingId/v1":"18c49a3f9bad9709822fdc2e4cd97b1e4a762ea2a24ca730e087632c9166121f"}},{"ruleId":"D1","level":"warning","message":{"text":"BaseSchemaValidator.validate_content_types (cyclomatic 25): BaseSchemaValidator.validate_content_types 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":"backend/skills/s_docx/ooxml/scripts/validation/base.py"},"region":{"startLine":522}}}],"partialFingerprints":{"codehealthFindingId/v1":"51be3ceec8adab196a48a1c7c0c77a79a4ed92f0ebb509c5f4a90bd79b5049ba"}},{"ruleId":"D1","level":"warning","message":{"text":"locked_write.locked_read_modify_write (cyclomatic 25): locked_write.locked_read_modify_write 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":"backend/skills/s_persist/scripts/locked_write.py"},"region":{"startLine":515}}}],"partialFingerprints":{"codehealthFindingId/v1":"dbc4235f58fa95e525e2ca28e53e4cebd24d730a6aefb52e6357ae1da8ddb4bd"}},{"ruleId":"D1","level":"warning","message":{"text":"pptx_to_deck.extract (cyclomatic 25): pptx_to_deck.extract 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":"backend/skills/s_pollinate/scripts/pptx_to_deck.py"},"region":{"startLine":36}}}],"partialFingerprints":{"codehealthFindingId/v1":"f155e41287c3518e7b64c198d18c08395be19f9224db03fd31c77bf63ec5cd09"}},{"ruleId":"D1","level":"warning","message":{"text":"sections.match_section_times (cyclomatic 25): sections.match_section_times 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":"backend/skills/s_pollinate/scripts/tts/sections.py"},"region":{"startLine":86}}}],"partialFingerprints":{"codehealthFindingId/v1":"4ce53a23fb7bcaf90f03896bb3ff7b891aa5a9b135ced6b5a9acfe42413398ab"}},{"ruleId":"D1","level":"warning","message":{"text":"BaseSchemaValidator.validate_content_types (cyclomatic 25): BaseSchemaValidator.validate_content_types 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":"backend/skills/s_pptx/ooxml/scripts/validation/base.py"},"region":{"startLine":525}}}],"partialFingerprints":{"codehealthFindingId/v1":"ebdb32d8dc86fed562cce20f1ddb095f47d534ca23a14beaab8f9c56b9d2d013"}},{"ruleId":"D1","level":"warning","message":{"text":"ai_ready_helpers._render_domain_skeleton_body (cyclomatic 25): ai_ready_helpers._render_domain_skeleton_body 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":"backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py"},"region":{"startLine":1568}}}],"partialFingerprints":{"codehealthFindingId/v1":"30bcd7816c42dd95e53085a2292e96eec56a9b7cbeddb2be1e6f2a8e5e3eb524"}},{"ruleId":"D1","level":"warning","message":{"text":"ai_ready_helpers.project_domain_skeleton (cyclomatic 25): ai_ready_helpers.project_domain_skeleton 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":"backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py"},"region":{"startLine":1225}}}],"partialFingerprints":{"codehealthFindingId/v1":"06c17d170044b114c56db2608c8662efbfdf77d2e6979a8bd3c0846171e67577"}},{"ruleId":"D1","level":"warning","message":{"text":"BrainHub.DistributeView (cyclomatic 25): BrainHub.DistributeView has cyclomatic complexity 25 (threshold 15). Of this number, 20 points are the body\u0027s own statements and 5 belong to 2 function literals inside it that branch. 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":"desktop/src/components/layout/BrainHub.tsx"},"region":{"startLine":1173}}}],"partialFingerprints":{"codehealthFindingId/v1":"3830e0f5bb1167dee341c222a5c3e65a05c2636aaf9ed4e844078ae6cc18f634"}},{"ruleId":"D1","level":"warning","message":{"text":"_ClaudeClientWrapper._extract_pid (cyclomatic 24): _ClaudeClientWrapper._extract_pid 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":"backend/core/claude_environment.py"},"region":{"startLine":81}}}],"partialFingerprints":{"codehealthFindingId/v1":"e2cec69f87b97c68952259f0883efef2303bbca317fb357e4a821f8b5dcf9f70"}},{"ruleId":"D1","level":"warning","message":{"text":"codebase_map._format_briefing (cyclomatic 24): codebase_map._format_briefing 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":"backend/core/code_intel/codebase_map.py"},"region":{"startLine":43}}}],"partialFingerprints":{"codehealthFindingId/v1":"5f8beeb1afd1ef8224dfdb5780149c97482433c1ef573dfb2f067bf83f7f31ca"}},{"ruleId":"D1","level":"warning","message":{"text":"parser._build_file_scope_regex (cyclomatic 24): parser._build_file_scope_regex has cyclomatic complexity 24 (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":"backend/core/code_intel/parser.py"},"region":{"startLine":784}}}],"partialFingerprints":{"codehealthFindingId/v1":"39c3e4ad86b24c44bb45ebe68b339faca90e6731ceab919f84a75a29c7f784f9"}},{"ruleId":"D1","level":"warning","message":{"text":"DddCultivationOrchestrator._ch_ddd_staleness (cyclomatic 24): DddCultivationOrchestrator._ch_ddd_staleness 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":"backend/core/ddd_orchestrator.py"},"region":{"startLine":444}}}],"partialFingerprints":{"codehealthFindingId/v1":"3146269c640de27729a9f594daedb3669215d8b4afdba313fcd662bee6264e86"}},{"ruleId":"D1","level":"warning","message":{"text":"DddCultivationOrchestrator._ch_entry_lifecycle (cyclomatic 24): DddCultivationOrchestrator._ch_entry_lifecycle 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":"backend/core/ddd_orchestrator.py"},"region":{"startLine":815}}}],"partialFingerprints":{"codehealthFindingId/v1":"404093e18e5d31ef863825cf729414a0aa28398e1985aef945a2154c3b0bfc6e"}},{"ruleId":"D1","level":"warning","message":{"text":"SummarizationPipeline._parse_enrichment (cyclomatic 24): SummarizationPipeline._parse_enrichment 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":"backend/core/summarization.py"},"region":{"startLine":823}}}],"partialFingerprints":{"codehealthFindingId/v1":"b2ca271a918a570116505c759a07bcbd5e56947a2840ab0ddb7b11619241864d"}},{"ruleId":"D1","level":"warning","message":{"text":"ContextHealthHook._deep_check (cyclomatic 24): ContextHealthHook._deep_check 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":"backend/hooks/context_health_hook.py"},"region":{"startLine":2492}}}],"partialFingerprints":{"codehealthFindingId/v1":"08def90419ab59c1787d427b7f4d5c50a148a2ee1f98e62037bb6a6341c0564c"}},{"ruleId":"D1","level":"warning","message":{"text":"tscc.get_security_scan (cyclomatic 24): tscc.get_security_scan has cyclomatic complexity 24 (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":"backend/routers/tscc.py"},"region":{"startLine":159}}}],"partialFingerprints":{"codehealthFindingId/v1":"e829185ad30e4403f3922b053d4717c3ffeb0153c5a010a4968bc895834b3baa"}},{"ruleId":"D1","level":"warning","message":{"text":"workspace_api._build_tree (cyclomatic 24): workspace_api._build_tree 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":"backend/routers/workspace_api.py"},"region":{"startLine":349}}}],"partialFingerprints":{"codehealthFindingId/v1":"b978470a83956d42a226845bb0551d14d7f434aedd2354a798a83eef6ba77475"}},{"ruleId":"D1","level":"warning","message":{"text":"pipeline_validator._verify_findings_on_disk (cyclomatic 24): pipeline_validator._verify_findings_on_disk 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":"backend/scripts/pipeline_validator.py"},"region":{"startLine":155}}}],"partialFingerprints":{"codehealthFindingId/v1":"0e80e222f40ae1609dfde27b9e7060195c2e87afe5ea6b6a923c43c23f9492bf"}},{"ruleId":"D1","level":"warning","message":{"text":"replace.apply_replacements (cyclomatic 24): replace.apply_replacements 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":"backend/skills/s_pptx/scripts/replace.py"},"region":{"startLine":214}}}],"partialFingerprints":{"codehealthFindingId/v1":"11c21d22f369d669a0a731247f454c6579c970867d787ffc3fe8d52ffd9bd83b"}},{"ruleId":"D1","level":"warning","message":{"text":"ai_ready_helpers.compute_business_rules_dimension (cyclomatic 24): ai_ready_helpers.compute_business_rules_dimension 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":"backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py"},"region":{"startLine":3973}}}],"partialFingerprints":{"codehealthFindingId/v1":"c51724dc1927af37d511f7cc5cb7b271c7b411d2daef35e0e2ab1e13aa720a57"}},{"ruleId":"D1","level":"warning","message":{"text":"html2pptx.addElements (cyclomatic 24): html2pptx.addElements 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":"backend/skills/s_pptx/scripts/html2pptx.js"},"region":{"startLine":133}}}],"partialFingerprints":{"codehealthFindingId/v1":"f2358ceefffe121c6cf3667456d515563e2a02e13346dfc212a616fbf0b5c66b"}},{"ruleId":"D1","level":"warning","message":{"text":"BrainHub.ReviewView (cyclomatic 24): BrainHub.ReviewView has cyclomatic complexity 24 (threshold 15). Of this number, 18 points are the body\u0027s own statements and 6 belong to 4 function literals inside it that branch. 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":"desktop/src/components/layout/BrainHub.tsx"},"region":{"startLine":840}}}],"partialFingerprints":{"codehealthFindingId/v1":"ecc4cca679a4788678db1af06ef876a34155fff30ad81edbcf4132c5c69f85e3"}},{"ruleId":"D1","level":"warning","message":{"text":"useCanvasAutoSurface.useCanvasAutoSurface (cyclomatic 24): useCanvasAutoSurface.useCanvasAutoSurface has cyclomatic complexity 24 (threshold 15). Most of this is not in the body itself: 1 of the 24 points is its own statement and the rest belongs to 4 function literals inside it that branch (lines 133, 189, 103, \u2026). The decisions are inside those literals, which nothing outside this body can call, review or test on its own, so splitting the enclosing body is not the move available here. To reduce it, lift the literals\u0027 work into a named function or method at the enclosing scope and have each literal call it, then reduce whichever part then reads as the largest."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/hooks/useCanvasAutoSurface.ts"},"region":{"startLine":75}}}],"partialFingerprints":{"codehealthFindingId/v1":"f2f43f7f18d754019cc44d7e6ed6e59b6633198adaa7c55ed3c6dc0f1340c65b"}},{"ruleId":"D1","level":"warning","message":{"text":"SlackChannelAdapter._text_to_blocks (cyclomatic 23): SlackChannelAdapter._text_to_blocks 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":"backend/channels/adapters/slack.py"},"region":{"startLine":1923}}}],"partialFingerprints":{"codehealthFindingId/v1":"d984a153b123ea9c66631431126bc339fd04835b4573aefaea00da15ac9b34d3"}},{"ruleId":"D1","level":"warning","message":{"text":"code_intel_feed.detect_tech_drift (cyclomatic 23): code_intel_feed.detect_tech_drift 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":"backend/core/code_intel_feed.py"},"region":{"startLine":59}}}],"partialFingerprints":{"codehealthFindingId/v1":"ddfd80f134ab4da5dac23f2f912f05e4faeba970508e078210b1f60e044c6110"}},{"ruleId":"D1","level":"warning","message":{"text":"context_injector._extract_tool_summary (cyclomatic 23): context_injector._extract_tool_summary 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":"backend/core/context_injector.py"},"region":{"startLine":215}}}],"partialFingerprints":{"codehealthFindingId/v1":"8501beddcdd5521a2fc20edaa8f4819c2952cff1fb42dfa3c9932b05fd53f212"}},{"ruleId":"D1","level":"warning","message":{"text":"context_injector.build_resume_context (cyclomatic 23): context_injector.build_resume_context 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":"backend/core/context_injector.py"},"region":{"startLine":1139}}}],"partialFingerprints":{"codehealthFindingId/v1":"88d0230b7ed45b4f3f43764683e5e60d640386ec3e35a3a4e2c2c06f617efb4f"}},{"ruleId":"D1","level":"warning","message":{"text":"prompt_builder._render_ui_context_section (cyclomatic 23): prompt_builder._render_ui_context_section 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":"backend/core/prompt_builder.py"},"region":{"startLine":202}}}],"partialFingerprints":{"codehealthFindingId/v1":"dd3dec06056983f08fd25d0794e488806d501e78d5a8f736886436230bcae18d"}},{"ruleId":"D1","level":"warning","message":{"text":"ContextHealthHook._extract_lessons_to_memory (cyclomatic 23): ContextHealthHook._extract_lessons_to_memory 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":"backend/hooks/context_health_hook.py"},"region":{"startLine":969}}}],"partialFingerprints":{"codehealthFindingId/v1":"872a553a646ffcd3ccf8fb318980dd7727af7544805b77cf8558e35f3f197d46"}},{"ruleId":"D1","level":"warning","message":{"text":"memory_health._resolve_open_thread (cyclomatic 23): memory_health._resolve_open_thread 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":"backend/jobs/handlers/memory_health.py"},"region":{"startLine":887}}}],"partialFingerprints":{"codehealthFindingId/v1":"ae3419a7120b1d181a8047e895da5de17ba304f999ae94ca7f9b046c158a121e"}},{"ruleId":"D1","level":"warning","message":{"text":"artifact_cli.cmd_release_gate (cyclomatic 23): artifact_cli.cmd_release_gate 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":"backend/scripts/artifact_cli.py"},"region":{"startLine":3258}}}],"partialFingerprints":{"codehealthFindingId/v1":"3761dc3f58d89de4af09802515dc180cf2b72f9db9e0174d83fe1127748b75dd"}},{"ruleId":"D1","level":"warning","message":{"text":"BaseSchemaValidator.validate_file_references (cyclomatic 23): BaseSchemaValidator.validate_file_references 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":"backend/skills/s_docx/ooxml/scripts/validation/base.py"},"region":{"startLine":277}}}],"partialFingerprints":{"codehealthFindingId/v1":"8e6b1659caad00be010372f09f1de0b10b77f9710a74ce1629056022b3094b9d"}},{"ruleId":"D1","level":"warning","message":{"text":"DocxXMLEditor.suggest_deletion (cyclomatic 23): DocxXMLEditor.suggest_deletion 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":"backend/skills/s_docx/scripts/document.py"},"region":{"startLine":482}}}],"partialFingerprints":{"codehealthFindingId/v1":"90b7ccb10125a5bc2cf5fbcf1db687e6ba597c08e68e8f12606435c768da323e"}},{"ruleId":"D1","level":"warning","message":{"text":"SelfLoopsHealthEngine._auto_remediate (cyclomatic 23): SelfLoopsHealthEngine._auto_remediate 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":"backend/skills/s_loops-health/scripts/loops_health_check.py"},"region":{"startLine":692}}}],"partialFingerprints":{"codehealthFindingId/v1":"16159e998933fc07bde4b709f16e4d6c0bae3e163aa5e49aa6c0f0e9bc86c45b"}},{"ruleId":"D1","level":"warning","message":{"text":"BaseSchemaValidator.validate_file_references (cyclomatic 23): BaseSchemaValidator.validate_file_references 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":"backend/skills/s_pptx/ooxml/scripts/validation/base.py"},"region":{"startLine":280}}}],"partialFingerprints":{"codehealthFindingId/v1":"83021222ba0001ff0441938621110bdc9f420b5e1daf00a4592ea569e591d19c"}},{"ruleId":"D1","level":"warning","message":{"text":"ai_ready_helpers.select_verification_tasks (cyclomatic 23): ai_ready_helpers.select_verification_tasks 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":"backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py"},"region":{"startLine":3252}}}],"partialFingerprints":{"codehealthFindingId/v1":"9b7b2e53f79cda4fd8683363d006d845cbc22c5e91499ecf90d00447ffc8150f"}},{"ruleId":"D1","level":"warning","message":{"text":"BottomBar.BottomBar (cyclomatic 23): BottomBar.BottomBar has cyclomatic complexity 23 (threshold 15). Of this number, 13 points are the body\u0027s own statements and 10 belong to 8 function literals inside it that branch. 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":"desktop/src/components/layout/BottomBar.tsx"},"region":{"startLine":89}}}],"partialFingerprints":{"codehealthFindingId/v1":"f51ae7778e76ebb102f1960b70619bb065db2af7a27535d371b1abe6d7ed650a"}},{"ruleId":"D1","level":"warning","message":{"text":"CMBrainOverlay.CMBrainContent (cyclomatic 23): CMBrainOverlay.CMBrainContent 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":"desktop/src/components/layout/CMBrainOverlay.tsx"},"region":{"startLine":167}}}],"partialFingerprints":{"codehealthFindingId/v1":"f48d69f8b210ac08dd19dd06e185aba4764b629c5f36a57cf3850966d6a1ce3d"}},{"ruleId":"D1","level":"warning","message":{"text":"ToDoOverlay.ToDoContent (cyclomatic 23): ToDoOverlay.ToDoContent has cyclomatic complexity 23 (threshold 15). Most of this is not in the body itself: 7 of the 23 points are its own statements and the rest belongs to 8 function literals inside it that branch (lines 299, 249, 214, \u2026). The decisions are inside those literals, which nothing outside this body can call, review or test on its own, so splitting the enclosing body is not the move available here. To reduce it, lift the literals\u0027 work into a named function or method at the enclosing scope and have each literal call it, then reduce whichever part then reads as the largest."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/layout/ToDoOverlay.tsx"},"region":{"startLine":195}}}],"partialFingerprints":{"codehealthFindingId/v1":"1cee15977b67a641973cf214c96b3afc4025a9a131830f89aee7955ef60e8cb8"}},{"ruleId":"D1","level":"warning","message":{"text":"TSCCPopoverButton.TSCCPopoverButton (cyclomatic 23): TSCCPopoverButton.TSCCPopoverButton has cyclomatic complexity 23 (threshold 15). Most of this is not in the body itself: 7 of the 23 points are its own statements and the rest belongs to 7 function literals inside it that branch (lines 105, 80, 70, \u2026). The decisions are inside those literals, which nothing outside this body can call, review or test on its own, so splitting the enclosing body is not the move available here. To reduce it, lift the literals\u0027 work into a named function or method at the enclosing scope and have each literal call it, then reduce whichever part then reads as the largest."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/pages/chat/components/TSCCPopoverButton.tsx"},"region":{"startLine":62}}}],"partialFingerprints":{"codehealthFindingId/v1":"96dd216821ca0169f7621510778071cebdb6d9c6e85f9cf3f4c80e9181bcd72c"}},{"ruleId":"D1","level":"warning","message":{"text":"code_intel_hook._build_context (cyclomatic 22): code_intel_hook._build_context 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":"backend/core/code_intel/code_intel_hook.py"},"region":{"startLine":235}}}],"partialFingerprints":{"codehealthFindingId/v1":"ead68e9d182a8177023be3f65d28d8d24b1efb07fa471eb2b9c01c20e93bf57c"}},{"ruleId":"D1","level":"warning","message":{"text":"correction_tracker._merge_drift (cyclomatic 22): correction_tracker._merge_drift 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":"backend/core/evolution/correction_tracker.py"},"region":{"startLine":69}}}],"partialFingerprints":{"codehealthFindingId/v1":"afaec7030231afcb947c3f806aae5491649dd1fa5de89efb675c4a97c33282b7"}},{"ruleId":"D1","level":"warning","message":{"text":"library_health.scan_library_health (cyclomatic 22): library_health.scan_library_health 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":"backend/core/library_health.py"},"region":{"startLine":103}}}],"partialFingerprints":{"codehealthFindingId/v1":"3ecb14e659e87d602bfb4146ddced3f0c192b264104a24a967143081fe91032b"}},{"ruleId":"D1","level":"warning","message":{"text":"proactive_learning.update_learning_from_activity (cyclomatic 22): proactive_learning.update_learning_from_activity 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":"backend/core/proactive_learning.py"},"region":{"startLine":431}}}],"partialFingerprints":{"codehealthFindingId/v1":"11a5f235888273641ff2714370ce92c3b33ec05c05cb19b8f79598cfa1621ed4"}},{"ruleId":"D1","level":"warning","message":{"text":"session_health_probe.session_health_probe (cyclomatic 22): session_health_probe.session_health_probe has cyclomatic complexity 22 (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":"backend/core/session_health_probe.py"},"region":{"startLine":190}}}],"partialFingerprints":{"codehealthFindingId/v1":"2721287275a2605b9b3f5abec07f33e4becee8a55c7a68128f858e7bd37b91c3"}},{"ruleId":"D1","level":"warning","message":{"text":"skill_migration.migrate_skill_ids_to_allowed_skills (cyclomatic 22): skill_migration.migrate_skill_ids_to_allowed_skills 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":"backend/core/skill_migration.py"},"region":{"startLine":25}}}],"partialFingerprints":{"codehealthFindingId/v1":"bbc1e4ac8c85d50a613547229b5c36f21d67d7d22dd765e7187be8d6075dba64"}},{"ruleId":"D1","level":"warning","message":{"text":"ContextHealthHook._set_verified_from_pipeline_runs (cyclomatic 22): ContextHealthHook._set_verified_from_pipeline_runs 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":"backend/hooks/context_health_hook.py"},"region":{"startLine":1433}}}],"partialFingerprints":{"codehealthFindingId/v1":"e0b0379ab5eba98b7ae3e5cb571fd22ad1a36e12500d73cbea1339f0b422e8bf"}},{"ruleId":"D1","level":"warning","message":{"text":"DistillationTriggerHook._enforce_section_caps (cyclomatic 22): DistillationTriggerHook._enforce_section_caps 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":"backend/hooks/distillation_hook.py"},"region":{"startLine":2372}}}],"partialFingerprints":{"codehealthFindingId/v1":"34b87a94dc393db3e8e3bc4c0ebf764f23f5c5a9267b160cc5c244328fc8c09e"}},{"ruleId":"D1","level":"warning","message":{"text":"ddd_self_audit.run_ddd_self_audit (cyclomatic 22): ddd_self_audit.run_ddd_self_audit 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":"backend/jobs/handlers/ddd_self_audit.py"},"region":{"startLine":221}}}],"partialFingerprints":{"codehealthFindingId/v1":"e5a8b1e3e8caaf5b72ed93d6caaa4a6a3a46a2a3d0c3bb05b55a6833022d2a2b"}},{"ruleId":"D1","level":"warning","message":{"text":"workspace_api._get_git_status (cyclomatic 22): workspace_api._get_git_status 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":"backend/routers/workspace_api.py"},"region":{"startLine":261}}}],"partialFingerprints":{"codehealthFindingId/v1":"6c61684df50b299e142cd4c504a36754501dfb7406de5507cf62a7eee1df6e5f"}},{"ruleId":"D1","level":"warning","message":{"text":"artifact_cli.cmd_run_status (cyclomatic 22): artifact_cli.cmd_run_status 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":"backend/scripts/artifact_cli.py"},"region":{"startLine":3828}}}],"partialFingerprints":{"codehealthFindingId/v1":"5138abaa2dc9307ae6bf7231f22aa1a53fbb41ccfbd7c4cba6c7f466df4e5921"}},{"ruleId":"D1","level":"warning","message":{"text":"backfill_cjk_escapes._populate_seg_columns (cyclomatic 22): backfill_cjk_escapes._populate_seg_columns 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":"backend/scripts/backfill_cjk_escapes.py"},"region":{"startLine":444}}}],"partialFingerprints":{"codehealthFindingId/v1":"b9edad83dc859ee844e1148465401ff79643c4ccc03c48cd324dc14753aad422"}},{"ruleId":"D1","level":"warning","message":{"text":"eval_runner.evaluate_case (cyclomatic 22): eval_runner.evaluate_case 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":"backend/scripts/eval_runner.py"},"region":{"startLine":1606}}}],"partialFingerprints":{"codehealthFindingId/v1":"1af15584f241135f9f2724cd5b3a1eaa6f5f7be9aacf9baac40d7fcc2158449e"}},{"ruleId":"D1","level":"warning","message":{"text":"evolution_escalation_probe.main (cyclomatic 22): evolution_escalation_probe.main 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":"backend/scripts/evolution_escalation_probe.py"},"region":{"startLine":73}}}],"partialFingerprints":{"codehealthFindingId/v1":"913023ad8950b117297f8c9f1133e0a4af4e730ad496aee98c8fab4a89541a99"}},{"ruleId":"D1","level":"warning","message":{"text":"pipeline_analytics._load_all_metrics (cyclomatic 22): pipeline_analytics._load_all_metrics 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":"backend/scripts/pipeline_analytics.py"},"region":{"startLine":64}}}],"partialFingerprints":{"codehealthFindingId/v1":"5a314967a0a08cea48f349283d58d08b2bf566929b7fa95382037d936f738e80"}},{"ruleId":"D1","level":"warning","message":{"text":"pipeline_analytics.analyze_stage_efficiency (cyclomatic 22): pipeline_analytics.analyze_stage_efficiency 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":"backend/scripts/pipeline_analytics.py"},"region":{"startLine":503}}}],"partialFingerprints":{"codehealthFindingId/v1":"c35836e50fa08df6cffdfef57c5fb682b6c24df48e72bf7a4568fd7456f800e0"}},{"ruleId":"D1","level":"warning","message":{"text":"pipeline_validator._check_security_boundaries (cyclomatic 22): pipeline_validator._check_security_boundaries 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":"backend/scripts/pipeline_validator.py"},"region":{"startLine":1124}}}],"partialFingerprints":{"codehealthFindingId/v1":"42cde711562a09e1196e306fca450b785d496f80f52388a62ab3ad901faae342"}},{"ruleId":"D1","level":"warning","message":{"text":"SelfLoopsHealthEngine._check_infrastructure (cyclomatic 22): SelfLoopsHealthEngine._check_infrastructure 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":"backend/skills/s_loops-health/scripts/loops_health_check.py"},"region":{"startLine":609}}}],"partialFingerprints":{"codehealthFindingId/v1":"0f5a0beeed325b6a3a290e8c6d688a276bdc02ff9435e850c8f05f81446664fc"}},{"ruleId":"D1","level":"warning","message":{"text":"publish_dashboard.scan_deliver (cyclomatic 22): publish_dashboard.scan_deliver 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":"backend/skills/s_pollinate/scripts/publish_dashboard.py"},"region":{"startLine":44}}}],"partialFingerprints":{"codehealthFindingId/v1":"fd6cb306694691449d88e9b79a0a0a1b903910522a12d374ac769f85d94119fb"}},{"ruleId":"D1","level":"warning","message":{"text":"todo_db._build_linked_context (cyclomatic 22): todo_db._build_linked_context 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":"backend/skills/s_radar-todo/scripts/todo_db.py"},"region":{"startLine":78}}}],"partialFingerprints":{"codehealthFindingId/v1":"e8b03d8b593c67427c271064c78854c29e35bc8632848e454d61648285425576"}},{"ruleId":"D1","level":"warning","message":{"text":"DiagramReveal.autoLayout (cyclomatic 22): DiagramReveal.autoLayout 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":"backend/skills/s_pollinate/templates/remotion/components/DiagramReveal.tsx"},"region":{"startLine":65}}}],"partialFingerprints":{"codehealthFindingId/v1":"c307132d38923b910d479b0b8ff0ef70cf2b541ff3a578126e88b5b0aee4f579"}},{"ruleId":"D1","level":"warning","message":{"text":"hiveComponents.InstanceCard (cyclomatic 22): hiveComponents.InstanceCard has cyclomatic complexity 22 (threshold 15). Of this number, 19 points are the body\u0027s own statements and 3 belong to 3 function literals inside it that branch. To reduce it, name the conditions: bind each compound test to a well-named local or a small predicate function, so the body reads as a sequence of named decisions rather than a chain of operators."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/settings/hiveComponents.tsx"},"region":{"startLine":114}}}],"partialFingerprints":{"codehealthFindingId/v1":"f9c2106d4dd56d9bbccbbc843a345d98a716b4b2675092c99c2f90ff3327a1a8"}},{"ruleId":"D1","level":"warning","message":{"text":"hiveComponents.AuthDisplay (cyclomatic 22): hiveComponents.AuthDisplay has cyclomatic complexity 22 (threshold 15). Of this number, 11 points are the body\u0027s own statements and 11 belong to 5 function literals inside it that branch. 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":"desktop/src/components/settings/hiveComponents.tsx"},"region":{"startLine":256}}}],"partialFingerprints":{"codehealthFindingId/v1":"7ef2f294a1816b01d95974dd3e719ac838faaff84f601cdee200f350b6992401"}},{"ruleId":"D1","level":"warning","message":{"text":"SystemTab.SystemTab (cyclomatic 22): SystemTab.SystemTab has cyclomatic complexity 22 (threshold 15). Of this number, 13 points are the body\u0027s own statements and 9 belong to 2 function literals inside it that branch. 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":"desktop/src/components/settings/SystemTab.tsx"},"region":{"startLine":26}}}],"partialFingerprints":{"codehealthFindingId/v1":"93477df5d9223aa4830261034f8d05b6d67313cdf80ba29df5a73bd291261580"}},{"ruleId":"D1","level":"warning","message":{"text":"AboutTab.AboutTab (cyclomatic 22): AboutTab.AboutTab has cyclomatic complexity 22 (threshold 15). Of this number, 13 points are the body\u0027s own statements and 9 belong to 4 function literals inside it that branch. To reduce it, name the conditions: bind each compound test to a well-named local or a small predicate function, so the body reads as a sequence of named decisions rather than a chain of operators."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/settings/AboutTab.tsx"},"region":{"startLine":26}}}],"partialFingerprints":{"codehealthFindingId/v1":"77f498de9806b040952d58adf6e7cca4cf606381b627872fa995c0fbd3d58cbf"}},{"ruleId":"D1","level":"warning","message":{"text":"OnboardingPage.StepRestore (cyclomatic 22): OnboardingPage.StepRestore has cyclomatic complexity 22 (threshold 15). Most of this is not in the body itself: 10 of the 22 points are its own statements and the rest belongs to 3 function literals inside it that branch (lines 386, 462, 372). The decisions are inside those literals, which nothing outside this body can call, review or test on its own, so splitting the enclosing body is not the move available here. To reduce it, lift the literals\u0027 work into a named function or method at the enclosing scope and have each literal call it, then reduce whichever part then reads as the largest."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/pages/OnboardingPage.tsx"},"region":{"startLine":354}}}],"partialFingerprints":{"codehealthFindingId/v1":"8d6de3359743e0898ea2b5bad2bb3f10ce5a0a002b2069ad3766a39b4ef5e8e2"}},{"ruleId":"D1","level":"warning","message":{"text":"community_data.parse_hot_topics (cyclomatic 21): community_data.parse_hot_topics 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":"backend/core/community_data.py"},"region":{"startLine":732}}}],"partialFingerprints":{"codehealthFindingId/v1":"06da55d87fc8d36cb9f669d1d76b46a9f62af1861ccd68a7117b4d43248c8823"}},{"ruleId":"D1","level":"warning","message":{"text":"mcp_config_loader.merge_catalog_template (cyclomatic 21): mcp_config_loader.merge_catalog_template 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":"backend/core/mcp_config_loader.py"},"region":{"startLine":149}}}],"partialFingerprints":{"codehealthFindingId/v1":"1fb04a4133c88039aca1f80439f4cd588d7871180404ccd400a16101d131855a"}},{"ruleId":"D1","level":"warning","message":{"text":"mcp_migration.migrate_if_needed (cyclomatic 21): mcp_migration.migrate_if_needed 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":"backend/core/mcp_migration.py"},"region":{"startLine":28}}}],"partialFingerprints":{"codehealthFindingId/v1":"a583ef1e3f7a2a9ecacc0b149d114e56c85dffd865619feecba1dcb6f3418be0"}},{"ruleId":"D1","level":"warning","message":{"text":"SessionUnit._spawn (cyclomatic 21): SessionUnit._spawn has cyclomatic complexity 21 (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":"backend/core/session_unit.py"},"region":{"startLine":3278}}}],"partialFingerprints":{"codehealthFindingId/v1":"64e40a8bb988a6c79d37a4b1865874b8f91ddd3cf6feefa32a2758f72f27592b"}},{"ruleId":"D1","level":"warning","message":{"text":"SwarmWorkspaceManager._cleanup_legacy_content (cyclomatic 21): SwarmWorkspaceManager._cleanup_legacy_content 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":"backend/core/swarm_workspace_manager.py"},"region":{"startLine":2092}}}],"partialFingerprints":{"codehealthFindingId/v1":"33080e09f922b694dfc4974fd436e37d0e4d5cb344fdd99aa031d2df557ae3b7"}},{"ruleId":"D1","level":"warning","message":{"text":"DistillationTriggerHook._apply_open_thread_updates (cyclomatic 21): DistillationTriggerHook._apply_open_thread_updates 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":"backend/hooks/distillation_hook.py"},"region":{"startLine":1964}}}],"partialFingerprints":{"codehealthFindingId/v1":"e7efd23fde120c4aef90be1a95039949fab102caece2edb76543b0c0539a8609"}},{"ruleId":"D1","level":"warning","message":{"text":"pollinate._walk_assets (cyclomatic 21): pollinate._walk_assets 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":"backend/routers/pollinate.py"},"region":{"startLine":327}}}],"partialFingerprints":{"codehealthFindingId/v1":"f23587ba25ef3b40462fd7c4d1cb1221fda76992ba313df04e190ca402f94940"}},{"ruleId":"D1","level":"warning","message":{"text":"generate_shorts.main (cyclomatic 21): generate_shorts.main 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":"backend/skills/s_pollinate/scripts/generate_shorts.py"},"region":{"startLine":522}}}],"partialFingerprints":{"codehealthFindingId/v1":"843fa8ddab71df9f03b28ec87459dc8f4b0ccdc4597e6f6c7cf5529cd8e7cc72"}},{"ruleId":"D1","level":"warning","message":{"text":"ShapeData._estimate_frame_overflow (cyclomatic 21): ShapeData._estimate_frame_overflow 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":"backend/skills/s_pptx/scripts/inventory.py"},"region":{"startLine":562}}}],"partialFingerprints":{"codehealthFindingId/v1":"7f034b0c2b6b8c593a6df1220e2676c86dedcad9d6d42e43032538336eb5174c"}},{"ruleId":"D1","level":"warning","message":{"text":"rearrange.rearrange_presentation (cyclomatic 21): rearrange.rearrange_presentation 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":"backend/skills/s_pptx/scripts/rearrange.py"},"region":{"startLine":149}}}],"partialFingerprints":{"codehealthFindingId/v1":"d9cb99559c712b44e017c9746cff01e3deecb59e9e43eead3a0fd5ddd2709ebc"}},{"ruleId":"D1","level":"warning","message":{"text":"mcp_validation.validate_config_entry (cyclomatic 21): mcp_validation.validate_config_entry 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":"backend/utils/mcp_validation.py"},"region":{"startLine":105}}}],"partialFingerprints":{"codehealthFindingId/v1":"536dec8fb37fe90f20af7379e9dfb9abac57bdf94852a930de299032274f1721"}},{"ruleId":"D1","level":"warning","message":{"text":"DeckStage._onKey (cyclomatic 21): DeckStage._onKey has cyclomatic complexity 21 (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":"backend/skills/s_pollinate/templates/html-deck/shared/deck-stage.js"},"region":{"startLine":559}}}],"partialFingerprints":{"codehealthFindingId/v1":"67ae4965eb0cf180554979930c804e2f4bcf1d1ef71276c862f9726ded549667"}},{"ruleId":"D1","level":"warning","message":{"text":"Dropdown.Dropdown (cyclomatic 21): Dropdown.Dropdown has cyclomatic complexity 21 (threshold 15). Of this number, 17 points are the body\u0027s own statements and 4 belong to 3 function literals inside it that branch. To reduce it, name the conditions: bind each compound test to a well-named local or a small predicate function, so the body reads as a sequence of named decisions rather than a chain of operators."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/common/Dropdown.tsx"},"region":{"startLine":22}}}],"partialFingerprints":{"codehealthFindingId/v1":"e075b7898e6df307f7da108b33c5e9b292a0da81018866428c1f31c49ee27db5"}},{"ruleId":"D1","level":"warning","message":{"text":"HistoryView.HistoryView (cyclomatic 21): HistoryView.HistoryView has cyclomatic complexity 21 (threshold 15). Of this number, 14 points are the body\u0027s own statements and 7 belong to 5 function literals inside it that branch. 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":"desktop/src/pages/chat/components/RightSidebar/HistoryView.tsx"},"region":{"startLine":34}}}],"partialFingerprints":{"codehealthFindingId/v1":"52170c20f693ed905bb07090b432fa2e568faeab8c82143c3b6b7d2a928e75aa"}},{"ruleId":"D1","level":"warning","message":{"text":"TerminalTab.TerminalTab (cyclomatic 21): TerminalTab.TerminalTab has cyclomatic complexity 21 (threshold 15). Most of this is not in the body itself: 1 of the 21 points is its own statement and the rest belongs to 6 function literals inside it that branch (lines 233, 154, 107, \u2026). The decisions are inside those literals, which nothing outside this body can call, review or test on its own, so splitting the enclosing body is not the move available here. To reduce it, lift the literals\u0027 work into a named function or method at the enclosing scope and have each literal call it, then reduce whichever part then reads as the largest."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/terminal/TerminalTab.tsx"},"region":{"startLine":61}}}],"partialFingerprints":{"codehealthFindingId/v1":"7d93d0251c89e9abecf4e3cfc0c5e5f1faad6e65f9cf204b9bea780ec4d53df0"}},{"ruleId":"D1","level":"warning","message":{"text":"(anonymous)::_onKey (cyclomatic 21): (anonymous)::_onKey has cyclomatic complexity 21 (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":"backend/skills/s_pollinate/templates/html-deck/shared/deck-stage.js"},"region":{"startLine":559}}}],"partialFingerprints":{"codehealthFindingId/v1":"be618f19daf28c3bbc508d14bad993af43f34b1e6faf5b22ada5765b541b39d0"}},{"ruleId":"D1","level":"warning","message":{"text":"canvas_surface.is_canvas_surfaceable (cyclomatic 20): canvas_surface.is_canvas_surfaceable has cyclomatic complexity 20 (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":"backend/core/canvas_surface.py"},"region":{"startLine":90}}}],"partialFingerprints":{"codehealthFindingId/v1":"5576ae6f15b942f2f0fe99525b633fbe6a5113048412303108b37460038c26f0"}},{"ruleId":"D1","level":"warning","message":{"text":"knowledge_store.sync_knowledge_index (cyclomatic 20): knowledge_store.sync_knowledge_index 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":"backend/core/knowledge_store.py"},"region":{"startLine":737}}}],"partialFingerprints":{"codehealthFindingId/v1":"c452ebd7853eda54bf2f84d28809c6293c24e35c20a4b66164e7fb01483b8022"}},{"ruleId":"D1","level":"warning","message":{"text":"proactive_intelligence._parse_continue_hints (cyclomatic 20): proactive_intelligence._parse_continue_hints 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":"backend/core/proactive_intelligence.py"},"region":{"startLine":176}}}],"partialFingerprints":{"codehealthFindingId/v1":"2224f3751d6f998c69b15e948702e52641a6f4284c548b58c3ae1ccd42651039"}},{"ruleId":"D1","level":"warning","message":{"text":"proactive_intelligence._get_job_result_highlights (cyclomatic 20): proactive_intelligence._get_job_result_highlights 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":"backend/core/proactive_intelligence.py"},"region":{"startLine":627}}}],"partialFingerprints":{"codehealthFindingId/v1":"615b4111bc04d9dbf2fd4765fdd2bf9be00719038a81d9d1da0fb03ab52c70e9"}},{"ruleId":"D1","level":"warning","message":{"text":"skill_manager.parse_skill_md (cyclomatic 20): skill_manager.parse_skill_md has cyclomatic complexity 20 (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":"backend/core/skill_manager.py"},"region":{"startLine":215}}}],"partialFingerprints":{"codehealthFindingId/v1":"7ab0ea34a4b930cbad1a250a88eb0ba771126a351261231593799a8aa9bec7f6"}},{"ruleId":"D1","level":"warning","message":{"text":"ContextHealthHook._light_refresh (cyclomatic 20): ContextHealthHook._light_refresh has cyclomatic complexity 20 (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":"backend/hooks/context_health_hook.py"},"region":{"startLine":175}}}],"partialFingerprints":{"codehealthFindingId/v1":"44595affc769a24001cac1b4ffba7fada6f9fa76389e3f3b3a9b0e76eeb82753"}},{"ruleId":"D1","level":"warning","message":{"text":"ContextHealthHook._run_eval_canary (cyclomatic 20): ContextHealthHook._run_eval_canary 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":"backend/hooks/context_health_hook.py"},"region":{"startLine":346}}}],"partialFingerprints":{"codehealthFindingId/v1":"00052d1cca861749015d794ddc84f607b4a17a9826b55ed509ce75289ce744a6"}},{"ruleId":"D1","level":"warning","message":{"text":"ImprovementWritebackHook._detect_project (cyclomatic 20): ImprovementWritebackHook._detect_project 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":"backend/hooks/improvement_writeback_hook.py"},"region":{"startLine":151}}}],"partialFingerprints":{"codehealthFindingId/v1":"8e31fcf7d7cf3464ffcc9481ed1066cead62f0391868e5c17ebf4eeba58f2c84"}},{"ruleId":"D1","level":"warning","message":{"text":"model_resolve.resolve_job_model (cyclomatic 20): model_resolve.resolve_job_model has cyclomatic complexity 20 (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":"backend/jobs/model_resolve.py"},"region":{"startLine":36}}}],"partialFingerprints":{"codehealthFindingId/v1":"fdc0ff7301b62ab3c89a5f9b93c241c435d3cc87b0cb05f4a75a6cac458a87e2"}},{"ruleId":"D1","level":"warning","message":{"text":"agents.update_agent (cyclomatic 20): agents.update_agent 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":"backend/routers/agents.py"},"region":{"startLine":168}}}],"partialFingerprints":{"codehealthFindingId/v1":"d00f158f6610d9f9d09667a6d462165e1eac4bfd0bbd307553149b743c08aeeb"}},{"ruleId":"D1","level":"warning","message":{"text":"eval._build_learning_dashboard (cyclomatic 20): eval._build_learning_dashboard 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":"backend/routers/eval.py"},"region":{"startLine":429}}}],"partialFingerprints":{"codehealthFindingId/v1":"982057182a28940ccce70953ad7aee1ada018b33e01bd1a4daffef3ab38918b4"}},{"ruleId":"D1","level":"warning","message":{"text":"tasks.create_task (cyclomatic 20): tasks.create_task 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":"backend/routers/tasks.py"},"region":{"startLine":66}}}],"partialFingerprints":{"codehealthFindingId/v1":"d1ee1a377f9b4c058e7b1a405cd2c64be9f8899bd3650214897d5d9918287f1a"}},{"ruleId":"D1","level":"warning","message":{"text":"artifact_cli._auto_validate_before_advance (cyclomatic 20): artifact_cli._auto_validate_before_advance 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":"backend/scripts/artifact_cli.py"},"region":{"startLine":827}}}],"partialFingerprints":{"codehealthFindingId/v1":"d82c18d21f5699a2130a9ec7f9f8743eb1e6fe73c542b9a6b6fbc33e5c1b7b0f"}},{"ruleId":"D1","level":"warning","message":{"text":"artifact_cli._stage_publish_times (cyclomatic 20): artifact_cli._stage_publish_times 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":"backend/scripts/artifact_cli.py"},"region":{"startLine":5027}}}],"partialFingerprints":{"codehealthFindingId/v1":"811644696814db602c7005e562e9dbe62ebff8701af950be136ac7a4c0955cef"}},{"ruleId":"D1","level":"warning","message":{"text":"eval_runner.eval_trajectory_capture (cyclomatic 20): eval_runner.eval_trajectory_capture has cyclomatic complexity 20 (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":"backend/scripts/eval_runner.py"},"region":{"startLine":1388}}}],"partialFingerprints":{"codehealthFindingId/v1":"6ba047b27efc79ee31f650e387fd7ea8ec2d231c1793bea4281c1bff413f0214"}},{"ruleId":"D1","level":"warning","message":{"text":"pipeline_analytics.generate_report (cyclomatic 20): pipeline_analytics.generate_report 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":"backend/scripts/pipeline_analytics.py"},"region":{"startLine":761}}}],"partialFingerprints":{"codehealthFindingId/v1":"248920cba6a1c8466dae92f192fc2a02f247c637b1c1aa42905598512e4ca756"}},{"ruleId":"D1","level":"warning","message":{"text":"BaseSchemaValidator.validate_all_relationship_ids (cyclomatic 20): BaseSchemaValidator.validate_all_relationship_ids 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":"backend/skills/s_docx/ooxml/scripts/validation/base.py"},"region":{"startLine":388}}}],"partialFingerprints":{"codehealthFindingId/v1":"3cb83f916e9415e567ee7fcc2c18c52d9631180b549bd071c5ab092b8d33b2a6"}},{"ruleId":"D1","level":"warning","message":{"text":"XMLEditor.get_node (cyclomatic 20): XMLEditor.get_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":"backend/skills/s_docx/scripts/utilities.py"},"region":{"startLine":76}}}],"partialFingerprints":{"codehealthFindingId/v1":"358f29f032fbefea7d4851c8b0d40ac3ce1f8d084103b5ffa9fe98af23079a46"}},{"ruleId":"D1","level":"warning","message":{"text":"generate_tts.main (cyclomatic 20): generate_tts.main 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":"backend/skills/s_pollinate/scripts/generate_tts.py"},"region":{"startLine":109}}}],"partialFingerprints":{"codehealthFindingId/v1":"5aca941c2d51455349fcece3e19a610d8cfa9b775857e2df5f479bc7fc6ae79d"}},{"ruleId":"D1","level":"warning","message":{"text":"publish_dashboard.generate_markdown (cyclomatic 20): publish_dashboard.generate_markdown 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":"backend/skills/s_pollinate/scripts/publish_dashboard.py"},"region":{"startLine":114}}}],"partialFingerprints":{"codehealthFindingId/v1":"49055850dc743411b2541e83dda96a16f247f859a8ca54fa5de8abb102fab6ca"}},{"ruleId":"D1","level":"warning","message":{"text":"BaseSchemaValidator.validate_unique_ids (cyclomatic 20): BaseSchemaValidator.validate_unique_ids 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":"backend/skills/s_pptx/ooxml/scripts/validation/base.py"},"region":{"startLine":186}}}],"partialFingerprints":{"codehealthFindingId/v1":"1bb81b99523ca3047ccb5f031bdad861af43323d20bbc5093120fd212e72a8fd"}},{"ruleId":"D1","level":"warning","message":{"text":"BaseSchemaValidator.validate_all_relationship_ids (cyclomatic 20): BaseSchemaValidator.validate_all_relationship_ids 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":"backend/skills/s_pptx/ooxml/scripts/validation/base.py"},"region":{"startLine":391}}}],"partialFingerprints":{"codehealthFindingId/v1":"c6d3b7281e73f94376cb6ff122784c2de00f4ba2d99eaf744ce5990bdf4b2151"}},{"ruleId":"D1","level":"warning","message":{"text":"ai_ready_helpers.check_domain_referential_integrity (cyclomatic 20): ai_ready_helpers.check_domain_referential_integrity 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":"backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py"},"region":{"startLine":250}}}],"partialFingerprints":{"codehealthFindingId/v1":"3ddc237e772785980b91a76ef678a09a483f2f398396fb9e2e1e4d15de39a21e"}},{"ruleId":"D1","level":"warning","message":{"text":"locked_write.locked_read_modify_write (cyclomatic 20): locked_write.locked_read_modify_write 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":"backend/templates/ddd-skills/s_ddd-persist/scripts/locked_write.py"},"region":{"startLine":515}}}],"partialFingerprints":{"codehealthFindingId/v1":"bdc2574419c9293a26ee1fb78211a1b7945e57453b3882820946e335c23dd9cd"}},{"ruleId":"D1","level":"warning","message":{"text":"ai_ready_helpers.check_domain_referential_integrity (cyclomatic 20): ai_ready_helpers.check_domain_referential_integrity 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":"backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py"},"region":{"startLine":249}}}],"partialFingerprints":{"codehealthFindingId/v1":"84945c76397059091a7b311f1790b4c35eeb32d47dafc0938c1d13b01d420df6"}},{"ruleId":"D1","level":"warning","message":{"text":"PipelineOverlay.RunDetailDrawer (cyclomatic 20): PipelineOverlay.RunDetailDrawer has cyclomatic complexity 20 (threshold 15). Of this number, 15 points are the body\u0027s own statements and 5 belong to 3 function literals inside it that branch. To reduce it, name the conditions: bind each compound test to a well-named local or a small predicate function, so the body reads as a sequence of named decisions rather than a chain of operators."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/layout/PipelineOverlay.tsx"},"region":{"startLine":447}}}],"partialFingerprints":{"codehealthFindingId/v1":"9acfae642e726627d0e23674bf99d380cdfda7db66d8aa7a7c6c02739620ea9c"}},{"ruleId":"D1","level":"warning","message":{"text":"DddCard.FullBody (cyclomatic 20): DddCard.FullBody has cyclomatic complexity 20 (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":"desktop/src/components/layout/DddCard.tsx"},"region":{"startLine":291}}}],"partialFingerprints":{"codehealthFindingId/v1":"ebde666634a3de6402b6d1555706ffe0ed605ce21d44638782be54913383bc1c"}},{"ruleId":"D1","level":"warning","message":{"text":"parser._extract_from_tree (cyclomatic 19): parser._extract_from_tree 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":"backend/core/code_intel/parser.py"},"region":{"startLine":997}}}],"partialFingerprints":{"codehealthFindingId/v1":"1e0fd0c81ab44751d2caa96cad556b570277dcb9d6d9ab33649d607e22244a74"}},{"ruleId":"D1","level":"warning","message":{"text":"daemon_guard._main (cyclomatic 19): daemon_guard._main 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":"backend/core/daemon_guard.py"},"region":{"startLine":413}}}],"partialFingerprints":{"codehealthFindingId/v1":"26eb1d58ca49a1ee45ea93a28b13a4c01b13dec5ea47515ab13d91ff5c44c109"}},{"ruleId":"D1","level":"warning","message":{"text":"ddd_bindings.describe_project_ddd_line (cyclomatic 19): ddd_bindings.describe_project_ddd_line 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":"backend/core/ddd_bindings.py"},"region":{"startLine":545}}}],"partialFingerprints":{"codehealthFindingId/v1":"e0bf0a62cf817c7d9074d810a75a7b4e5afd9e52f9efc730add4f3980375b566"}},{"ruleId":"D1","level":"warning","message":{"text":"closed_loop.audit_recurrence (cyclomatic 19): closed_loop.audit_recurrence has cyclomatic complexity 19 (threshold 15). To reduce it, name the conditions: bind each compound test to a well-named local or a small predicate function, so the body reads as a sequence of named decisions rather than a chain of operators."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/core/evolution/closed_loop.py"},"region":{"startLine":37}}}],"partialFingerprints":{"codehealthFindingId/v1":"0a66db2b33176437ac117d0fd205390e673c78456656bcc7a1cbd2dde9b0e3f4"}},{"ruleId":"D1","level":"warning","message":{"text":"library_mounts.index_docs_mount (cyclomatic 19): library_mounts.index_docs_mount 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":"backend/core/library_mounts.py"},"region":{"startLine":579}}}],"partialFingerprints":{"codehealthFindingId/v1":"57d76fde3a583e8bb245505c76d65d2f40784eb3659f09b1e0f233fe271fe2e8"}},{"ruleId":"D1","level":"warning","message":{"text":"mcp_config_loader.add_mcp_server_to_dict (cyclomatic 19): mcp_config_loader.add_mcp_server_to_dict 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":"backend/core/mcp_config_loader.py"},"region":{"startLine":303}}}],"partialFingerprints":{"codehealthFindingId/v1":"434542f12d4fd7f49f9d547db8458ba089329960a069afa1671f12ccf57248d1"}},{"ruleId":"D1","level":"warning","message":{"text":"proactive_intelligence._detect_temporal_signals (cyclomatic 19): proactive_intelligence._detect_temporal_signals 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":"backend/core/proactive_intelligence.py"},"region":{"startLine":461}}}],"partialFingerprints":{"codehealthFindingId/v1":"565e4f1f1fba2cae382c24754e52f130938251c6a26131dd2e12c278a1947f2b"}},{"ruleId":"D1","level":"warning","message":{"text":"proactive_intelligence._extract_working_items (cyclomatic 19): proactive_intelligence._extract_working_items 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":"backend/core/proactive_intelligence.py"},"region":{"startLine":1788}}}],"partialFingerprints":{"codehealthFindingId/v1":"9b3d60fff5054d5b66e5264c2adca11780e7ed36447e2c9e6101e7c41103ea6d"}},{"ruleId":"D1","level":"warning","message":{"text":"security_hooks._segment_is_history_rewrite (cyclomatic 19): security_hooks._segment_is_history_rewrite 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":"backend/core/security_hooks.py"},"region":{"startLine":669}}}],"partialFingerprints":{"codehealthFindingId/v1":"1596d20f67542696274af610882030592fe17808a72d34bff10118a783d87a41"}},{"ruleId":"D1","level":"warning","message":{"text":"SummarizationPipeline._extract_topics (cyclomatic 19): SummarizationPipeline._extract_topics 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":"backend/core/summarization.py"},"region":{"startLine":292}}}],"partialFingerprints":{"codehealthFindingId/v1":"67f2629e4b05f5f499599128e8c95a59b2811bf0114218fe02f3a283b3751d6b"}},{"ruleId":"D1","level":"warning","message":{"text":"SQLiteDatabase._migrate_existing_task_data (cyclomatic 19): SQLiteDatabase._migrate_existing_task_data 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":"backend/database/sqlite.py"},"region":{"startLine":3328}}}],"partialFingerprints":{"codehealthFindingId/v1":"650a09dd21030b425256d44b1389040ec9d78574b2129a7aed90fd20df6dcfe6"}},{"ruleId":"D1","level":"warning","message":{"text":"ContextHealthHook._refresh_code_intel (cyclomatic 19): ContextHealthHook._refresh_code_intel 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":"backend/hooks/context_health_hook.py"},"region":{"startLine":577}}}],"partialFingerprints":{"codehealthFindingId/v1":"fbe1454bff9da96623a1544a26211cf04e629a35fdfa60e3a6ae04716390abc3"}},{"ruleId":"D1","level":"warning","message":{"text":"EvolutionMaintenanceHook._check_promotion_threshold (cyclomatic 19): EvolutionMaintenanceHook._check_promotion_threshold 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":"backend/hooks/evolution_maintenance_hook.py"},"region":{"startLine":961}}}],"partialFingerprints":{"codehealthFindingId/v1":"21b0f5823bc938101769a061d0dba8fa6873a1cc7c0d091039228c86f6ce3241"}},{"ruleId":"D1","level":"warning","message":{"text":"migrate_skills.generate_manifest (cyclomatic 19): migrate_skills.generate_manifest 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":"backend/scripts/migrate_skills.py"},"region":{"startLine":235}}}],"partialFingerprints":{"codehealthFindingId/v1":"29d54735bac2fcf32d3351d0fdf49f5be88c5c9a9deaa56c2e3ab93545fd6b9a"}},{"ruleId":"D1","level":"warning","message":{"text":"pipeline_cleanup.reclassify_stale_runs (cyclomatic 19): pipeline_cleanup.reclassify_stale_runs 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":"backend/scripts/pipeline_cleanup.py"},"region":{"startLine":31}}}],"partialFingerprints":{"codehealthFindingId/v1":"7c76e0978c138d7154ac643a4b3e5ac411fe3ac30fc9de0e2f6fdc0f4d17ba64"}},{"ruleId":"D1","level":"warning","message":{"text":"pipeline_pr.create_pr (cyclomatic 19): pipeline_pr.create_pr 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":"backend/skills/s_autonomous-pipeline/scripts/pipeline_pr.py"},"region":{"startLine":240}}}],"partialFingerprints":{"codehealthFindingId/v1":"ea5f7c8327b18b215aff7340fe4c2e6ea28d4c40b2af35f7b952ee9ddb37001c"}},{"ruleId":"D1","level":"warning","message":{"text":"BaseSchemaValidator.validate_unique_ids (cyclomatic 19): BaseSchemaValidator.validate_unique_ids 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":"backend/skills/s_docx/ooxml/scripts/validation/base.py"},"region":{"startLine":186}}}],"partialFingerprints":{"codehealthFindingId/v1":"168f55d831d13919392c0931ee5f6b1471894e1caec5d8d68c322c2ee5470165"}},{"ruleId":"D1","level":"warning","message":{"text":"design_system.format_markdown (cyclomatic 19): design_system.format_markdown 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":"backend/skills/s_frontend-design/scripts/design_system.py"},"region":{"startLine":422}}}],"partialFingerprints":{"codehealthFindingId/v1":"d0044f4bcde201d466f4b5eb64cdc4b1ae99b83e8c201c41783fe0f6e67baeaa"}},{"ruleId":"D1","level":"warning","message":{"text":"font_link_backfill.main (cyclomatic 19): font_link_backfill.main 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":"backend/skills/s_pollinate/scripts/font_link_backfill.py"},"region":{"startLine":94}}}],"partialFingerprints":{"codehealthFindingId/v1":"ca7496e88a984a903a3875c45f2053481f4f41dea9ab7c9c73e36c2ddea3a270"}},{"ruleId":"D1","level":"warning","message":{"text":"todo_db._print_work_packet (cyclomatic 19): todo_db._print_work_packet 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":"backend/skills/s_radar-todo/scripts/todo_db.py"},"region":{"startLine":149}}}],"partialFingerprints":{"codehealthFindingId/v1":"cb18327d91696c91a46271408f768daae97f7017aa60cdbd9ee6e0f062433ab8"}},{"ruleId":"D1","level":"warning","message":{"text":"ai_ready_helpers._validate_v3_domain_layer (cyclomatic 19): ai_ready_helpers._validate_v3_domain_layer 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":"backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py"},"region":{"startLine":213}}}],"partialFingerprints":{"codehealthFindingId/v1":"3d4a6addf9dfebeda0e69fa98dbc046fe3e6e04ef404043762160c25bbc39ca2"}},{"ruleId":"D1","level":"warning","message":{"text":"ai_ready_helpers.incremental_update (cyclomatic 19): ai_ready_helpers.incremental_update 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":"backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py"},"region":{"startLine":2746}}}],"partialFingerprints":{"codehealthFindingId/v1":"70a4974878a00dbc46313c6f34f56bb0a02a58580f75d66072cd61e20dd0c52a"}},{"ruleId":"D1","level":"warning","message":{"text":"ai_ready_helpers.prioritized_file_list (cyclomatic 19): ai_ready_helpers.prioritized_file_list 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":"backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py"},"region":{"startLine":3173}}}],"partialFingerprints":{"codehealthFindingId/v1":"ebe7c18b72fbefb73b707b8529eca1d3777546181c05a8e478a88dfe38aff6d8"}},{"ruleId":"D1","level":"warning","message":{"text":"steeringify.group_and_propose (cyclomatic 19): steeringify.group_and_propose 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":"backend/skills/s_steeringify/steeringify.py"},"region":{"startLine":198}}}],"partialFingerprints":{"codehealthFindingId/v1":"9431183b6ee95fb6366b5beaed9bbe4ecb310b174193c92b5b2dbeae0d405a9a"}},{"ruleId":"D1","level":"warning","message":{"text":"ai_ready_helpers._validate_v3_domain_layer (cyclomatic 19): ai_ready_helpers._validate_v3_domain_layer 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":"backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py"},"region":{"startLine":212}}}],"partialFingerprints":{"codehealthFindingId/v1":"16d9314da27378b5787ed1c3a692e59e2eeb3dd2da0d6d1d22287a41e57e1863"}},{"ruleId":"D1","level":"warning","message":{"text":"ai_ready_helpers.incremental_update (cyclomatic 19): ai_ready_helpers.incremental_update 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":"backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py"},"region":{"startLine":2399}}}],"partialFingerprints":{"codehealthFindingId/v1":"b65f3db7aa4d782695f853a0f46f76da2fe021a6e4e3e0f56a5f7f89e45779ce"}},{"ruleId":"D1","level":"warning","message":{"text":"ai_ready_helpers.prioritized_file_list (cyclomatic 19): ai_ready_helpers.prioritized_file_list 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":"backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py"},"region":{"startLine":2826}}}],"partialFingerprints":{"codehealthFindingId/v1":"b28be2371f06e4cf09be8187cbfd00ab1c56f06fdf5edba0dd2ef04aad5568f5"}},{"ruleId":"D1","level":"warning","message":{"text":"daemon_guard._main (cyclomatic 19): daemon_guard._main 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":"desktop/resources/daemon/daemon_guard.py"},"region":{"startLine":413}}}],"partialFingerprints":{"codehealthFindingId/v1":"296a1b6973f10fe5c71803b9b5aef0b3610cebd3b0593c14276041420149ba4d"}},{"ruleId":"D1","level":"warning","message":{"text":"SectionLayouts.StepCard (cyclomatic 19): SectionLayouts.StepCard 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":"backend/skills/s_pollinate/templates/remotion/components/SectionLayouts.tsx"},"region":{"startLine":579}}}],"partialFingerprints":{"codehealthFindingId/v1":"1efc2eb2dde6d91cf004cbe6635c3d37f71b92dcc2752c9eb1a59b9954792433"}},{"ruleId":"D1","level":"warning","message":{"text":"api.parseApiError (cyclomatic 19): api.parseApiError has cyclomatic complexity 19 (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":"desktop/src/services/api.ts"},"region":{"startLine":49}}}],"partialFingerprints":{"codehealthFindingId/v1":"5a925d6a8df34db5ca9182b5a3b3024ed010e2d72a165b9764b6cc6ceea1b7a8"}},{"ruleId":"D1","level":"warning","message":{"text":"streaming-guards.forceClearStreamVerdict (cyclomatic 19): streaming-guards.forceClearStreamVerdict 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":"desktop/src/hooks/streaming-guards.ts"},"region":{"startLine":412}}}],"partialFingerprints":{"codehealthFindingId/v1":"3a790cb060a27bb830bf5fe27f3f19101bc4d462f361613837959bc464fa659a"}},{"ruleId":"D1","level":"warning","message":{"text":"CommunityOverlay.SourcesTab (cyclomatic 19): CommunityOverlay.SourcesTab has cyclomatic complexity 19 (threshold 15). Most of this is not in the body itself: 4 of the 19 points are its own statements and the rest belongs to 4 function literals inside it that branch (lines 423, 386, 391, \u2026). The decisions are inside those literals, which nothing outside this body can call, review or test on its own, so splitting the enclosing body is not the move available here. To reduce it, lift the literals\u0027 work into a named function or method at the enclosing scope and have each literal call it, then reduce whichever part then reads as the largest."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/layout/CommunityOverlay.tsx"},"region":{"startLine":374}}}],"partialFingerprints":{"codehealthFindingId/v1":"0b43ff49bce9ac69039beb89ee2190de2eb115f8e4445fbb24cbddde70dc11aa"}},{"ruleId":"D1","level":"warning","message":{"text":"ThreeColumnLayout.LeftSidebar (cyclomatic 19): ThreeColumnLayout.LeftSidebar has cyclomatic complexity 19 (threshold 15). Most of this is not in the body itself: 4 of the 19 points are its own statements and the rest belongs to 15 function literals inside it that branch (lines 224, 256, 257, \u2026). The decisions are inside those literals, which nothing outside this body can call, review or test on its own, so splitting the enclosing body is not the move available here. To reduce it, lift the literals\u0027 work into a named function or method at the enclosing scope and have each literal call it, then reduce whichever part then reads as the largest. This is NOT this file\u0027s highest cyclomatic complexity: ThreeColumnLayout.NavSvgIcon (cyclomatic 24) is higher and carries no row of its own \u2014 it was excluded as a flat dispatcher (a long switch/match over independent cases: many branches, almost no nesting), which this dimension does not treat as a refactor obligation. It is named here so the ranking you see in this file is not mistaken for the whole of it; the excluded method is counted neither in this dimension\u0027s figures nor in its score."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/layout/ThreeColumnLayout.tsx"},"region":{"startLine":177}}}],"partialFingerprints":{"codehealthFindingId/v1":"52663a7cca451db4e366b8d408f5d414f203584bab224df03554fa9e3363b435"}},{"ruleId":"D1","level":"warning","message":{"text":"useAudioPlayer.useAudioPlayer (cyclomatic 19): useAudioPlayer.useAudioPlayer has cyclomatic complexity 19 (threshold 15). Most of this is not in the body itself: 1 of the 19 points is its own statement and the rest belongs to 7 function literals inside it that branch (lines 91, 173, 43, \u2026). The decisions are inside those literals, which nothing outside this body can call, review or test on its own, so splitting the enclosing body is not the move available here. To reduce it, lift the literals\u0027 work into a named function or method at the enclosing scope and have each literal call it, then reduce whichever part then reads as the largest."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/hooks/useAudioPlayer.ts"},"region":{"startLine":31}}}],"partialFingerprints":{"codehealthFindingId/v1":"87418b994ba841daf17dcb73ec4486e03f00cbdc3a56e5cf4c87abbbe07916a6"}},{"ruleId":"D1","level":"warning","message":{"text":"SkillsPage.SkillsPage (cyclomatic 19): SkillsPage.SkillsPage has cyclomatic complexity 19 (threshold 15). Most of this is not in the body itself: 6 of the 19 points are its own statements and the rest belongs to 6 function literals inside it that branch (lines 205, 110, 122, \u2026). The decisions are inside those literals, which nothing outside this body can call, review or test on its own, so splitting the enclosing body is not the move available here. To reduce it, lift the literals\u0027 work into a named function or method at the enclosing scope and have each literal call it, then reduce whichever part then reads as the largest."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/pages/SkillsPage.tsx"},"region":{"startLine":77}}}],"partialFingerprints":{"codehealthFindingId/v1":"aca612aa528f5334a5ace18a8e35feaa160bf736b871a664b739748eaddc1f64"}},{"ruleId":"D1","level":"warning","message":{"text":"ChannelGateway._should_reply (cyclomatic 18): ChannelGateway._should_reply 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":"backend/channels/gateway.py"},"region":{"startLine":1164}}}],"partialFingerprints":{"codehealthFindingId/v1":"901846236f6e1b3e3393b979ae6086363ef8578c0b76876fbdbc4efc9dc85bc0"}},{"ruleId":"D1","level":"warning","message":{"text":"domain_rules.compute_domain_rules (cyclomatic 18): domain_rules.compute_domain_rules 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":"backend/core/code_intel/domain_rules.py"},"region":{"startLine":136}}}],"partialFingerprints":{"codehealthFindingId/v1":"b3a89d9e7b0c3ff6af200e78163ea4ba8a8d4de73417834500235e9b813aef7c"}},{"ruleId":"D1","level":"warning","message":{"text":"ddd_entry_lifecycle.assess_decay (cyclomatic 18): ddd_entry_lifecycle.assess_decay 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":"backend/core/ddd_entry_lifecycle.py"},"region":{"startLine":855}}}],"partialFingerprints":{"codehealthFindingId/v1":"c04e16253d52b60c05e70a4b1bec88ac4701e683788ca1b73b64bbc993626aca"}},{"ruleId":"D1","level":"warning","message":{"text":"ddd_entry_lifecycle._strip_entries (cyclomatic 18): ddd_entry_lifecycle._strip_entries 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":"backend/core/ddd_entry_lifecycle.py"},"region":{"startLine":1789}}}],"partialFingerprints":{"codehealthFindingId/v1":"a27bf3a127ff37d1d6af296ae041ac36957c658aa01e08d187d35dcff90ffcb3"}},{"ruleId":"D1","level":"warning","message":{"text":"LifecycleManager._check_streaming_timeout (cyclomatic 18): LifecycleManager._check_streaming_timeout 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":"backend/core/lifecycle_manager.py"},"region":{"startLine":653}}}],"partialFingerprints":{"codehealthFindingId/v1":"f9ba3743fcab67528c3e7b7c5e4301ea5e5ba6bd323e241937396c5b016ca1f1"}},{"ruleId":"D1","level":"warning","message":{"text":"PluginManager.sync_git_marketplace (cyclomatic 18): PluginManager.sync_git_marketplace 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":"backend/core/plugin_manager.py"},"region":{"startLine":118}}}],"partialFingerprints":{"codehealthFindingId/v1":"146fcb714bf18f00be6e93a2f5aab52bc2892ff4253f7439bed54f9b61dcd832"}},{"ruleId":"D1","level":"warning","message":{"text":"security_hooks._is_dangerous_rm (cyclomatic 18): security_hooks._is_dangerous_rm 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":"backend/core/security_hooks.py"},"region":{"startLine":99}}}],"partialFingerprints":{"codehealthFindingId/v1":"dd601fa0d23b86bce6bdd63438609eec3e1428d1839f74e61d7b3eab246611d7"}},{"ruleId":"D1","level":"warning","message":{"text":"SessionRouter._evict_idle (cyclomatic 18): SessionRouter._evict_idle 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":"backend/core/session_router.py"},"region":{"startLine":2431}}}],"partialFingerprints":{"codehealthFindingId/v1":"77b7b662803ee3064a455502ff079d408c597997b8b36a8793b99dbb8695716d"}},{"ruleId":"D1","level":"warning","message":{"text":"SkillManager._scan_tier (cyclomatic 18): SkillManager._scan_tier 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":"backend/core/skill_manager.py"},"region":{"startLine":576}}}],"partialFingerprints":{"codehealthFindingId/v1":"b88f8209299d036698d984b7dc18171c6e776ee7b23acaec0b4ab65a719eb199"}},{"ruleId":"D1","level":"warning","message":{"text":"ContextHealthHook._detect_stale_memory_claims (cyclomatic 18): ContextHealthHook._detect_stale_memory_claims 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":"backend/hooks/context_health_hook.py"},"region":{"startLine":2941}}}],"partialFingerprints":{"codehealthFindingId/v1":"390e47cd77463b547dac873ed6da7fadbbbc23977d1a2fd68736a522c5d4815a"}},{"ruleId":"D1","level":"warning","message":{"text":"data_point_folding._fold_one_family (cyclomatic 18): data_point_folding._fold_one_family 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":"backend/hooks/data_point_folding.py"},"region":{"startLine":201}}}],"partialFingerprints":{"codehealthFindingId/v1":"9dc3ca6593827fa85c0ef93000fdf1e2f15c74ab53bc9d7cd537c62fd6cea551"}},{"ruleId":"D1","level":"warning","message":{"text":"DistillationTriggerHook._extract_lessons (cyclomatic 18): DistillationTriggerHook._extract_lessons 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":"backend/hooks/distillation_hook.py"},"region":{"startLine":1161}}}],"partialFingerprints":{"codehealthFindingId/v1":"8dce72347b3cfcdfcf4ab36444dfa15fa7149ec460efab052458ac0933833d7e"}},{"ruleId":"D1","level":"warning","message":{"text":"swarmai_monthly_report._collect_pipeline_metrics (cyclomatic 18): swarmai_monthly_report._collect_pipeline_metrics 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":"backend/jobs/handlers/swarmai_monthly_report.py"},"region":{"startLine":153}}}],"partialFingerprints":{"codehealthFindingId/v1":"aa146412d94fe15ed13ff687b0b0d2bb0829c50393f80aa8e54e2505a6523b1a"}},{"ruleId":"D1","level":"warning","message":{"text":"pipelines.pipeline_run_detail (cyclomatic 18): pipelines.pipeline_run_detail 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":"backend/routers/pipelines.py"},"region":{"startLine":645}}}],"partialFingerprints":{"codehealthFindingId/v1":"cdcd9267b18a87e2efe06df90194e61fd7934cb1e4dfb8353ad3cba59006f1ff"}},{"ruleId":"D1","level":"warning","message":{"text":"artifact_cli.purge_garbage_runs (cyclomatic 18): artifact_cli.purge_garbage_runs 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":"backend/scripts/artifact_cli.py"},"region":{"startLine":1469}}}],"partialFingerprints":{"codehealthFindingId/v1":"433f50cf03c3061120f78f06e31e559f35cd6137d58f7c0e1b9cbcfcea845f44"}},{"ruleId":"D1","level":"warning","message":{"text":"completion_gate.completion_surface_verdict (cyclomatic 18): completion_gate.completion_surface_verdict has cyclomatic complexity 18 (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":"backend/scripts/completion_gate.py"},"region":{"startLine":59}}}],"partialFingerprints":{"codehealthFindingId/v1":"f727e596f96d0eaf18fd52d5ce49000a29d1f085f19b56277ebffbf98b9b5988"}},{"ruleId":"D1","level":"warning","message":{"text":"context_recall_cli.main (cyclomatic 18): context_recall_cli.main has cyclomatic complexity 18 (threshold 15). To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/scripts/context_recall_cli.py"},"region":{"startLine":52}}}],"partialFingerprints":{"codehealthFindingId/v1":"05f45baa8ac94b4501f1ebae6b4b5e7a184ac567e635fe2e21e48854afebaf5e"}},{"ruleId":"D1","level":"warning","message":{"text":"publish_dashboard.generate_html (cyclomatic 18): publish_dashboard.generate_html 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":"backend/skills/s_pollinate/scripts/publish_dashboard.py"},"region":{"startLine":194}}}],"partialFingerprints":{"codehealthFindingId/v1":"7b3e687d0fa59ff3eccb64c28757c59637c2c6a3e672f3feaa61ef7e78b3d36e"}},{"ruleId":"D1","level":"warning","message":{"text":"ai_ready_helpers.blind_spot_scan (cyclomatic 18): ai_ready_helpers.blind_spot_scan 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":"backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py"},"region":{"startLine":947}}}],"partialFingerprints":{"codehealthFindingId/v1":"25fb307d07bc00d3e1d623169b72d04c75d2d0d71147efb2eec32d637a71d1fc"}},{"ruleId":"D1","level":"warning","message":{"text":"ai_ready_helpers.eval_spec_details (cyclomatic 18): ai_ready_helpers.eval_spec_details has cyclomatic complexity 18 (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":"backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py"},"region":{"startLine":1374}}}],"partialFingerprints":{"codehealthFindingId/v1":"a6e43f0fde6716c9d5883bfb5e0e90d26a7eb0b002301897b5accfde9088f45f"}},{"ruleId":"D1","level":"warning","message":{"text":"ai_ready_helpers.score_equivalence (cyclomatic 18): ai_ready_helpers.score_equivalence 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":"backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py"},"region":{"startLine":1803}}}],"partialFingerprints":{"codehealthFindingId/v1":"f8c5de4f7c7fda7c34885e0d152f31ee8415d97462fed08714adcba2bcec52d4"}},{"ruleId":"D1","level":"warning","message":{"text":"ai_ready_helpers.generate_learning_tour (cyclomatic 18): ai_ready_helpers.generate_learning_tour 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":"backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py"},"region":{"startLine":2862}}}],"partialFingerprints":{"codehealthFindingId/v1":"a50816c23b97eb49c66f9360c013272061419f9d8682e30bcccaecd3bc2bc10b"}},{"ruleId":"D1","level":"warning","message":{"text":"ai_ready_helpers.run_multi_package (cyclomatic 18): ai_ready_helpers.run_multi_package 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":"backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py"},"region":{"startLine":2948}}}],"partialFingerprints":{"codehealthFindingId/v1":"70b615016330cc5020315b369119e5172ba4740c4cd32aea6bb7b42427445a9f"}},{"ruleId":"D1","level":"warning","message":{"text":"ai_ready_helpers.eval_spec_details (cyclomatic 18): ai_ready_helpers.eval_spec_details has cyclomatic complexity 18 (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":"backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py"},"region":{"startLine":1091}}}],"partialFingerprints":{"codehealthFindingId/v1":"de4f14b071c29e8cb01bbf194d2895f1bae2890f2d79ddaeeed3e92a68c22c0b"}},{"ruleId":"D1","level":"warning","message":{"text":"ai_ready_helpers.score_equivalence (cyclomatic 18): ai_ready_helpers.score_equivalence 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":"backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py"},"region":{"startLine":1467}}}],"partialFingerprints":{"codehealthFindingId/v1":"a8d20f10c5b865aad4ce653046d6cf34012fde969ee227af444111e33db9cc47"}},{"ruleId":"D1","level":"warning","message":{"text":"ai_ready_helpers.generate_learning_tour (cyclomatic 18): ai_ready_helpers.generate_learning_tour 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":"backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py"},"region":{"startLine":2515}}}],"partialFingerprints":{"codehealthFindingId/v1":"4c1177b114f0d3a3a477f32a50623a324ddbc7eb283ea771a682feb7bf530272"}},{"ruleId":"D1","level":"warning","message":{"text":"ai_ready_helpers.run_multi_package (cyclomatic 18): ai_ready_helpers.run_multi_package 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":"backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py"},"region":{"startLine":2601}}}],"partialFingerprints":{"codehealthFindingId/v1":"1d0305a1bff531d1b7d5d5b7314ec989bade0e47ef581d6b96340fc2327ae83e"}},{"ruleId":"D1","level":"warning","message":{"text":"MarkdownRenderer.MermaidDiagram (cyclomatic 18): MarkdownRenderer.MermaidDiagram has cyclomatic complexity 18 (threshold 15). Most of this is not in the body itself: 4 of the 18 points are its own statements and the rest belongs to 5 function literals inside it that branch (lines 316, 284, 247, \u2026). The decisions are inside those literals, which nothing outside this body can call, review or test on its own, so splitting the enclosing body is not the move available here. To reduce it, lift the literals\u0027 work into a named function or method at the enclosing scope and have each literal call it, then reduce whichever part then reads as the largest."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/common/MarkdownRenderer.tsx"},"region":{"startLine":238}}}],"partialFingerprints":{"codehealthFindingId/v1":"84b32a247d93fbdfb81bbdef42357009ddae4112c2ec6cba51568729d0791ad7"}},{"ruleId":"D1","level":"warning","message":{"text":"ErrorBoundary.ApiError (cyclomatic 18): ErrorBoundary.ApiError has cyclomatic complexity 18 (threshold 15). Most of this is not in the body itself: 8 of the 18 points are its own statements and the rest belongs to 2 function literals inside it that branch (lines 155, 165). The decisions are inside those literals, which nothing outside this body can call, review or test on its own, so splitting the enclosing body is not the move available here. To reduce it, lift the literals\u0027 work into a named function or method at the enclosing scope and have each literal call it, then reduce whichever part then reads as the largest."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/common/ErrorBoundary.tsx"},"region":{"startLine":154}}}],"partialFingerprints":{"codehealthFindingId/v1":"1b7ac7839348e83af7e0597adaf1a55a14bcab784b96ccabd8c003e2f12fc11a"}},{"ruleId":"D1","level":"warning","message":{"text":"chat.consumeSSEStream (cyclomatic 18): chat.consumeSSEStream 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":"desktop/src/services/chat.ts"},"region":{"startLine":267}}}],"partialFingerprints":{"codehealthFindingId/v1":"d95b4cbb078c5e507101683fbc2ddddcafbd48f01517c58cc43b31d4b48ad34d"}},{"ruleId":"D1","level":"warning","message":{"text":"uiCommands.dispatchUiCommand (cyclomatic 18): uiCommands.dispatchUiCommand 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":"desktop/src/utils/uiCommands.ts"},"region":{"startLine":99}}}],"partialFingerprints":{"codehealthFindingId/v1":"a996484e4eac9c5c027fcb1a1f5e54f1643966e776b0c8589e1a8533e2d3da49"}},{"ruleId":"D1","level":"warning","message":{"text":"HistoryOverlay.HistoryContent (cyclomatic 18): HistoryOverlay.HistoryContent has cyclomatic complexity 18 (threshold 15). Most of this is not in the body itself: 4 of the 18 points are its own statements and the rest belongs to 7 function literals inside it that branch (lines 91, 117, 138, \u2026). The decisions are inside those literals, which nothing outside this body can call, review or test on its own, so splitting the enclosing body is not the move available here. To reduce it, lift the literals\u0027 work into a named function or method at the enclosing scope and have each literal call it, then reduce whichever part then reads as the largest."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/layout/HistoryOverlay.tsx"},"region":{"startLine":59}}}],"partialFingerprints":{"codehealthFindingId/v1":"d003eecd781901adba254e4d7d32cdea2e4e6d528c33b304865deeb3185cc40e"}},{"ruleId":"D1","level":"warning","message":{"text":"JobsRunsOverlay.JobsRunsContent (cyclomatic 18): JobsRunsOverlay.JobsRunsContent has cyclomatic complexity 18 (threshold 15). Most of this is not in the body itself: 6 of the 18 points are its own statements and the rest belongs to 6 function literals inside it that branch (lines 74, 93, 145, \u2026). The decisions are inside those literals, which nothing outside this body can call, review or test on its own, so splitting the enclosing body is not the move available here. To reduce it, lift the literals\u0027 work into a named function or method at the enclosing scope and have each literal call it, then reduce whichever part then reads as the largest."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/layout/JobsRunsOverlay.tsx"},"region":{"startLine":59}}}],"partialFingerprints":{"codehealthFindingId/v1":"269e852e1db0c0399ac6d56e201dc45fd7c384433331eab99da004c07dff96a8"}},{"ruleId":"D1","level":"warning","message":{"text":"JobsRunsOverlay.JobDetailDrawer (cyclomatic 18): JobsRunsOverlay.JobDetailDrawer has cyclomatic complexity 18 (threshold 15). Of this number, 14 points are the body\u0027s own statements and 4 belong to 4 function literals inside it that branch. 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":"desktop/src/components/layout/JobsRunsOverlay.tsx"},"region":{"startLine":316}}}],"partialFingerprints":{"codehealthFindingId/v1":"6c1bdfed127965354911d9f48897b39fff3c21f6bb04a5b1823f9e1bd3f6c5fc"}},{"ruleId":"D1","level":"warning","message":{"text":"TerminalPanel.TerminalPanel (cyclomatic 18): TerminalPanel.TerminalPanel has cyclomatic complexity 18 (threshold 15). Most of this is not in the body itself: 7 of the 18 points are its own statements and the rest belongs to 7 function literals inside it that branch (lines 57, 70, 123, \u2026). The decisions are inside those literals, which nothing outside this body can call, review or test on its own, so splitting the enclosing body is not the move available here. To reduce it, lift the literals\u0027 work into a named function or method at the enclosing scope and have each literal call it, then reduce whichever part then reads as the largest."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/terminal/TerminalPanel.tsx"},"region":{"startLine":23}}}],"partialFingerprints":{"codehealthFindingId/v1":"9ef1825b544fdb387a8e4f1ceb0cdf334c63748e37d7aa62098156be50cb6d27"}},{"ruleId":"D1","level":"warning","message":{"text":"useReviewMode.useReviewMode (cyclomatic 18): useReviewMode.useReviewMode has cyclomatic complexity 18 (threshold 15). Most of this is not in the body itself: 1 of the 18 points is its own statement and the rest belongs to 8 function literals inside it that branch (lines 170, 163, 83, \u2026). The decisions are inside those literals, which nothing outside this body can call, review or test on its own, so splitting the enclosing body is not the move available here. To reduce it, lift the literals\u0027 work into a named function or method at the enclosing scope and have each literal call it, then reduce whichever part then reads as the largest."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/hooks/useReviewMode.ts"},"region":{"startLine":75}}}],"partialFingerprints":{"codehealthFindingId/v1":"871bcd8864bd71bc39aef56db16fec912aae2c4a5d4696ddda8818420373e3f9"}},{"ruleId":"D1","level":"warning","message":{"text":"CommentPopover.CommentPopover (cyclomatic 18): CommentPopover.CommentPopover has cyclomatic complexity 18 (threshold 15). Most of this is not in the body itself: 5 of the 18 points are its own statements and the rest belongs to 6 function literals inside it that branch (lines 96, 52, 77, \u2026). The decisions are inside those literals, which nothing outside this body can call, review or test on its own, so splitting the enclosing body is not the move available here. To reduce it, lift the literals\u0027 work into a named function or method at the enclosing scope and have each literal call it, then reduce whichever part then reads as the largest."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/common/CommentPopover.tsx"},"region":{"startLine":34}}}],"partialFingerprints":{"codehealthFindingId/v1":"3f13cd312a7469219e902e37a237a09217546e75e312b7d248fd63504938cf49"}},{"ruleId":"D1","level":"warning","message":{"text":"CanvasOutputRail.OutputRow (cyclomatic 18): CanvasOutputRail.OutputRow has cyclomatic complexity 18 (threshold 15). Of this number, 16 points are the body\u0027s own statements and 2 belong to 2 function literals inside it that branch. 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":"desktop/src/components/file-viewer/CanvasOutputRail.tsx"},"region":{"startLine":109}}}],"partialFingerprints":{"codehealthFindingId/v1":"6afb7adefef1b957785ee04c68cdb8341cfb6c3c5f1127dc2de1278b13015496"}},{"ruleId":"D1","level":"warning","message":{"text":"sentenceSplitter.extractSentences (cyclomatic 18): sentenceSplitter.extractSentences 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":"desktop/src/utils/sentenceSplitter.ts"},"region":{"startLine":127}}}],"partialFingerprints":{"codehealthFindingId/v1":"80af88190b4256561b563db7578be7873f5feec9424757a02adbafb87da754e4"}},{"ruleId":"D1","level":"warning","message":{"text":"SessionTabBar.SessionTabBar (cyclomatic 18): SessionTabBar.SessionTabBar has cyclomatic complexity 18 (threshold 15). Most of this is not in the body itself: 6 of the 18 points are its own statements and the rest belongs to 4 function literals inside it that branch (lines 69, 40, 48, \u2026). The decisions are inside those literals, which nothing outside this body can call, review or test on its own, so splitting the enclosing body is not the move available here. To reduce it, lift the literals\u0027 work into a named function or method at the enclosing scope and have each literal call it, then reduce whichever part then reads as the largest."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/pages/chat/components/SessionTabBar.tsx"},"region":{"startLine":27}}}],"partialFingerprints":{"codehealthFindingId/v1":"7ed0a418ebe413d3a22885f7a610b6d40bf8f3490391ce3b6085bbfecd864c70"}},{"ruleId":"D1","level":"warning","message":{"text":"AttachedFileChips.AttachedFileChips (cyclomatic 18): AttachedFileChips.AttachedFileChips has cyclomatic complexity 18 (threshold 15). Most of this is not in the body itself: 3 of the 18 points are its own statements and the rest belongs to 6 function literals inside it that branch (lines 184, 197, 220, \u2026). The decisions are inside those literals, which nothing outside this body can call, review or test on its own, so splitting the enclosing body is not the move available here. To reduce it, lift the literals\u0027 work into a named function or method at the enclosing scope and have each literal call it, then reduce whichever part then reads as the largest."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/chat/AttachedFileChips.tsx"},"region":{"startLine":174}}}],"partialFingerprints":{"codehealthFindingId/v1":"3471ff943da676afc2c7bf25d182bf708ea4d1fe22a941bddd44008f29e7fe83"}},{"ruleId":"D1","level":"warning","message":{"text":"SlackChannelAdapter._normalize_event (cyclomatic 17): SlackChannelAdapter._normalize_event 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":"backend/channels/adapters/slack.py"},"region":{"startLine":586}}}],"partialFingerprints":{"codehealthFindingId/v1":"8c9e397deec8ed93e318790b82b6be2fafa49384797c77eaa1b3c36031997211"}},{"ruleId":"D1","level":"warning","message":{"text":"dead_code._is_entry_point (cyclomatic 17): dead_code._is_entry_point 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":"backend/core/code_intel/dead_code.py"},"region":{"startLine":59}}}],"partialFingerprints":{"codehealthFindingId/v1":"4b87576c00daf1322cb4af10f9390f96e9cc4539d7e7d9c885096947668b4853"}},{"ruleId":"D1","level":"warning","message":{"text":"freshness.detect_spec_details_staleness (cyclomatic 17): freshness.detect_spec_details_staleness 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":"backend/core/code_intel/freshness.py"},"region":{"startLine":224}}}],"partialFingerprints":{"codehealthFindingId/v1":"069b39adf32b6b81abfa6b53501340451f6092d467bf506014a3967d9ac7f93f"}},{"ruleId":"D1","level":"warning","message":{"text":"ddd_cultivation.backfill_proposals (cyclomatic 17): ddd_cultivation.backfill_proposals 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":"backend/core/ddd_cultivation.py"},"region":{"startLine":2196}}}],"partialFingerprints":{"codehealthFindingId/v1":"c700c47d8a91826b8e86951260baca8d8d17612c8cd12a44cda390ebfd685ece"}},{"ruleId":"D1","level":"warning","message":{"text":"escalation_ladder.decide_escalation (cyclomatic 17): escalation_ladder.decide_escalation 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":"backend/core/evolution/escalation_ladder.py"},"region":{"startLine":75}}}],"partialFingerprints":{"codehealthFindingId/v1":"8850383589b3627cbd0a05f1e90dcf0fcc11c94be1376050fbd404594a87ad54"}},{"ruleId":"D1","level":"warning","message":{"text":"file_change_classifier.parse_bash_write_targets (cyclomatic 17): file_change_classifier.parse_bash_write_targets 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":"backend/core/file_change_classifier.py"},"region":{"startLine":73}}}],"partialFingerprints":{"codehealthFindingId/v1":"40b14ffb3c225d127802fb3dda0ca1114e66e763ce8ae8a094e54d331516ccf0"}},{"ruleId":"D1","level":"warning","message":{"text":"needs_human_review.needs_human_review_batch (cyclomatic 17): needs_human_review.needs_human_review_batch 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":"backend/core/needs_human_review.py"},"region":{"startLine":369}}}],"partialFingerprints":{"codehealthFindingId/v1":"aac4bf71f3ba65bf453d363554e96f96b0d6efe604f0dc6d32559eca41cfce1d"}},{"ruleId":"D1","level":"warning","message":{"text":"proactive_intelligence._get_signal_highlights (cyclomatic 17): proactive_intelligence._get_signal_highlights 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":"backend/core/proactive_intelligence.py"},"region":{"startLine":556}}}],"partialFingerprints":{"codehealthFindingId/v1":"20e8340b939588acc6b57aa6a57db7ea28ae52aa8a55622d1e0affe7251a7eb6"}},{"ruleId":"D1","level":"warning","message":{"text":"ProposalFeedbackTracker.compute_channel_stats (cyclomatic 17): ProposalFeedbackTracker.compute_channel_stats 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":"backend/core/proposal_feedback.py"},"region":{"startLine":158}}}],"partialFingerprints":{"codehealthFindingId/v1":"d0c158156f04ca47773c0dfb70db5686981e7e5b5f217c3fce580a86f0eae220"}},{"ruleId":"D1","level":"warning","message":{"text":"session_registry.kill_all_claude_processes (cyclomatic 17): session_registry.kill_all_claude_processes has cyclomatic complexity 17 (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":"backend/core/session_registry.py"},"region":{"startLine":175}}}],"partialFingerprints":{"codehealthFindingId/v1":"b0258e5d3d5405b5ba7ed4a74b5cd5aaf2fe924cf07c61377cd3294ad664c55c"}},{"ruleId":"D1","level":"warning","message":{"text":"SessionRouter.drain_pending (cyclomatic 17): SessionRouter.drain_pending 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":"backend/core/session_router.py"},"region":{"startLine":2678}}}],"partialFingerprints":{"codehealthFindingId/v1":"b929fb8ae867321eb146f5f44ddaf91ed4b7e2f4cffa9e9d327e872b325e88cc"}},{"ruleId":"D1","level":"warning","message":{"text":"SessionUnit._pid_watchdog_loop (cyclomatic 17): SessionUnit._pid_watchdog_loop 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":"backend/core/session_unit.py"},"region":{"startLine":1288}}}],"partialFingerprints":{"codehealthFindingId/v1":"5e55f251f3afb0304645c16f38fc881eb53ed8e9cc95965ed9cfee6ee95423cc"}},{"ruleId":"D1","level":"warning","message":{"text":"SwarmWorkspaceManager._seed_hive_from_package (cyclomatic 17): SwarmWorkspaceManager._seed_hive_from_package 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":"backend/core/swarm_workspace_manager.py"},"region":{"startLine":1243}}}],"partialFingerprints":{"codehealthFindingId/v1":"4083c9124ebf930ec732e3c5ca7ee1328bba9d2e8d967d9540d03ae21b73ebb4"}},{"ruleId":"D1","level":"warning","message":{"text":"DistillationTriggerHook._verify_claim_against_git (cyclomatic 17): DistillationTriggerHook._verify_claim_against_git has cyclomatic complexity 17 (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":"backend/hooks/distillation_hook.py"},"region":{"startLine":1493}}}],"partialFingerprints":{"codehealthFindingId/v1":"bf55346fc40c2043eff96c6190531c2fdaddc4b888d0b41fe15991dc488d2e49"}},{"ruleId":"D1","level":"warning","message":{"text":"DistillationTriggerHook._apply_deliverable_reconciliation (cyclomatic 17): DistillationTriggerHook._apply_deliverable_reconciliation 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":"backend/hooks/distillation_hook.py"},"region":{"startLine":2117}}}],"partialFingerprints":{"codehealthFindingId/v1":"dbe1eb0c81f5b455f08d35d66a78ed95aa004c1bfe68793d867a997c297c01b9"}},{"ruleId":"D1","level":"warning","message":{"text":"EvolutionMaintenanceHook._size_evict_locked (cyclomatic 17): EvolutionMaintenanceHook._size_evict_locked 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":"backend/hooks/evolution_maintenance_hook.py"},"region":{"startLine":793}}}],"partialFingerprints":{"codehealthFindingId/v1":"e7a30764cf856c57da2082a72e7bcc5a9a507603fc7c0229090e1b675c6b821a"}},{"ruleId":"D1","level":"warning","message":{"text":"github_trending.fetch_github_trending (cyclomatic 17): github_trending.fetch_github_trending 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":"backend/jobs/adapters/github_trending.py"},"region":{"startLine":47}}}],"partialFingerprints":{"codehealthFindingId/v1":"693c7c176310a7d487bd9897c70c891691586fcafc5ad9d0c3fac90e749240e2"}},{"ruleId":"D1","level":"warning","message":{"text":"bedrock._resolve_credentials (cyclomatic 17): bedrock._resolve_credentials 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":"backend/jobs/bedrock.py"},"region":{"startLine":62}}}],"partialFingerprints":{"codehealthFindingId/v1":"a67ab5cf92a74d0f16142f78f2f3f6eac35faf3a4b8e5a7dfb567d0cc74e73c7"}},{"ruleId":"D1","level":"warning","message":{"text":"swarmai_monthly_report._collect_prior_month_metrics (cyclomatic 17): swarmai_monthly_report._collect_prior_month_metrics 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":"backend/jobs/handlers/swarmai_monthly_report.py"},"region":{"startLine":480}}}],"partialFingerprints":{"codehealthFindingId/v1":"4e1f40a7633b8e3b568c88e6db1ad4ddd1f88ddc219dbf8ac78b80c5f25a9baa"}},{"ruleId":"D1","level":"warning","message":{"text":"pollinate._build_card (cyclomatic 17): pollinate._build_card 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":"backend/routers/pollinate.py"},"region":{"startLine":490}}}],"partialFingerprints":{"codehealthFindingId/v1":"87792d4271191c95a4284f1648d9b6eaca943d832cd8643480e26093b88ad090"}},{"ruleId":"D1","level":"warning","message":{"text":"system._probe_ada_details (cyclomatic 17): system._probe_ada_details 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":"backend/routers/system.py"},"region":{"startLine":751}}}],"partialFingerprints":{"codehealthFindingId/v1":"0f9c97bfa110a1395cad745256a4585a92d2508b20881516c3178c21c5493f55"}},{"ruleId":"D1","level":"warning","message":{"text":"artifact_cli._next_stage_continuation (cyclomatic 17): artifact_cli._next_stage_continuation 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":"backend/scripts/artifact_cli.py"},"region":{"startLine":617}}}],"partialFingerprints":{"codehealthFindingId/v1":"bac565e0d0cc30b14509b87035cbd09bd019eeee79e1bab88e83f4e70cab4bdd"}},{"ruleId":"D1","level":"warning","message":{"text":"artifact_cli._lookup_already_committed (cyclomatic 17): artifact_cli._lookup_already_committed 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":"backend/scripts/artifact_cli.py"},"region":{"startLine":2852}}}],"partialFingerprints":{"codehealthFindingId/v1":"14d1024f761b854de1366f7c6836f48900086bfe3cc47946955e2531e3a91127"}},{"ruleId":"D1","level":"warning","message":{"text":"migrate_memory_lifecycle.migrate_file (cyclomatic 17): migrate_memory_lifecycle.migrate_file 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":"backend/scripts/migrate_memory_lifecycle.py"},"region":{"startLine":95}}}],"partialFingerprints":{"codehealthFindingId/v1":"19e625e06ac4405413ac1bc68b60de3b84b73c4833fa3a3a80cb9c360434c9a3"}},{"ruleId":"D1","level":"warning","message":{"text":"migrate_skills.migrate_skill (cyclomatic 17): migrate_skills.migrate_skill 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":"backend/scripts/migrate_skills.py"},"region":{"startLine":400}}}],"partialFingerprints":{"codehealthFindingId/v1":"172078d7a3a570f9a985446291e4f71a2e5d42654763c0ecbdab17c853ced364"}},{"ruleId":"D1","level":"warning","message":{"text":"scan.main (cyclomatic 17): scan.main 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":"backend/skills/s_context-hygiene/scripts/scan.py"},"region":{"startLine":201}}}],"partialFingerprints":{"codehealthFindingId/v1":"50cbdbc703f9180605c3d9735632911c6562aacad7f9bc19b141c4d7e8bf138c"}},{"ruleId":"D1","level":"warning","message":{"text":"distribute.main (cyclomatic 17): distribute.main 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":"backend/skills/s_ddd-distribute/scripts/distribute.py"},"region":{"startLine":57}}}],"partialFingerprints":{"codehealthFindingId/v1":"f1fb47a0e8209e7b36815087b0495428591da01e3cb54967f57478fb49227e53"}},{"ruleId":"D1","level":"warning","message":{"text":"format_recommend.recommend (cyclomatic 17): format_recommend.recommend 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":"backend/skills/s_pollinate/scripts/format_recommend.py"},"region":{"startLine":158}}}],"partialFingerprints":{"codehealthFindingId/v1":"f11dcf50e2dfc14cbae151730e04ef534e8e4976df5c4fd40c8eb4ed6a46724d"}},{"ruleId":"D1","level":"warning","message":{"text":"publish_meta.generate_publish_info (cyclomatic 17): publish_meta.generate_publish_info 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":"backend/skills/s_pollinate/scripts/publish_meta.py"},"region":{"startLine":143}}}],"partialFingerprints":{"codehealthFindingId/v1":"70afaeed440cd4841db2c9f9b8c10a6bd41695c59ccd013c53029d8d879d8c67"}},{"ruleId":"D1","level":"warning","message":{"text":"style-extract.extract_fonts (cyclomatic 17): style-extract.extract_fonts 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":"backend/skills/s_pptx/scripts/style-extract.py"},"region":{"startLine":53}}}],"partialFingerprints":{"codehealthFindingId/v1":"0464ff57d2a5f678d927e62fc4fd05a5eefd4593cf7f23cbae4b198e0383fc6e"}},{"ruleId":"D1","level":"warning","message":{"text":"ai_ready_helpers.check_anchor_accounting (cyclomatic 17): ai_ready_helpers.check_anchor_accounting 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":"backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py"},"region":{"startLine":773}}}],"partialFingerprints":{"codehealthFindingId/v1":"8896bdb16fb4e4803e71b2bd719a30dd1baa6ec0008bcb9efd1a075f54a9a74c"}},{"ruleId":"D1","level":"warning","message":{"text":"ai_ready_helpers.check_anchor_accounting (cyclomatic 17): ai_ready_helpers.check_anchor_accounting 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":"backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py"},"region":{"startLine":687}}}],"partialFingerprints":{"codehealthFindingId/v1":"0392a9f51e4a2c6f07e78789924f46a8584d3f6bb4a3ecb7a857f477f703741f"}},{"ruleId":"D1","level":"warning","message":{"text":"swarmai::sync_daemon_version (cyclomatic 17): swarmai::sync_daemon_version 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":"desktop/src-tauri/src/lib.rs"},"region":{"startLine":1130}}}],"partialFingerprints":{"codehealthFindingId/v1":"df38a7be2edbdce054c7fcd4cbba1281a943bd33fed05f38694276f3836e3eae"}},{"ruleId":"D1","level":"warning","message":{"text":"SettingsTabs.SettingsTabs (cyclomatic 17): SettingsTabs.SettingsTabs has cyclomatic complexity 17 (threshold 15). Most of this is not in the body itself: 1 of the 17 points is its own statement and the rest belongs to 5 function literals inside it that branch (lines 103, 63, 72, \u2026). The decisions are inside those literals, which nothing outside this body can call, review or test on its own, so splitting the enclosing body is not the move available here. To reduce it, lift the literals\u0027 work into a named function or method at the enclosing scope and have each literal call it, then reduce whichever part then reads as the largest."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/settings/SettingsTabs.tsx"},"region":{"startLine":58}}}],"partialFingerprints":{"codehealthFindingId/v1":"54eac800cd3422ea92b919e51caf2f82f659bce8780b55047eea99f7b695244c"}},{"ruleId":"D1","level":"warning","message":{"text":"EvalDashboard.ContextHealthTab (cyclomatic 17): EvalDashboard.ContextHealthTab has cyclomatic complexity 17 (threshold 15). Of this number, 16 points are the body\u0027s own statements and 1 belongs to one function literal inside it that branches. To reduce it, name the conditions: bind each compound test to a well-named local or a small predicate function, so the body reads as a sequence of named decisions rather than a chain of operators."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/pages/EvalDashboard.tsx"},"region":{"startLine":1084}}}],"partialFingerprints":{"codehealthFindingId/v1":"60a504eb66eb8f478f323143a8ef97988bbbd7ea35f1e408bb728ce7cab931fb"}},{"ruleId":"D1","level":"warning","message":{"text":"EvolutionMessage.EvolutionMessage (cyclomatic 17): EvolutionMessage.EvolutionMessage has cyclomatic complexity 17 (threshold 15). Of this number, 15 points are the body\u0027s own statements and 2 belong to 2 function literals inside it that branch. 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":"desktop/src/components/chat/EvolutionMessage.tsx"},"region":{"startLine":82}}}],"partialFingerprints":{"codehealthFindingId/v1":"1afa6b1c5547de5af70de8e86ecca9bf5b7d7e4f3afe32f70f5f377a00f50f14"}},{"ruleId":"D1","level":"warning","message":{"text":"attention_authority._collect_governance (cyclomatic 16): attention_authority._collect_governance 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":"backend/core/attention_authority.py"},"region":{"startLine":195}}}],"partialFingerprints":{"codehealthFindingId/v1":"fcf3c2dc7d0adb66e45452936af306b4d2d03ad24d10fd487b2dfdc4984b495c"}},{"ruleId":"D1","level":"warning","message":{"text":"BackupManager._restore_impl (cyclomatic 16): BackupManager._restore_impl 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":"backend/core/backup_manager.py"},"region":{"startLine":471}}}],"partialFingerprints":{"codehealthFindingId/v1":"27b609da6e13feb8001f5480fc14db2fcb511a3bfb94c15e4e4c023a67022f49"}},{"ruleId":"D1","level":"warning","message":{"text":"claude_environment._configure_claude_environment (cyclomatic 16): claude_environment._configure_claude_environment 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":"backend/core/claude_environment.py"},"region":{"startLine":184}}}],"partialFingerprints":{"codehealthFindingId/v1":"fe347ba482375834a3ee04c3d2388d187a2ecdef2240ffa10e2e3f28715415c3"}},{"ruleId":"D1","level":"warning","message":{"text":"community_data.build_feed (cyclomatic 16): community_data.build_feed 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":"backend/core/community_data.py"},"region":{"startLine":564}}}],"partialFingerprints":{"codehealthFindingId/v1":"051a1a57464b3428352a44455f4dfc9d09dec8dcbec9c801be5d22032e327693"}},{"ruleId":"D1","level":"warning","message":{"text":"CompactionGuard.check (cyclomatic 16): CompactionGuard.check 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":"backend/core/compaction_guard.py"},"region":{"startLine":609}}}],"partialFingerprints":{"codehealthFindingId/v1":"abd9cc2524456bfd8dbea3bcb4ab1cc391fc72bc710d9af2d379d38d65cf17f9"}},{"ruleId":"D1","level":"warning","message":{"text":"ContextDirectoryLoader._assemble_from_sources (cyclomatic 16): ContextDirectoryLoader._assemble_from_sources 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":"backend/core/context_directory_loader.py"},"region":{"startLine":869}}}],"partialFingerprints":{"codehealthFindingId/v1":"9f2650e2e1baecc1f6be45aa232ed472dc9beb3bedc40ba568729da199d87f27"}},{"ruleId":"D1","level":"warning","message":{"text":"ddd_cultivation._locate_target_entry (cyclomatic 16): ddd_cultivation._locate_target_entry 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":"backend/core/ddd_cultivation.py"},"region":{"startLine":1546}}}],"partialFingerprints":{"codehealthFindingId/v1":"7af542928c13554cd72ed920d0e0d1051040cbe486d07569d2b99edf83e56394"}},{"ruleId":"D1","level":"warning","message":{"text":"ddd_cultivation.apply_retire_proposal (cyclomatic 16): ddd_cultivation.apply_retire_proposal 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":"backend/core/ddd_cultivation.py"},"region":{"startLine":1678}}}],"partialFingerprints":{"codehealthFindingId/v1":"1558fff3085c52a8752ec67463ff2f6f471199825fb6b253809b676ec98aaae1"}},{"ruleId":"D1","level":"warning","message":{"text":"ddd_entry_lifecycle.reclaim_duplicate_entries (cyclomatic 16): ddd_entry_lifecycle.reclaim_duplicate_entries 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":"backend/core/ddd_entry_lifecycle.py"},"region":{"startLine":1509}}}],"partialFingerprints":{"codehealthFindingId/v1":"f984caeff7badc1031b69aeed4fdbaab71125d1c757976eadeb25cbeeb01dae3"}},{"ruleId":"D1","level":"warning","message":{"text":"ddd_packager.emit_target_aim (cyclomatic 16): ddd_packager.emit_target_aim 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":"backend/core/ddd_packager.py"},"region":{"startLine":1500}}}],"partialFingerprints":{"codehealthFindingId/v1":"108d820749b52ba41eaaa2511c74bf08db0d71e57a7f96b70efd24ecf6910560"}},{"ruleId":"D1","level":"warning","message":{"text":"EvolutionOptimizer._is_quality_correction (cyclomatic 16): EvolutionOptimizer._is_quality_correction 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":"backend/core/evolution_optimizer.py"},"region":{"startLine":687}}}],"partialFingerprints":{"codehealthFindingId/v1":"122fbc47dfffd266d6750c308c668e9e73cf84331e080227831eaab1b945e839"}},{"ruleId":"D1","level":"warning","message":{"text":"knowledge_store.chunk_markdown (cyclomatic 16): knowledge_store.chunk_markdown 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":"backend/core/knowledge_store.py"},"region":{"startLine":67}}}],"partialFingerprints":{"codehealthFindingId/v1":"5fea81bb985b89b1f383328e63dc167add3cc207a3a7668d8f519f7e46ea9ad4"}},{"ruleId":"D1","level":"warning","message":{"text":"LifecycleManager._scan_unprocessed_sessions (cyclomatic 16): LifecycleManager._scan_unprocessed_sessions 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":"backend/core/lifecycle_manager.py"},"region":{"startLine":1642}}}],"partialFingerprints":{"codehealthFindingId/v1":"659c77353247c931a397f828f7509c132edc724ba5d952d1a79855185b61fc98"}},{"ruleId":"D1","level":"warning","message":{"text":"LifecycleManager._get_mcp_server_patterns (cyclomatic 16): LifecycleManager._get_mcp_server_patterns 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":"backend/core/lifecycle_manager.py"},"region":{"startLine":1901}}}],"partialFingerprints":{"codehealthFindingId/v1":"8f52899c3bb72842d323452e06e9d10610a8caf4b5d2d0b4dfa52a8d314f80e2"}},{"ruleId":"D1","level":"warning","message":{"text":"ManifestLoader.ensure_dependencies (cyclomatic 16): ManifestLoader.ensure_dependencies 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":"backend/core/manifest_loader.py"},"region":{"startLine":161}}}],"partialFingerprints":{"codehealthFindingId/v1":"1fc0e08600b4ec4298a0fb40f2d737b29c8b104e09342ba24d306f8a16219910"}},{"ruleId":"D1","level":"warning","message":{"text":"proactive_intelligence._extract_jobs_summary (cyclomatic 16): proactive_intelligence._extract_jobs_summary has cyclomatic complexity 16 (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":"backend/core/proactive_intelligence.py"},"region":{"startLine":1703}}}],"partialFingerprints":{"codehealthFindingId/v1":"69c36c17930806b11ea404d4b1a96233c7815cab1ca661a27f9ced58433734d6"}},{"ruleId":"D1","level":"warning","message":{"text":"recall_multi._render_domain_hits (cyclomatic 16): recall_multi._render_domain_hits 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":"backend/core/recall_multi.py"},"region":{"startLine":625}}}],"partialFingerprints":{"codehealthFindingId/v1":"95788200f3041fc29aec08826e26816c9b948813681f4995f3230acaafc4bb01"}},{"ruleId":"D1","level":"warning","message":{"text":"session_harvest._parse_draft (cyclomatic 16): session_harvest._parse_draft 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":"backend/core/session_harvest.py"},"region":{"startLine":104}}}],"partialFingerprints":{"codehealthFindingId/v1":"717298e73b9f4869b689c8cf5dccd60972cdabc2f3d3df0c65fcb4271c2ef242"}},{"ruleId":"D1","level":"warning","message":{"text":"ui_actions.format_attention_for_agent (cyclomatic 16): ui_actions.format_attention_for_agent 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":"backend/core/ui_actions.py"},"region":{"startLine":773}}}],"partialFingerprints":{"codehealthFindingId/v1":"a2bf3ae72e2a8fd825dfa191e6a4da72e04eb5a78e4905350d6e240c9f5eb4e3"}},{"ruleId":"D1","level":"warning","message":{"text":"SQLiteDatabase._run_data_cleanups (cyclomatic 16): SQLiteDatabase._run_data_cleanups 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":"backend/database/sqlite.py"},"region":{"startLine":3248}}}],"partialFingerprints":{"codehealthFindingId/v1":"8a5a65319cf7193e7cefbcded9f8f0f7107f2d8bf98add67c89e6d335d1b70b1"}},{"ruleId":"D1","level":"warning","message":{"text":"ContextHealthHook._check_governance_budgets (cyclomatic 16): ContextHealthHook._check_governance_budgets 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":"backend/hooks/context_health_hook.py"},"region":{"startLine":3291}}}],"partialFingerprints":{"codehealthFindingId/v1":"5070f3778530077f66036f1814f05affa62a6009be246784413642d92ba63591"}},{"ruleId":"D1","level":"warning","message":{"text":"DistillationTriggerHook._extract_decisions (cyclomatic 16): DistillationTriggerHook._extract_decisions 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":"backend/hooks/distillation_hook.py"},"region":{"startLine":1126}}}],"partialFingerprints":{"codehealthFindingId/v1":"53472a755e71f456d8fdfe54e8a228ad8a35bb30cb7fe9d38b5a5e0e5d3fa4fd"}},{"ruleId":"D1","level":"warning","message":{"text":"DistillationTriggerHook._supersede_by_topic (cyclomatic 16): DistillationTriggerHook._supersede_by_topic 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":"backend/hooks/distillation_hook.py"},"region":{"startLine":1276}}}],"partialFingerprints":{"codehealthFindingId/v1":"28714aac7c07a281a68f80febba3b3039dc758587630c40956958ffe6c2662cf"}},{"ruleId":"D1","level":"warning","message":{"text":"DistillationTriggerHook._reconcile_open_threads_from_deliverables (cyclomatic 16): DistillationTriggerHook._reconcile_open_threads_from_deliverables 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":"backend/hooks/distillation_hook.py"},"region":{"startLine":2053}}}],"partialFingerprints":{"codehealthFindingId/v1":"82225d628d854e68fe4ca1953bbf20f24f7b72c390cc2fe96d345bc7455e36a2"}},{"ruleId":"D1","level":"warning","message":{"text":"executor._handle_maintenance (cyclomatic 16): executor._handle_maintenance 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":"backend/jobs/executor.py"},"region":{"startLine":1075}}}],"partialFingerprints":{"codehealthFindingId/v1":"da5cd7b0d57a5871e19b530af1deffee73a1793e79abfd87ede624ba5f04ed5b"}},{"ruleId":"D1","level":"warning","message":{"text":"session_health_probe.run_session_health_probe (cyclomatic 16): session_health_probe.run_session_health_probe has cyclomatic complexity 16 (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":"backend/jobs/handlers/session_health_probe.py"},"region":{"startLine":172}}}],"partialFingerprints":{"codehealthFindingId/v1":"71784478234ac1fdd873891b2b00a917a6169b4f8a3f940747cf6dc190c5008a"}},{"ruleId":"D1","level":"warning","message":{"text":"swarmai_monthly_report._collect_cultivation_metrics (cyclomatic 16): swarmai_monthly_report._collect_cultivation_metrics 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":"backend/jobs/handlers/swarmai_monthly_report.py"},"region":{"startLine":213}}}],"partialFingerprints":{"codehealthFindingId/v1":"416bc63c1301fcbc46f7c67d27be81d16fe99630ff1b91a74f8dbef99158f0a6"}},{"ruleId":"D1","level":"warning","message":{"text":"swarmai_monthly_report._collect_eval_metrics (cyclomatic 16): swarmai_monthly_report._collect_eval_metrics 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":"backend/jobs/handlers/swarmai_monthly_report.py"},"region":{"startLine":297}}}],"partialFingerprints":{"codehealthFindingId/v1":"93cfdc70480d6c3bbbcd2aecbddc284c7d3a5b7f30b36c7603dc1884f5cccf84"}},{"ruleId":"D1","level":"warning","message":{"text":"scheduler.load_user_context (cyclomatic 16): scheduler.load_user_context 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":"backend/jobs/scheduler.py"},"region":{"startLine":242}}}],"partialFingerprints":{"codehealthFindingId/v1":"0c92bd0e25881bca0c807d6e567bbadd062dfd1f53a95e9f523502a9384e87a8"}},{"ruleId":"D1","level":"warning","message":{"text":"self_tune.track_signal_usage (cyclomatic 16): self_tune.track_signal_usage 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":"backend/jobs/self_tune.py"},"region":{"startLine":176}}}],"partialFingerprints":{"codehealthFindingId/v1":"752f2acbd758a9e542f30f3f5278161cb0010d49b418aa4c2acb850a38bd9357"}},{"ruleId":"D1","level":"warning","message":{"text":"self_tune.suggest_new_feeds (cyclomatic 16): self_tune.suggest_new_feeds 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":"backend/jobs/self_tune.py"},"region":{"startLine":349}}}],"partialFingerprints":{"codehealthFindingId/v1":"d50b1cf06f04379934570a56115e4b108136e289aee62958310b3f67c8770255"}},{"ruleId":"D1","level":"warning","message":{"text":"system.get_system_status (cyclomatic 16): system.get_system_status 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":"backend/routers/system.py"},"region":{"startLine":150}}}],"partialFingerprints":{"codehealthFindingId/v1":"5251b5d912af8e73b52eaaf661ac794806efee719bc05108870c24663c68c334"}},{"ruleId":"D1","level":"warning","message":{"text":"check_migration_class.check_migration_class (cyclomatic 16): check_migration_class.check_migration_class 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":"backend/scripts/check_migration_class.py"},"region":{"startLine":197}}}],"partialFingerprints":{"codehealthFindingId/v1":"b443a802627f794743ec77a4b851ca91a476a67e38419d6129dfa6e2efe714e5"}},{"ruleId":"D1","level":"warning","message":{"text":"eval_runner.eval_trajectory (cyclomatic 16): eval_runner.eval_trajectory 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":"backend/scripts/eval_runner.py"},"region":{"startLine":440}}}],"partialFingerprints":{"codehealthFindingId/v1":"cd04e01709710823568aed145ee38947c00eedebb55c9f3aa114c45c3b2c77be"}},{"ruleId":"D1","level":"warning","message":{"text":"eval_runner._load_rules_context (cyclomatic 16): eval_runner._load_rules_context 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":"backend/scripts/eval_runner.py"},"region":{"startLine":803}}}],"partialFingerprints":{"codehealthFindingId/v1":"2376aed09c1ff1b3867f230a02907f1ddb7157f3a1d800c3f9e88ddc82c252f8"}},{"ruleId":"D1","level":"warning","message":{"text":"judge_telemetry_report.render (cyclomatic 16): judge_telemetry_report.render 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":"backend/scripts/judge_telemetry_report.py"},"region":{"startLine":101}}}],"partialFingerprints":{"codehealthFindingId/v1":"0d8bf47c669fc67c2b2bd93efaeb65078d9a5e613da6d82ab045a46d19034f6a"}},{"ruleId":"D1","level":"warning","message":{"text":"locked_write.locked_field_modify (cyclomatic 16): locked_write.locked_field_modify 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":"backend/scripts/locked_write.py"},"region":{"startLine":409}}}],"partialFingerprints":{"codehealthFindingId/v1":"0718df7e921a0e9041b6a7396b3aed708e2e3855d69216c2ce9fd8dfbf1fd0af"}},{"ruleId":"D1","level":"warning","message":{"text":"pipeline_analytics.analyze_estimation_accuracy (cyclomatic 16): pipeline_analytics.analyze_estimation_accuracy 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":"backend/scripts/pipeline_analytics.py"},"region":{"startLine":629}}}],"partialFingerprints":{"codehealthFindingId/v1":"3bd9324afeef4f90bc41acfba7e1654e11048ac7ceeec120a44793f5d39de945"}},{"ruleId":"D1","level":"warning","message":{"text":"BaseSchemaValidator.validate_against_xsd (cyclomatic 16): BaseSchemaValidator.validate_against_xsd 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":"backend/skills/s_docx/ooxml/scripts/validation/base.py"},"region":{"startLine":688}}}],"partialFingerprints":{"codehealthFindingId/v1":"ff18b1f2bffcd6eaf7ffe178baf189e491053da39933cb6131be7148d346f62e"}},{"ruleId":"D1","level":"warning","message":{"text":"PPTXSchemaValidator.validate_notes_slide_references (cyclomatic 16): PPTXSchemaValidator.validate_notes_slide_references 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":"backend/skills/s_docx/ooxml/scripts/validation/pptx.py"},"region":{"startLine":243}}}],"partialFingerprints":{"codehealthFindingId/v1":"c07b3477f97bdbad397770735ceb0c9c6f5af3d6dcff57b757f20bcc9703e254"}},{"ruleId":"D1","level":"warning","message":{"text":"DocxXMLEditor._inject_attributes_to_nodes (cyclomatic 16): DocxXMLEditor._inject_attributes_to_nodes 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":"backend/skills/s_docx/scripts/document.py"},"region":{"startLine":116}}}],"partialFingerprints":{"codehealthFindingId/v1":"0c9a953cd85f5d3849ace5a66fb4e3d533e71894243ab070313b165de9d7abf9"}},{"ruleId":"D1","level":"warning","message":{"text":"SelfLoopsHealthEngine._check_knowledge (cyclomatic 16): SelfLoopsHealthEngine._check_knowledge 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":"backend/skills/s_loops-health/scripts/loops_health_check.py"},"region":{"startLine":378}}}],"partialFingerprints":{"codehealthFindingId/v1":"053cc6067ead19a2e6d7493b9cc94b2e5e95cbe3dc57947195e8fe31b2e81847"}},{"ruleId":"D1","level":"warning","message":{"text":"locked_write.locked_field_modify (cyclomatic 16): locked_write.locked_field_modify 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":"backend/skills/s_persist/scripts/locked_write.py"},"region":{"startLine":409}}}],"partialFingerprints":{"codehealthFindingId/v1":"4d6740b3cee1df9ec32e06e0b14055d1c43214249df160f5c50d53066d1ef548"}},{"ruleId":"D1","level":"warning","message":{"text":"BaseSchemaValidator.validate_against_xsd (cyclomatic 16): BaseSchemaValidator.validate_against_xsd 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":"backend/skills/s_pptx/ooxml/scripts/validation/base.py"},"region":{"startLine":691}}}],"partialFingerprints":{"codehealthFindingId/v1":"3b2d29ada7135d6302491773eb4f0eed00e30810a9eaa69bf20e7266315da286"}},{"ruleId":"D1","level":"warning","message":{"text":"PPTXSchemaValidator.validate_notes_slide_references (cyclomatic 16): PPTXSchemaValidator.validate_notes_slide_references 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":"backend/skills/s_pptx/ooxml/scripts/validation/pptx.py"},"region":{"startLine":243}}}],"partialFingerprints":{"codehealthFindingId/v1":"a7e9652387ee7455941f637fbff9f8056d9a5e7f8b14f8fd8542781943ad4856"}},{"ruleId":"D1","level":"warning","message":{"text":"ShapeData.__init__ (cyclomatic 16): ShapeData.__init__ has cyclomatic complexity 16 (threshold 15). To reduce it, split the body: these branches sit side by side rather than nested inside one another, so extracting each one on its own would leave a function per branch. Group the statements between the checks into named steps and move each step into its own function, so the body reads as a short sequence of named stages."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/skills/s_pptx/scripts/inventory.py"},"region":{"startLine":388}}}],"partialFingerprints":{"codehealthFindingId/v1":"d4c7122697d7f6b8b4034181b998ddb88e2cb37fffe1acd2795b3f8a992ea5a9"}},{"ruleId":"D1","level":"warning","message":{"text":"ai_ready_helpers._collect_doc_file_anchors (cyclomatic 16): ai_ready_helpers._collect_doc_file_anchors has cyclomatic complexity 16 (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":"backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py"},"region":{"startLine":391}}}],"partialFingerprints":{"codehealthFindingId/v1":"c8714358708b2b26ddafc2616f2480b0bb49af335ad00e7ec0786d3b32e67d48"}},{"ruleId":"D1","level":"warning","message":{"text":"ai_ready_helpers.render_agents_md (cyclomatic 16): ai_ready_helpers.render_agents_md 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":"backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py"},"region":{"startLine":2270}}}],"partialFingerprints":{"codehealthFindingId/v1":"6824183e700bc1b776a2b293d96605841e09e6296f4e1e30442fcc5ea0da6bf7"}},{"ruleId":"D1","level":"warning","message":{"text":"steeringify.extract_corrections (cyclomatic 16): steeringify.extract_corrections 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":"backend/skills/s_steeringify/steeringify.py"},"region":{"startLine":94}}}],"partialFingerprints":{"codehealthFindingId/v1":"03ee46b556ae00a9b0346bf6ba9d85c7052e70e1d5047efadd045bef8a09349f"}},{"ruleId":"D1","level":"warning","message":{"text":"locked_write.locked_field_modify (cyclomatic 16): locked_write.locked_field_modify 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":"backend/templates/ddd-skills/s_ddd-persist/scripts/locked_write.py"},"region":{"startLine":409}}}],"partialFingerprints":{"codehealthFindingId/v1":"cc6057ace983ae4de70c81acb2a4d10f5f26a241d7517573bb13a83dc64de8d2"}},{"ruleId":"D1","level":"warning","message":{"text":"ai_ready_helpers._collect_doc_file_anchors (cyclomatic 16): ai_ready_helpers._collect_doc_file_anchors has cyclomatic complexity 16 (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":"backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py"},"region":{"startLine":391}}}],"partialFingerprints":{"codehealthFindingId/v1":"10bd3973754aec37470b24c9c165844fdf2ba36bbc4fd57b199f1f4bbc2180ac"}},{"ruleId":"D1","level":"warning","message":{"text":"ai_ready_helpers.render_agents_md (cyclomatic 16): ai_ready_helpers.render_agents_md 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":"backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py"},"region":{"startLine":1922}}}],"partialFingerprints":{"codehealthFindingId/v1":"81bf264b0cd7cd0c329d81f44643a7ae6005ffe88549789128275321eaced496"}},{"ruleId":"D1","level":"warning","message":{"text":"lint_doc_frontmatter.check_file (cyclomatic 16): lint_doc_frontmatter.check_file 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":"scripts/lint_doc_frontmatter.py"},"region":{"startLine":47}}}],"partialFingerprints":{"codehealthFindingId/v1":"05eac09b142a18ba246b251dfd071548129b5f087d6e93fb5b2c7c42905e5cd3"}},{"ruleId":"D1","level":"warning","message":{"text":"CMBrainOverlay.ProposalCard (cyclomatic 16): CMBrainOverlay.ProposalCard 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":"desktop/src/components/layout/CMBrainOverlay.tsx"},"region":{"startLine":392}}}],"partialFingerprints":{"codehealthFindingId/v1":"8d132fd40f7cc0b45651751c6bf145e2cf18d62c2d0f948c993342ad7eb161dd"}},{"ruleId":"D1","level":"warning","message":{"text":"CMBrainOverlay.ContextTab (cyclomatic 16): CMBrainOverlay.ContextTab has cyclomatic complexity 16 (threshold 15). Most of this is not in the body itself: 3 of the 16 points are its own statements and the rest belongs to one function literal inside it that branches (line 556). The decisions are inside the literal, which nothing outside this body can call, review or test on its own, so splitting the enclosing body is not the move available here. To reduce it, lift the literal\u0027s work into a named function or method at the enclosing scope and have the literal call it, then reduce whichever part then reads as the largest."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/layout/CMBrainOverlay.tsx"},"region":{"startLine":520}}}],"partialFingerprints":{"codehealthFindingId/v1":"ca3916cd1357af1b8d341c13e8c2d36942ec60cd97ec3dd4a0718e473b37d0a6"}},{"ruleId":"D1","level":"warning","message":{"text":"CMBrainOverlay.KnowledgeGraph (cyclomatic 16): CMBrainOverlay.KnowledgeGraph has cyclomatic complexity 16 (threshold 15). Of this number, 9 points are the body\u0027s own statements and 7 belong to 3 function literals inside it that branch. 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":"desktop/src/components/layout/CMBrainOverlay.tsx"},"region":{"startLine":669}}}],"partialFingerprints":{"codehealthFindingId/v1":"4cd8ce7737aef32ac014c6f2d350dad1def3ad0cfa5f9288619bb98f98e7fbd6"}},{"ruleId":"D1","level":"warning","message":{"text":"agents.toSnakeCase (cyclomatic 16): agents.toSnakeCase 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":"desktop/src/services/agents.ts"},"region":{"startLine":5}}}],"partialFingerprints":{"codehealthFindingId/v1":"c510c026c07f51ca467f61da8d2efc779479c0c644c7fe0045177d09223c8baf"}},{"ruleId":"D1","level":"warning","message":{"text":"todos.toSnakeCase (cyclomatic 16): todos.toSnakeCase 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":"desktop/src/services/todos.ts"},"region":{"startLine":53}}}],"partialFingerprints":{"codehealthFindingId/v1":"80d9480de50ef06ddf6615b202613a8da1ed006e293d78704a92883a030ba4f2"}},{"ruleId":"D1","level":"warning","message":{"text":"HtmlRenderer.HtmlRenderer (cyclomatic 16): HtmlRenderer.HtmlRenderer has cyclomatic complexity 16 (threshold 15). Of this number, 11 points are the body\u0027s own statements and 5 belong to 4 function literals inside it that branch. 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":"desktop/src/components/file-viewer/renderers/HtmlRenderer.tsx"},"region":{"startLine":94}}}],"partialFingerprints":{"codehealthFindingId/v1":"5536702b4c47bcdd048c276e3f462c00b4c2dac75245609d676cd66064a04f0e"}},{"ruleId":"D1","level":"warning","message":{"text":"useReferencedFiles.useReferencedFiles (cyclomatic 16): useReferencedFiles.useReferencedFiles has cyclomatic complexity 16 (threshold 15). Most of this is not in the body itself: 1 of the 16 points is its own statement and the rest belongs to 6 function literals inside it that branch (lines 286, 276, 283, \u2026). The decisions are inside those literals, which nothing outside this body can call, review or test on its own, so splitting the enclosing body is not the move available here. To reduce it, lift the literals\u0027 work into a named function or method at the enclosing scope and have each literal call it, then reduce whichever part then reads as the largest."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/hooks/useReferencedFiles.ts"},"region":{"startLine":263}}}],"partialFingerprints":{"codehealthFindingId/v1":"bfad9f341135d9f610c701a1c03a9b306581b37f6784734339c869006e27e41e"}},{"ruleId":"D1","level":"warning","message":{"text":"TSCCModules.RecallTab (cyclomatic 16): TSCCModules.RecallTab has cyclomatic complexity 16 (threshold 15). Of this number, 11 points are the body\u0027s own statements and 5 belong to 2 function literals inside it that branch. To reduce it, name the conditions: bind each compound test to a well-named local or a small predicate function, so the body reads as a sequence of named decisions rather than a chain of operators."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/pages/chat/components/TSCCModules.tsx"},"region":{"startLine":369}}}],"partialFingerprints":{"codehealthFindingId/v1":"e2bd17765949b6b43f0035cf011a6a21dee6aecb416bb963cb274beca7739c92"}},{"ruleId":"D1","level":"warning","message":{"text":"FileBrowser.FileBrowser (cyclomatic 16): FileBrowser.FileBrowser has cyclomatic complexity 16 (threshold 15). Of this number, 9 points are the body\u0027s own statements and 7 belong to 4 function literals inside it that branch. 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 is NOT this file\u0027s highest cyclomatic complexity: FileBrowser.getFileIcon (cyclomatic 22) is higher and carries no row of its own \u2014 it was excluded as a flat dispatcher (a long switch/match over independent cases: many branches, almost no nesting), which this dimension does not treat as a refactor obligation. It is named here so the ranking you see in this file is not mistaken for the whole of it; the excluded method is counted neither in this dimension\u0027s figures nor in its score."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/workspace/FileBrowser.tsx"},"region":{"startLine":99}}}],"partialFingerprints":{"codehealthFindingId/v1":"6b3c8f146c856fd4d9244cfa3db4d1f22bf74ce2290f1c89592118c7d7454fb8"}},{"ruleId":"D2","level":"warning","message":{"text":"useChatStreamingLifecycle.useChatStreamingLifecycle (cognitive 1088): useChatStreamingLifecycle.useChatStreamingLifecycle has cognitive complexity 1088 (threshold 15). Drivers by points: if/else 383 (810 pts), ternaries 62 (147 pts), boolean chains 106, error handling 8 (21 pts), loops 3 (4 pts) (nesting depth added 526). Most of this is not in the body itself: 6 of the 1088 points are its own statements and the rest belongs to 60 function literals inside it that branch (lines 2302, 1235, 3756, \u2026). The decisions are inside those literals, which nothing outside this body can call, review or test on its own, so splitting the enclosing body is not the move available here. To reduce it, lift the literals\u0027 work into a named function or method at the enclosing scope and have each literal call it, then reduce whichever part then reads as the largest."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/hooks/useChatStreamingLifecycle.ts"},"region":{"startLine":1030}}}],"partialFingerprints":{"codehealthFindingId/v1":"0b21989ac4b68794133efdfa2c388032f22163dc701803889e7b19aaf34919e7"}},{"ruleId":"D2","level":"warning","message":{"text":"ChatPage.ChatPage (cognitive 710): ChatPage.ChatPage has cognitive complexity 710 (threshold 15). Drivers by points: if/else 277 (443 pts), ternaries 56 (121 pts), boolean chains 101, error handling 14 (23 pts), loops 8 (17 pts), match/switch 3 (5 pts) (nesting depth added 251). Of this number, 19 points are the body\u0027s own statements and 691 belong to 87 function literals inside it that branch. To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/pages/ChatPage.tsx"},"region":{"startLine":129}}}],"partialFingerprints":{"codehealthFindingId/v1":"9803770c588ed129396332ede25bbd5c9e646608281bf88acd0536efa2625e2e"}},{"ruleId":"D2","level":"warning","message":{"text":"pipeline_validator.validate (cognitive 620): pipeline_validator.validate has cognitive complexity 620 (threshold 15). Drivers by points: if/else 150 (459 pts), loops 11 (53 pts), boolean chains 51, ternaries 9 (46 pts), error handling 3 (11 pts) (nesting depth added 396). 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":"backend/scripts/pipeline_validator.py"},"region":{"startLine":2603}}}],"partialFingerprints":{"codehealthFindingId/v1":"a596e8f623950cb4d1f2314c98d95eaa99cb39fa14a3eef98e027268ba8ebd8b"}},{"ruleId":"D2","level":"warning","message":{"text":"StreamingOrchestrator._read_formatted_response (cognitive 594): StreamingOrchestrator._read_formatted_response has cognitive complexity 594 (threshold 15). Drivers by points: if/else 85 (355 pts), error handling 18 (69 pts), loops 13 (61 pts), boolean chains 55, ternaries 16 (54 pts) (nesting depth added 407). 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":"backend/core/streaming_orchestrator.py"},"region":{"startLine":525}}}],"partialFingerprints":{"codehealthFindingId/v1":"735bc61c8debe4427a6e86943b17a90220bc07eaa26bbccf98d677ebb19a3853"}},{"ruleId":"D2","level":"warning","message":{"text":"artifact_cli.cmd_run_update (cognitive 410): artifact_cli.cmd_run_update has cognitive complexity 410 (threshold 15). Drivers by points: if/else 85 (274 pts), boolean chains 39, ternaries 8 (35 pts), loops 8 (32 pts), error handling 9 (30 pts) (nesting depth added 261). 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":"backend/scripts/artifact_cli.py"},"region":{"startLine":1797}}}],"partialFingerprints":{"codehealthFindingId/v1":"c6032c9b5ea4e3dff9e794f6d08aa8b988073a6260539a1d717cc345aeb943ef"}},{"ruleId":"D2","level":"warning","message":{"text":"ChannelGateway._handle_conversation (cognitive 328): ChannelGateway._handle_conversation has cognitive complexity 328 (threshold 15). Drivers by points: if/else 72 (203 pts), error handling 18 (45 pts), boolean chains 44, loops 6 (18 pts), ternaries 11 (18 pts) (nesting depth added 177). 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":"backend/channels/gateway.py"},"region":{"startLine":1619}}}],"partialFingerprints":{"codehealthFindingId/v1":"2087e538e556f8affe7cc12f19dd41823dafc14a1518fa21bd3d2863752f29ee"}},{"ruleId":"D2","level":"warning","message":{"text":"artifact_cli.cmd_run_report (cognitive 280): artifact_cli.cmd_run_report has cognitive complexity 280 (threshold 15). Drivers by points: if/else 83 (147 pts), loops 26 (52 pts), boolean chains 45, ternaries 17 (29 pts), error handling 3 (7 pts) (nesting depth added 106). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/scripts/artifact_cli.py"},"region":{"startLine":3992}}}],"partialFingerprints":{"codehealthFindingId/v1":"51f861d0fe2f6712eaceeccfac79f040330fba2da12d619f950c35f35f55a6f2"}},{"ruleId":"D2","level":"warning","message":{"text":"html2pptx.extractSlideData (cognitive 246): html2pptx.extractSlideData has cognitive complexity 246 (threshold 15). Drivers by points: if/else 82 (160 pts), boolean chains 56, ternaries 11 (28 pts), loops 1 (2 pts) (nesting depth added 96). Most of this is not in the body itself: 0 of the 246 points are its own statements and the rest belongs to 15 function literals inside it that branch (lines 534, 422, 365, \u2026). The decisions are inside those literals, which nothing outside this body can call, review or test on its own, so splitting the enclosing body is not the move available here. To reduce it, lift the literals\u0027 work into a named function or method at the enclosing scope and have each literal call it, then reduce whichever part then reads as the largest."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/skills/s_pptx/scripts/html2pptx.js"},"region":{"startLine":244}}}],"partialFingerprints":{"codehealthFindingId/v1":"576b73ce8331737987d5b673f4956f08c9f4455db9cbb9835a756b2596e77e86"}},{"ruleId":"D2","level":"warning","message":{"text":"FileEditorCore.FileEditorCore (cognitive 208): FileEditorCore.FileEditorCore has cognitive complexity 208 (threshold 15). Drivers by points: if/else 71 (88 pts), boolean chains 69, ternaries 19 (36 pts), error handling 7 (8 pts), loops 4 (7 pts) (nesting depth added 38). Of this number, 75 points are the body\u0027s own statements and 133 belong to 47 function literals inside it that branch. To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/common/FileEditorCore.tsx"},"region":{"startLine":606}}}],"partialFingerprints":{"codehealthFindingId/v1":"fe374997d71fb2b447c1efff1e11162327bf5a31bf4057a30c9e43c66c2d16ef"}},{"ruleId":"D2","level":"warning","message":{"text":"evolution_optimizer._run_evolution_cycle_locked (cognitive 202): evolution_optimizer._run_evolution_cycle_locked has cognitive complexity 202 (threshold 15). Drivers by points: if/else 53 (137 pts), loops 15 (31 pts), boolean chains 16, error handling 10 (16 pts), ternaries 1 (2 pts) (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":"backend/core/evolution_optimizer.py"},"region":{"startLine":1148}}}],"partialFingerprints":{"codehealthFindingId/v1":"0fa228a1874944ec8d14bc8be50b7bd451d9e70dc496edd8030c51507528ec82"}},{"ruleId":"D2","level":"warning","message":{"text":"proactive_intelligence.build_session_briefing_data (cognitive 172): proactive_intelligence.build_session_briefing_data has cognitive complexity 172 (threshold 15). Drivers by points: if/else 37 (101 pts), error handling 13 (34 pts), loops 11 (21 pts), ternaries 3 (10 pts), boolean chains 6 (nesting depth added 102). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/core/proactive_intelligence.py"},"region":{"startLine":1884}}}],"partialFingerprints":{"codehealthFindingId/v1":"2d4dd2338a9f9708c700e27d6004ce62bb38592d585dc3c6707f8ca28a005ecb"}},{"ruleId":"D2","level":"warning","message":{"text":"proactive_intelligence._advance_pipeline_recovery_state (cognitive 171): proactive_intelligence._advance_pipeline_recovery_state has cognitive complexity 171 (threshold 15). Drivers by points: if/else 27 (91 pts), error handling 12 (49 pts), boolean chains 20, ternaries 2 (8 pts), loops 2 (3 pts) (nesting depth added 108). 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":"backend/core/proactive_intelligence.py"},"region":{"startLine":816}}}],"partialFingerprints":{"codehealthFindingId/v1":"327d333ac1cfbb45c3a0b7c386c402dfc70f63fc67d191710139e269c75ddae0"}},{"ruleId":"D2","level":"warning","message":{"text":"DistillationTriggerHook._distill_files (cognitive 170): DistillationTriggerHook._distill_files has cognitive complexity 170 (threshold 15). Drivers by points: if/else 34 (79 pts), loops 17 (45 pts), ternaries 6 (29 pts), boolean chains 10, error handling 3 (7 pts) (nesting depth added 100). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/hooks/distillation_hook.py"},"region":{"startLine":451}}}],"partialFingerprints":{"codehealthFindingId/v1":"934edb42d2d4456bed1a66452fbc64be68a0652acf67de8ac50beb195e991872"}},{"ruleId":"D2","level":"warning","message":{"text":"ChatInput.ChatInput (cognitive 154): ChatInput.ChatInput has cognitive complexity 154 (threshold 15). Drivers by points: if/else 62 (76 pts), boolean chains 53, ternaries 16 (23 pts), error handling 1, loops 1 (nesting depth added 21). Of this number, 41 points are the body\u0027s own statements and 113 belong to 38 function literals inside it that branch. 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":"desktop/src/pages/chat/components/ChatInput.tsx"},"region":{"startLine":164}}}],"partialFingerprints":{"codehealthFindingId/v1":"c08d28dd0cef359a1a00366b83eb28ee329e16ddd323e292acc010417e81fc06"}},{"ruleId":"D2","level":"warning","message":{"text":"security_hooks._segment_is_irreversible (cognitive 135): security_hooks._segment_is_irreversible has cognitive complexity 135 (threshold 15). Drivers by points: if/else 36 (109 pts), boolean chains 13, loops 6 (13 pts) (nesting depth added 80). 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":"backend/core/security_hooks.py"},"region":{"startLine":284}}}],"partialFingerprints":{"codehealthFindingId/v1":"e6f2565180c13ca14313b9822652979c4e8db42d5aaf7c9abc9c06ca9b9a2e37"}},{"ruleId":"D2","level":"warning","message":{"text":"SessionUnit.send (cognitive 134): SessionUnit.send has cognitive complexity 134 (threshold 15). Drivers by points: if/else 43 (94 pts), loops 7 (21 pts), boolean chains 10, error handling 3 (6 pts), ternaries 2 (3 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":"backend/core/session_unit.py"},"region":{"startLine":1867}}}],"partialFingerprints":{"codehealthFindingId/v1":"4a77ee85203ee504099c4b5e6a74cbb86ee91a1ca2ed3da91d08aa8e308bcdd3"}},{"ruleId":"D2","level":"warning","message":{"text":"SessionRouter.run_conversation (cognitive 133): SessionRouter.run_conversation has cognitive complexity 133 (threshold 15). Drivers by points: if/else 45 (69 pts), boolean chains 26, error handling 8 (20 pts), ternaries 12 (17 pts), loops 1 (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":"backend/core/session_router.py"},"region":{"startLine":2782}}}],"partialFingerprints":{"codehealthFindingId/v1":"14a3dc862a20fbbd400ebf5f7582c32f28da545b6ec59b14dcd7238bc259f494"}},{"ruleId":"D2","level":"warning","message":{"text":"eval_runner.generate_html_report (cognitive 133): eval_runner.generate_html_report has cognitive complexity 133 (threshold 15). Drivers by points: ternaries 34 (55 pts), if/else 33 (54 pts), loops 14 (21 pts), boolean chains 3 (nesting depth added 49). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/scripts/eval_runner.py"},"region":{"startLine":2163}}}],"partialFingerprints":{"codehealthFindingId/v1":"d211bc4822a4881f0a0284e6ef1ca6ffb1f6c6f65ab5b0d6f5059c9e793dc7ed"}},{"ruleId":"D2","level":"warning","message":{"text":"FileViewer.FileViewerImpl (cognitive 130): FileViewer.FileViewerImpl has cognitive complexity 130 (threshold 15). Drivers by points: if/else 50 (74 pts), boolean chains 32, ternaries 6 (13 pts), error handling 4 (8 pts), loops 2 (3 pts) (nesting depth added 36). Of this number, 23 points are the body\u0027s own statements and 107 belong to 14 function literals inside it that branch. To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/file-viewer/FileViewer.tsx"},"region":{"startLine":126}}}],"partialFingerprints":{"codehealthFindingId/v1":"7be44d825263b97a000b5e021c6e90eb4069b7f91c0e708a5989b1371b73d312"}},{"ruleId":"D2","level":"warning","message":{"text":"SkillsPage.GenerateSkillForm (cognitive 126): SkillsPage.GenerateSkillForm has cognitive complexity 126 (threshold 15). Drivers by points: ternaries 28 (49 pts), if/else 36 (44 pts), boolean chains 31, error handling 2 (nesting depth added 29). Of this number, 37 points are the body\u0027s own statements and 89 belong to 20 function literals inside it that branch. To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/pages/SkillsPage.tsx"},"region":{"startLine":327}}}],"partialFingerprints":{"codehealthFindingId/v1":"71d19b1afc1be481779a498ea906d94af43b19dd7fda369ffa18db5f9d8529c3"}},{"ruleId":"D2","level":"warning","message":{"text":"main (cognitive 122): main has cognitive complexity 122 (threshold 15). Drivers by points: if/else 34 (63 pts), ternaries 11 (25 pts), error handling 7 (17 pts), boolean chains 16, match/switch 1 (nesting depth added 53). Of this number, 115 points are the body\u0027s own statements and 7 belong to 8 function literals inside it that branch. To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/skills/s_browser-agent/browser-agent.mjs"},"region":{"startLine":304}}}],"partialFingerprints":{"codehealthFindingId/v1":"336e676b9bcdc0a04dee52d5d39d1a30e9edb7c5f0167684065dd96159ca6219"}},{"ruleId":"D2","level":"warning","message":{"text":"style-extract.extract_shapes_summary (cognitive 114): style-extract.extract_shapes_summary has cognitive complexity 114 (threshold 15). Drivers by points: if/else 13 (53 pts), ternaries 8 (32 pts), loops 9 (29 pts) (nesting depth added 84). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/skills/s_pptx/scripts/style-extract.py"},"region":{"startLine":81}}}],"partialFingerprints":{"codehealthFindingId/v1":"b34e370cf7b973408b1052c6977d49f9980a27dc857fc04f6a17b1158cf565ca"}},{"ruleId":"D2","level":"warning","message":{"text":"SessionMiner._extract_skill_invocations (cognitive 110): SessionMiner._extract_skill_invocations has cognitive complexity 110 (threshold 15). Drivers by points: if/else 14 (70 pts), loops 6 (22 pts), ternaries 3 (14 pts), boolean chains 4 (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":"backend/core/session_miner.py"},"region":{"startLine":287}}}],"partialFingerprints":{"codehealthFindingId/v1":"ca072eaf1c03268e19d8adf591be9b51ac9f4fc75587e6b88ad283d7ac383950"}},{"ruleId":"D2","level":"warning","message":{"text":"code_intel_reindex.reindex_projects (cognitive 108): code_intel_reindex.reindex_projects has cognitive complexity 108 (threshold 15). Drivers by points: if/else 19 (54 pts), ternaries 5 (21 pts), error handling 4 (18 pts), loops 3 (8 pts), boolean chains 7 (nesting depth added 70). 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":"backend/jobs/handlers/code_intel_reindex.py"},"region":{"startLine":20}}}],"partialFingerprints":{"codehealthFindingId/v1":"5b8863710dc79df2a8e95caad9153646d6c8569802f54f2302e42e7a980a4ba5"}},{"ruleId":"D2","level":"warning","message":{"text":"skill_metrics_hook._detect_skill_invocations (cognitive 102): skill_metrics_hook._detect_skill_invocations has cognitive complexity 102 (threshold 15). Drivers by points: if/else 19 (67 pts), loops 8 (19 pts), ternaries 3 (12 pts), boolean chains 4 (nesting depth added 68). 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":"backend/hooks/skill_metrics_hook.py"},"region":{"startLine":112}}}],"partialFingerprints":{"codehealthFindingId/v1":"64d7cb50239a02bbe3d56e4d1308d172715bdb339b06efdbca82af7bb91e7bd9"}},{"ruleId":"D2","level":"warning","message":{"text":"adversarial_meta.check_adversarial_health (cognitive 101): adversarial_meta.check_adversarial_health has cognitive complexity 101 (threshold 15). Drivers by points: if/else 15 (40 pts), ternaries 4 (26 pts), error handling 4 (16 pts), loops 6 (16 pts), boolean chains 3 (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":"backend/core/adversarial_meta.py"},"region":{"startLine":21}}}],"partialFingerprints":{"codehealthFindingId/v1":"fe77588331afb232dea6c40f9aa1153d352cd90a701b88bfe4ab1e2478f69504"}},{"ruleId":"D2","level":"warning","message":{"text":"pipeline_validator._check_depth (cognitive 99): pipeline_validator._check_depth has cognitive complexity 99 (threshold 15). Drivers by points: if/else 27 (76 pts), boolean chains 19, loops 1 (4 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":"backend/scripts/pipeline_validator.py"},"region":{"startLine":1995}}}],"partialFingerprints":{"codehealthFindingId/v1":"55fae1b957af6f517c5cc5fae6ad19dede13a75f586c32d252886ef5ff2b26bf"}},{"ruleId":"D2","level":"warning","message":{"text":"workspace_api.resolve_path_to_physical (cognitive 97): workspace_api.resolve_path_to_physical has cognitive complexity 97 (threshold 15). Drivers by points: if/else 23 (62 pts), loops 6 (16 pts), error handling 3 (12 pts), boolean chains 7 (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":"backend/routers/workspace_api.py"},"region":{"startLine":992}}}],"partialFingerprints":{"codehealthFindingId/v1":"1cbe605550ec65a6638494ab5ec658eded75e7c103a5eacdd5b2865d4abc257b"}},{"ruleId":"D2","level":"warning","message":{"text":"artifact_cli._extract_run_metrics (cognitive 97): artifact_cli._extract_run_metrics has cognitive complexity 97 (threshold 15). Drivers by points: if/else 25 (55 pts), ternaries 10 (29 pts), boolean chains 7, loops 3 (4 pts), error handling 1 (2 pts) (nesting depth added 51). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/scripts/artifact_cli.py"},"region":{"startLine":4783}}}],"partialFingerprints":{"codehealthFindingId/v1":"b5000f864f20c14486101566121d7c2a2f3169b2a12003512ca26e42f17f4c34"}},{"ruleId":"D2","level":"warning","message":{"text":"polly.synthesize (cognitive 94): polly.synthesize has cognitive complexity 94 (threshold 15). Drivers by points: if/else 19 (66 pts), loops 6 (21 pts), error handling 1 (3 pts), ternaries 1 (3 pts), boolean chains 1 (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":"backend/skills/s_pollinate/scripts/tts/backends/polly.py"},"region":{"startLine":246}}}],"partialFingerprints":{"codehealthFindingId/v1":"4209a78cd247dbeab4a477dc8e50b5a54d8a8dd1216ad6b593e149f13faf650b"}},{"ruleId":"D2","level":"warning","message":{"text":"SummarizationPipeline._extract_files_modified (cognitive 93): SummarizationPipeline._extract_files_modified has cognitive complexity 93 (threshold 15). Drivers by points: if/else 15 (66 pts), loops 5 (17 pts), boolean chains 10 (nesting depth added 63). 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":"backend/core/summarization.py"},"region":{"startLine":422}}}],"partialFingerprints":{"codehealthFindingId/v1":"f6a7f16208577250a0a3ee058defb4bd2aee64f774c2e0c17f32afb9eb853c0d"}},{"ruleId":"D2","level":"warning","message":{"text":"PromptBuilder.build_system_prompt (cognitive 89): PromptBuilder.build_system_prompt has cognitive complexity 89 (threshold 15). Drivers by points: if/else 35 (50 pts), boolean chains 16, ternaries 5 (12 pts), error handling 7 (10 pts), loops 1 (nesting depth added 25). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/core/prompt_builder.py"},"region":{"startLine":825}}}],"partialFingerprints":{"codehealthFindingId/v1":"6b921e404f488a78cb76ece84ef722cae0a2936fa7f418f6af7da0385f5ff443"}},{"ruleId":"D2","level":"warning","message":{"text":"useChatStreamingLifecycle.updateMessages (cognitive 89): useChatStreamingLifecycle.updateMessages has cognitive complexity 89 (threshold 15). Drivers by points: if/else 24 (59 pts), ternaries 4 (12 pts), boolean chains 10, loops 4 (8 pts) (nesting depth added 47). Most of this is not in the body itself: 0 of the 89 points are its own statements and the rest belongs to one function literal inside it that branches (line 372). The decisions are inside the literal, which nothing outside this body can call, review or test on its own, so splitting the enclosing body is not the move available here. To reduce it, lift the literal\u0027s work into a named function or method at the enclosing scope and have the literal call it, then reduce whichever part then reads as the largest."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/hooks/useChatStreamingLifecycle.ts"},"region":{"startLine":366}}}],"partialFingerprints":{"codehealthFindingId/v1":"300f6e2cde6b65a2ba5382083a7fdfadc868f10c5d8117c9ffe9adbe53d26f13"}},{"ruleId":"D2","level":"warning","message":{"text":"executor.execute_job (cognitive 88): executor.execute_job has cognitive complexity 88 (threshold 15). Drivers by points: ternaries 22 (48 pts), if/else 14 (26 pts), boolean chains 9, error handling 3 (5 pts) (nesting depth added 40). 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":"backend/jobs/executor.py"},"region":{"startLine":154}}}],"partialFingerprints":{"codehealthFindingId/v1":"cad8cbbde20cd11a3cffeaae119bc3d8db9daf99ef6d30f2e9deaf9192b4ace0"}},{"ruleId":"D2","level":"warning","message":{"text":"swarmai::spawn_daemon_health_watchdog (cognitive 88): swarmai::spawn_daemon_health_watchdog has cognitive complexity 88 (threshold 15). Drivers by points: if/else 24 (59 pts), match/switch 8 (21 pts), boolean chains 7, loops 1 (nesting depth added 48). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src-tauri/src/lib.rs"},"region":{"startLine":1856}}}],"partialFingerprints":{"codehealthFindingId/v1":"0a5b75ec219ef338c19efb99c7313edae78ad548b938e2db5ee88e676ee5845f"}},{"ruleId":"D2","level":"warning","message":{"text":"TabView.TabViewImpl (cognitive 87): TabView.TabViewImpl has cognitive complexity 87 (threshold 15). Drivers by points: ternaries 17 (40 pts), boolean chains 24, if/else 17 (23 pts) (nesting depth added 29). Most of this is not in the body itself: 15 of the 87 points are its own statements and the rest belongs to 10 function literals inside it that branch (lines 486, 290, 381, \u2026). The decisions are inside those literals, which nothing outside this body can call, review or test on its own, so splitting the enclosing body is not the move available here. To reduce it, lift the literals\u0027 work into a named function or method at the enclosing scope and have each literal call it, then reduce whichever part then reads as the largest."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/pages/chat/components/TabView.tsx"},"region":{"startLine":208}}}],"partialFingerprints":{"codehealthFindingId/v1":"2217e85894d2acc68ea01d9bce7580ed5df337f065a9914436735402944c61e7"}},{"ruleId":"D2","level":"warning","message":{"text":"ai_ready_helpers.extract_import_graph (cognitive 86): ai_ready_helpers.extract_import_graph has cognitive complexity 86 (threshold 15). Drivers by points: if/else 22 (54 pts), ternaries 5 (14 pts), loops 9 (13 pts), boolean chains 3, error handling 1 (2 pts) (nesting depth added 46). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py"},"region":{"startLine":2388}}}],"partialFingerprints":{"codehealthFindingId/v1":"0b887720cf289a1cb339f06a5cd1ae50fed58e6469fc2238c2371c06efa3488f"}},{"ruleId":"D2","level":"warning","message":{"text":"ai_ready_helpers.extract_import_graph (cognitive 86): ai_ready_helpers.extract_import_graph has cognitive complexity 86 (threshold 15). Drivers by points: if/else 22 (54 pts), ternaries 5 (14 pts), loops 9 (13 pts), boolean chains 3, error handling 1 (2 pts) (nesting depth added 46). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py"},"region":{"startLine":2041}}}],"partialFingerprints":{"codehealthFindingId/v1":"09ce3867e6cae53b8c1f453b05b7be77f881a58a7ed27d05e51f6ace036c15e5"}},{"ruleId":"D2","level":"warning","message":{"text":"pipeline_validator.validate_artifact_data (cognitive 82): pipeline_validator.validate_artifact_data has cognitive complexity 82 (threshold 15). Drivers by points: if/else 28 (67 pts), boolean chains 10, loops 3 (5 pts) (nesting depth added 41). 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":"backend/scripts/pipeline_validator.py"},"region":{"startLine":1270}}}],"partialFingerprints":{"codehealthFindingId/v1":"2b0f046bad11b6799e3faecd220545527fb96495a0d079a95ec8b9fa0406d568"}},{"ruleId":"D2","level":"warning","message":{"text":"ddd_entry_lifecycle.parse_entries (cognitive 81): ddd_entry_lifecycle.parse_entries has cognitive complexity 81 (threshold 15). Drivers by points: if/else 14 (48 pts), error handling 2 (12 pts), loops 3 (9 pts), boolean chains 7, ternaries 1 (5 pts) (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":"backend/core/ddd_entry_lifecycle.py"},"region":{"startLine":521}}}],"partialFingerprints":{"codehealthFindingId/v1":"6444e867a2679f2331dc31151d929f4b0c445a830ee093086b7880497c1e6253"}},{"ruleId":"D2","level":"warning","message":{"text":"swarmai_monthly_report._generate_monthly_report (cognitive 81): swarmai_monthly_report._generate_monthly_report has cognitive complexity 81 (threshold 15). Drivers by points: if/else 36 (47 pts), ternaries 14 (26 pts), loops 3 (6 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":"backend/jobs/handlers/swarmai_monthly_report.py"},"region":{"startLine":589}}}],"partialFingerprints":{"codehealthFindingId/v1":"e10ef41a999e66d0ba48c28ecd75ad0f3c6e1323072e613c61afa317528fc5f1"}},{"ruleId":"D2","level":"warning","message":{"text":"scheduler.run_scheduler (cognitive 81): scheduler.run_scheduler has cognitive complexity 81 (threshold 15). Drivers by points: if/else 26 (52 pts), loops 10 (17 pts), boolean chains 7, ternaries 1 (5 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":"backend/jobs/scheduler.py"},"region":{"startLine":472}}}],"partialFingerprints":{"codehealthFindingId/v1":"68fadec31bf0ff570ca1522da69cd21d347dcbc842eb08343d071dd0b827d7ef"}},{"ruleId":"D2","level":"warning","message":{"text":"pipeline_validator._check_semantic_depth (cognitive 81): pipeline_validator._check_semantic_depth has cognitive complexity 81 (threshold 15). Drivers by points: if/else 20 (65 pts), boolean chains 9, loops 2 (5 pts), ternaries 1 (2 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":"backend/scripts/pipeline_validator.py"},"region":{"startLine":2242}}}],"partialFingerprints":{"codehealthFindingId/v1":"0a90fdd8325eb7c57735433114725633f0514e891fcfd94cba9f7af37d9205e4"}},{"ruleId":"D2","level":"warning","message":{"text":"ContextHealthHook._auto_cultivate_session_signals (cognitive 78): ContextHealthHook._auto_cultivate_session_signals has cognitive complexity 78 (threshold 15). Drivers by points: if/else 19 (44 pts), error handling 5 (15 pts), loops 6 (15 pts), boolean chains 3, ternaries 1 (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":"backend/hooks/context_health_hook.py"},"region":{"startLine":1163}}}],"partialFingerprints":{"codehealthFindingId/v1":"dadcea169bc402d9efd6089e0ad2ac7dedc31d644fc3eacac2c8e9b847d74995"}},{"ruleId":"D2","level":"warning","message":{"text":"security_hooks._pending_commit_paths (cognitive 77): security_hooks._pending_commit_paths has cognitive complexity 77 (threshold 15). Drivers by points: if/else 20 (55 pts), boolean chains 8, loops 5 (7 pts), ternaries 2 (4 pts), error handling 3 (nesting depth added 39). 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":"backend/core/security_hooks.py"},"region":{"startLine":1729}}}],"partialFingerprints":{"codehealthFindingId/v1":"f44dbbcda05fbcfb6ddfa65d15be4dc435cba84851f3e42d31341e082ed93313"}},{"ruleId":"D2","level":"warning","message":{"text":"tool_summarizer.summarize_tool_use (cognitive 76): tool_summarizer.summarize_tool_use has cognitive complexity 76 (threshold 15). Drivers by points: if/else 20 (35 pts), ternaries 13 (27 pts), boolean chains 14 (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":"backend/core/tool_summarizer.py"},"region":{"startLine":150}}}],"partialFingerprints":{"codehealthFindingId/v1":"e10ed1d32d5542b4f6ed71ee5c0b0469ea771948073b41695bbda88a54d0b66d"}},{"ruleId":"D2","level":"warning","message":{"text":"browser-agent.compressDOM (cognitive 75): browser-agent.compressDOM has cognitive complexity 75 (threshold 15). Drivers by points: if/else 30 (54 pts), boolean chains 12, loops 3 (4 pts), ternaries 2 (4 pts), error handling 1 (nesting depth added 27). Most of this is not in the body itself: 0 of the 75 points are its own statements and the rest belongs to one function literal inside it that branches (line 128). The decisions are inside the literal, which nothing outside this body can call, review or test on its own, so splitting the enclosing body is not the move available here. To reduce it, lift the literal\u0027s work into a named function or method at the enclosing scope and have the literal call it, then reduce whichever part then reads as the largest."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/skills/s_browser-agent/browser-agent.mjs"},"region":{"startLine":127}}}],"partialFingerprints":{"codehealthFindingId/v1":"64cbacfe2a63234b246424137ef2273d21e925e1cba1d37a1357f8925bb38d69"}},{"ruleId":"D2","level":"warning","message":{"text":"BackendStartupOverlay.BackendStartupOverlay (cognitive 74): BackendStartupOverlay.BackendStartupOverlay has cognitive complexity 74 (threshold 15). Drivers by points: if/else 42 (52 pts), boolean chains 13, ternaries 4 (6 pts), error handling 3 (nesting depth added 12). Most of this is not in the body itself: 9 of the 74 points are its own statements and the rest belongs to 14 function literals inside it that branch (lines 438, 403, 528, \u2026). The decisions are inside those literals, which nothing outside this body can call, review or test on its own, so splitting the enclosing body is not the move available here. To reduce it, lift the literals\u0027 work into a named function or method at the enclosing scope and have each literal call it, then reduce whichever part then reads as the largest."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/common/BackendStartupOverlay.tsx"},"region":{"startLine":241}}}],"partialFingerprints":{"codehealthFindingId/v1":"9be630d4217e102e7d65bf57282fd024640b8a3c7a2a047ecd30b2978d35cdbf"}},{"ruleId":"D2","level":"warning","message":{"text":"DddCultivationOrchestrator._auto_apply_ddd_proposals (cognitive 72): DddCultivationOrchestrator._auto_apply_ddd_proposals has cognitive complexity 72 (threshold 15). Drivers by points: if/else 15 (44 pts), loops 6 (16 pts), error handling 3 (8 pts), boolean chains 4 (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":"backend/core/ddd_orchestrator.py"},"region":{"startLine":582}}}],"partialFingerprints":{"codehealthFindingId/v1":"f1ded92f4041f312c1e21c7c104b1ec7e1c64d9a80dc1516434bb10d20ec6ef7"}},{"ruleId":"D2","level":"warning","message":{"text":"confidence_score.calculate_score (cognitive 72): confidence_score.calculate_score has cognitive complexity 72 (threshold 15). Drivers by points: if/else 33 (42 pts), boolean chains 23, ternaries 6 (7 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."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/skills/s_autonomous-pipeline/scripts/confidence_score.py"},"region":{"startLine":71}}}],"partialFingerprints":{"codehealthFindingId/v1":"a3dab15cb15a8e03fb4167f49eead81db293f2fc552f69b525d5d2e6bd48cac3"}},{"ruleId":"D2","level":"warning","message":{"text":"chat.sse_with_heartbeat (cognitive 70): chat.sse_with_heartbeat has cognitive complexity 70 (threshold 15). Drivers by points: if/else 12 (38 pts), error handling 7 (22 pts), loops 2 (5 pts), ternaries 1 (3 pts), boolean chains 2 (nesting depth added 46). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/routers/chat.py"},"region":{"startLine":336}}}],"partialFingerprints":{"codehealthFindingId/v1":"103063096cd27bd5beca6a93e080ceccba1417515c8f7f5df12d644d00854028"}},{"ruleId":"D2","level":"warning","message":{"text":"executor._format_briefing_slack_message (cognitive 69): executor._format_briefing_slack_message has cognitive complexity 69 (threshold 15). Drivers by points: if/else 16 (27 pts), ternaries 6 (22 pts), loops 7 (18 pts), boolean chains 1, error handling 1 (nesting depth added 38). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/jobs/executor.py"},"region":{"startLine":1357}}}],"partialFingerprints":{"codehealthFindingId/v1":"aed6625b0e2acc88f690c992850b91a945b1fabb9000346f7633d054cf6b44f6"}},{"ruleId":"D2","level":"warning","message":{"text":"memory_health._apply_report (cognitive 69): memory_health._apply_report has cognitive complexity 69 (threshold 15). Drivers by points: if/else 21 (49 pts), loops 7 (13 pts), error handling 1 (4 pts), boolean chains 3 (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":"backend/jobs/handlers/memory_health.py"},"region":{"startLine":493}}}],"partialFingerprints":{"codehealthFindingId/v1":"2b3160082802eda48b27bc6d57fcd3e307c5b93837ad17113ec2a84a13276bb5"}},{"ruleId":"D2","level":"warning","message":{"text":"pollinate_validator.validate_delivery (cognitive 69): pollinate_validator.validate_delivery has cognitive complexity 69 (threshold 15). Drivers by points: if/else 32 (50 pts), loops 5 (9 pts), boolean chains 5, error handling 2 (5 pts) (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":"backend/skills/s_pollinate/scripts/pollinate_validator.py"},"region":{"startLine":182}}}],"partialFingerprints":{"codehealthFindingId/v1":"64bd8deb00418c882939b1b87fb79919a73493e2142316f6e59ffada934826ea"}},{"ruleId":"D2","level":"warning","message":{"text":"ContextHealthHook._auto_cultivate_pipeline_lessons (cognitive 68): ContextHealthHook._auto_cultivate_pipeline_lessons has cognitive complexity 68 (threshold 15). Drivers by points: if/else 18 (45 pts), error handling 3 (10 pts), loops 4 (9 pts), ternaries 2 (4 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":"backend/hooks/context_health_hook.py"},"region":{"startLine":788}}}],"partialFingerprints":{"codehealthFindingId/v1":"a56ac2cc7003952195042aa0b2e0a74d7a0c2b92705f94ee89f935b4bff36997"}},{"ruleId":"D2","level":"warning","message":{"text":"ContextHealthHook._track_memory_usage_locked (cognitive 68): ContextHealthHook._track_memory_usage_locked has cognitive complexity 68 (threshold 15). Drivers by points: if/else 15 (31 pts), error handling 8 (23 pts), loops 5 (13 pts), boolean chains 1 (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":"backend/hooks/context_health_hook.py"},"region":{"startLine":1593}}}],"partialFingerprints":{"codehealthFindingId/v1":"2603a0d350a67e29e6de230c799213325c3ff0cee3fe0c4f3b2ea7c9496bfb88"}},{"ruleId":"D2","level":"warning","message":{"text":"artifact_cli.cmd_publish (cognitive 68): artifact_cli.cmd_publish has cognitive complexity 68 (threshold 15). Drivers by points: if/else 23 (45 pts), error handling 8 (17 pts), boolean chains 6 (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":"backend/scripts/artifact_cli.py"},"region":{"startLine":337}}}],"partialFingerprints":{"codehealthFindingId/v1":"a3b6343a726193f7a2781f32e17d97f0f337c2f285898a488f5594a9585d37f9"}},{"ruleId":"D2","level":"warning","message":{"text":"ai_ready_helpers.select_verification_tasks (cognitive 68): ai_ready_helpers.select_verification_tasks has cognitive complexity 68 (threshold 15). Drivers by points: if/else 21 (52 pts), boolean chains 9, loops 5 (6 pts), error handling 1 (nesting depth added 32). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py"},"region":{"startLine":2905}}}],"partialFingerprints":{"codehealthFindingId/v1":"af6066a5a2bd066d7377bd5d35fb60e4b1cdd857ae709ed4ceb0fe0ea293b94a"}},{"ruleId":"D2","level":"warning","message":{"text":"ddd_entry_lifecycle.inject_entry_metadata (cognitive 66): ddd_entry_lifecycle.inject_entry_metadata has cognitive complexity 66 (threshold 15). Drivers by points: if/else 15 (45 pts), loops 5 (13 pts), boolean chains 8 (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":"backend/core/ddd_entry_lifecycle.py"},"region":{"startLine":642}}}],"partialFingerprints":{"codehealthFindingId/v1":"c22a74684430d9930e193daa3c0f7c3fc4d08d59b9865a7481a82c7dd2210cc8"}},{"ruleId":"D2","level":"warning","message":{"text":"MessageStore._applyMerge (cognitive 66): MessageStore._applyMerge has cognitive complexity 66 (threshold 15). Drivers by points: if/else 16 (45 pts), loops 5 (10 pts), boolean chains 9, ternaries 1 (2 pts) (nesting depth added 35). Of this number, 63 points are the body\u0027s own statements and 3 belong to 2 function literals inside it that branch. 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":"desktop/src/stores/MessageStore.ts"},"region":{"startLine":892}}}],"partialFingerprints":{"codehealthFindingId/v1":"4f66ca2d1d407ba9c5f64a1bd958228305aa8e70df7f10d4dc9caf704e235ca6"}},{"ruleId":"D2","level":"warning","message":{"text":"BaseSchemaValidator.validate_unique_ids (cognitive 65): BaseSchemaValidator.validate_unique_ids has cognitive complexity 65 (threshold 15). Drivers by points: if/else 13 (44 pts), loops 5 (11 pts), ternaries 2 (8 pts), error handling 1 (2 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":"backend/skills/s_pptx/ooxml/scripts/validation/base.py"},"region":{"startLine":186}}}],"partialFingerprints":{"codehealthFindingId/v1":"2c95bc02b95a4145a7266085fd39a47da4c008927d603e91bae2d6b6c9d92ecc"}},{"ruleId":"D2","level":"warning","message":{"text":"DddCultivationOrchestrator._ch_entry_lifecycle (cognitive 64): DddCultivationOrchestrator._ch_entry_lifecycle has cognitive complexity 64 (threshold 15). Drivers by points: if/else 16 (43 pts), loops 3 (9 pts), error handling 2 (5 pts), ternaries 1 (5 pts), boolean chains 2 (nesting depth added 40). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/core/ddd_orchestrator.py"},"region":{"startLine":815}}}],"partialFingerprints":{"codehealthFindingId/v1":"eceb15e808449762d484366e101909076538196a4eba40a6d772bef1f63692e2"}},{"ruleId":"D2","level":"warning","message":{"text":"chat.consumeSSEStream (cognitive 63): chat.consumeSSEStream has cognitive complexity 63 (threshold 15). Drivers by points: if/else 10 (34 pts), error handling 4 (21 pts), loops 3 (7 pts), boolean chains 1 (nesting depth added 45). To reduce it, flatten the nesting: this score is depth rather than breadth \u2014 most of its points come from checks stacked inside one another, so the work sits several levels in. Invert each enclosing check into an early exit (a return, or the language\u0027s equivalent) so the happy path stays at one level, and where a level cannot be exited early, lift the block it encloses into its own named function."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/services/chat.ts"},"region":{"startLine":267}}}],"partialFingerprints":{"codehealthFindingId/v1":"d7b4fffc6ccdde036aac55adda4251b315670362838b242f61295eef7c956ceb"}},{"ruleId":"D2","level":"warning","message":{"text":"AuthConfigPanel.AuthConfigPanel (cognitive 63): AuthConfigPanel.AuthConfigPanel has cognitive complexity 63 (threshold 15). Drivers by points: boolean chains 29, if/else 19 (27 pts), ternaries 6, error handling 1 (nesting depth added 8). Of this number, 22 points are the body\u0027s own statements and 41 belong to 8 function literals inside it that branch. 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":"desktop/src/components/settings/AuthConfigPanel.tsx"},"region":{"startLine":29}}}],"partialFingerprints":{"codehealthFindingId/v1":"f08a884bf6d0ac514ab8c862253c60ce2fedb6af7211d5b5bfa1a3d36935e6bf"}},{"ruleId":"D2","level":"warning","message":{"text":"BaseSchemaValidator.validate_unique_ids (cognitive 62): BaseSchemaValidator.validate_unique_ids has cognitive complexity 62 (threshold 15). Drivers by points: if/else 12 (41 pts), loops 5 (11 pts), ternaries 2 (8 pts), error handling 1 (2 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":"backend/skills/s_docx/ooxml/scripts/validation/base.py"},"region":{"startLine":186}}}],"partialFingerprints":{"codehealthFindingId/v1":"af665f4d4b9493f13f93f07c4483421826d672be09399788fd0dfa83c2079298"}},{"ruleId":"D2","level":"warning","message":{"text":"json_exporter.export_code_intel_json (cognitive 61): json_exporter.export_code_intel_json has cognitive complexity 61 (threshold 15). Drivers by points: if/else 18 (30 pts), error handling 8 (12 pts), loops 3 (9 pts), ternaries 5 (6 pts), boolean chains 4 (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":"backend/core/code_intel/json_exporter.py"},"region":{"startLine":36}}}],"partialFingerprints":{"codehealthFindingId/v1":"8d9d6aa8a04f8dc2d209de6f7d6ecbee09cba6b453aca7426d71c18ed3d697b7"}},{"ruleId":"D2","level":"warning","message":{"text":"main.lifespan (cognitive 61): main.lifespan has cognitive complexity 61 (threshold 15). Drivers by points: if/else 27 (32 pts), error handling 17 (23 pts), boolean chains 5, loops 1 (nesting depth added 11). 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":"backend/main.py"},"region":{"startLine":938}}}],"partialFingerprints":{"codehealthFindingId/v1":"84948ceb0c864ef71a61bf7ae81c101bd6659b2f9eaf5fa4cda284b7617b19f3"}},{"ruleId":"D2","level":"warning","message":{"text":"pipeline_analytics._load_all_metrics (cognitive 61): pipeline_analytics._load_all_metrics has cognitive complexity 61 (threshold 15). Drivers by points: if/else 12 (35 pts), error handling 4 (17 pts), ternaries 2 (5 pts), loops 2 (3 pts), boolean chains 1 (nesting depth added 40). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/scripts/pipeline_analytics.py"},"region":{"startLine":64}}}],"partialFingerprints":{"codehealthFindingId/v1":"b4f6707e1391f3408d33a5599296daf3a441ccac2d22248ab16401835a82618a"}},{"ruleId":"D2","level":"warning","message":{"text":"sections.match_section_times (cognitive 61): sections.match_section_times has cognitive complexity 61 (threshold 15). Drivers by points: if/else 14 (37 pts), loops 8 (20 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":"backend/skills/s_pollinate/scripts/tts/sections.py"},"region":{"startLine":86}}}],"partialFingerprints":{"codehealthFindingId/v1":"b6f18f7533b7a3c0a0a6c1296763728e062f41fe61d07c94355a3bb15503544e"}},{"ruleId":"D2","level":"warning","message":{"text":"ContextDirectoryLoader.ensure_directory (cognitive 60): ContextDirectoryLoader.ensure_directory has cognitive complexity 60 (threshold 15). Drivers by points: if/else 16 (34 pts), error handling 7 (19 pts), boolean chains 4, loops 3 (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":"backend/core/context_directory_loader.py"},"region":{"startLine":543}}}],"partialFingerprints":{"codehealthFindingId/v1":"9cd2814d20bf3d2a532c3b3a0f2a86b9ea7f5278ec80067326e7836098e36cbf"}},{"ruleId":"D2","level":"warning","message":{"text":"ProjectionLayer.project_skills (cognitive 60): ProjectionLayer.project_skills has cognitive complexity 60 (threshold 15). Drivers by points: if/else 20 (38 pts), error handling 5 (12 pts), boolean chains 4, loops 3 (4 pts), ternaries 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":"backend/core/projection_layer.py"},"region":{"startLine":227}}}],"partialFingerprints":{"codehealthFindingId/v1":"fdbf43a2ee83d850fa72f0b4f5df361804772d58a98cbe80a4aa5933408ff333"}},{"ruleId":"D2","level":"warning","message":{"text":"AgentFormModal.AgentFormModal (cognitive 59): AgentFormModal.AgentFormModal has cognitive complexity 59 (threshold 15). Drivers by points: ternaries 20 (25 pts), boolean chains 23, if/else 9 (10 pts), error handling 1 (nesting depth added 6). Of this number, 27 points are the body\u0027s own statements and 32 belong to 7 function literals inside it that branch. 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":"desktop/src/components/common/AgentFormModal.tsx"},"region":{"startLine":36}}}],"partialFingerprints":{"codehealthFindingId/v1":"534bf6642371eb8b9496e4a06280375eee15c1a8cd61f6e2467c3431c8ee95ed"}},{"ruleId":"D2","level":"warning","message":{"text":"artifact_cli.cmd_run_commit (cognitive 58): artifact_cli.cmd_run_commit has cognitive complexity 58 (threshold 15). Drivers by points: if/else 22 (40 pts), loops 5 (9 pts), boolean chains 5, error handling 2 (4 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":"backend/scripts/artifact_cli.py"},"region":{"startLine":2920}}}],"partialFingerprints":{"codehealthFindingId/v1":"fa6a4888ae8b2970780f8c0a8c743c00b6c9d3317d5db0d3dbfe0b3620831bcc"}},{"ruleId":"D2","level":"warning","message":{"text":"useUnifiedAttachments.useUnifiedAttachments (cognitive 58): useUnifiedAttachments.useUnifiedAttachments has cognitive complexity 58 (threshold 15). Drivers by points: if/else 26 (36 pts), error handling 3 (9 pts), ternaries 3 (7 pts), boolean chains 4, loops 2 (nesting depth added 20). Most of this is not in the body itself: 0 of the 58 points are its own statements and the rest belongs to 9 function literals inside it that branch (lines 173, 307, 146, \u2026). The decisions are inside those literals, which nothing outside this body can call, review or test on its own, so splitting the enclosing body is not the move available here. To reduce it, lift the literals\u0027 work into a named function or method at the enclosing scope and have each literal call it, then reduce whichever part then reads as the largest."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/hooks/useUnifiedAttachments.ts"},"region":{"startLine":117}}}],"partialFingerprints":{"codehealthFindingId/v1":"3836f51a651abfb493898847c0baff7ba5ada4d32ec1829397bb69a65891f7b0"}},{"ruleId":"D2","level":"warning","message":{"text":"memory_health._compress_evolution_entries (cognitive 57): memory_health._compress_evolution_entries has cognitive complexity 57 (threshold 15). Drivers by points: if/else 21 (40 pts), boolean chains 10, loops 5 (6 pts), error handling 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":"backend/jobs/handlers/memory_health.py"},"region":{"startLine":614}}}],"partialFingerprints":{"codehealthFindingId/v1":"f339d4fa5e89692915bf01a05d1f029644080d5481ce21928c6908fd31afc7e6"}},{"ruleId":"D2","level":"warning","message":{"text":"recalc.recalc (cognitive 57): recalc.recalc has cognitive complexity 57 (threshold 15). Drivers by points: if/else 12 (27 pts), loops 8 (18 pts), boolean chains 5, error handling 2 (4 pts), ternaries 2 (3 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":"backend/skills/s_xlsx/recalc.py"},"region":{"startLine":53}}}],"partialFingerprints":{"codehealthFindingId/v1":"e04bce39ed1aeca0cb82206d821c0d2a4cc0a2fd01837fb332cf2225125084ae"}},{"ruleId":"D2","level":"warning","message":{"text":"context_injector._extract_key_tool_results (cognitive 56): context_injector._extract_key_tool_results has cognitive complexity 56 (threshold 15). Drivers by points: if/else 15 (45 pts), boolean chains 7, loops 2 (3 pts), error handling 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":"backend/core/context_injector.py"},"region":{"startLine":654}}}],"partialFingerprints":{"codehealthFindingId/v1":"5a1b9cd6d93366e5931c3a3b2d14eeecb304c27c21841e241b7ce1dd2272395f"}},{"ruleId":"D2","level":"warning","message":{"text":"DistillationTriggerHook._apply_open_thread_updates (cognitive 56): DistillationTriggerHook._apply_open_thread_updates has cognitive complexity 56 (threshold 15). Drivers by points: if/else 13 (42 pts), loops 5 (11 pts), boolean chains 3 (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":"backend/hooks/distillation_hook.py"},"region":{"startLine":1964}}}],"partialFingerprints":{"codehealthFindingId/v1":"d4ec11d49c6658ed67be5901ff5f3a9f54e5fb3f7d18e390f22a1556b56203c2"}},{"ruleId":"D2","level":"warning","message":{"text":"ParagraphData.__init__ (cognitive 56): ParagraphData.__init__ has cognitive complexity 56 (threshold 15). Drivers by points: if/else 19 (40 pts), error handling 2 (7 pts), boolean chains 6, ternaries 1 (3 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":"backend/skills/s_pptx/scripts/inventory.py"},"region":{"startLine":140}}}],"partialFingerprints":{"codehealthFindingId/v1":"6b344f48c138b859fe2d992279f971fbe7edbb1f42e8dbd01f893bcf76dfdedf"}},{"ruleId":"D2","level":"warning","message":{"text":"html2pptx.addElements (cognitive 56): html2pptx.addElements has cognitive complexity 56 (threshold 15). Drivers by points: if/else 19 (46 pts), ternaries 2 (6 pts), boolean chains 3, loops 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":"backend/skills/s_pptx/scripts/html2pptx.js"},"region":{"startLine":133}}}],"partialFingerprints":{"codehealthFindingId/v1":"7777fc0aed970fed8f71f1f0d6f3e9094d65cfca5eba834d7f8a95d5506c9762"}},{"ruleId":"D2","level":"warning","message":{"text":"file_change_classifier.parse_bash_delete_targets (cognitive 55): file_change_classifier.parse_bash_delete_targets has cognitive complexity 55 (threshold 15). Drivers by points: if/else 16 (44 pts), boolean chains 5, loops 3 (5 pts), error handling 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":"backend/core/file_change_classifier.py"},"region":{"startLine":122}}}],"partialFingerprints":{"codehealthFindingId/v1":"f24fcbf6eef98940fbee1161cf16ffe53ca91ff68dd1d9a47fe1cd295430e2a3"}},{"ruleId":"D2","level":"warning","message":{"text":"PluginManager.install_plugin (cognitive 55): PluginManager.install_plugin has cognitive complexity 55 (threshold 15). Drivers by points: if/else 19 (36 pts), loops 7 (12 pts), ternaries 2 (4 pts), error handling 2 (3 pts) (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":"backend/core/plugin_manager.py"},"region":{"startLine":696}}}],"partialFingerprints":{"codehealthFindingId/v1":"c09db95171ff31cd2eaa216e6721689b586b459c2895f53e457f28817fd0ecd5"}},{"ruleId":"D2","level":"warning","message":{"text":"ui_actions.build_surface_events (cognitive 55): ui_actions.build_surface_events has cognitive complexity 55 (threshold 15). Drivers by points: if/else 13 (24 pts), ternaries 4 (10 pts), boolean chains 9, error handling 3 (6 pts), loops 4 (6 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":"backend/core/ui_actions.py"},"region":{"startLine":287}}}],"partialFingerprints":{"codehealthFindingId/v1":"7d24e3f10d924f5b011798ac2aab2aad7fb88e2acd43428c941c93e6d84d6610"}},{"ruleId":"D2","level":"warning","message":{"text":"pipelines.pipeline_analytics (cognitive 55): pipelines.pipeline_analytics has cognitive complexity 55 (threshold 15). Drivers by points: if/else 14 (29 pts), boolean chains 12, ternaries 5 (10 pts), loops 3 (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":"backend/routers/pipelines.py"},"region":{"startLine":444}}}],"partialFingerprints":{"codehealthFindingId/v1":"08581dd6955c3b53c41c888cc8284b46480d6486fb7fe2b8c6ae8bd8691e94eb"}},{"ruleId":"D2","level":"warning","message":{"text":"artifact_cli.cmd_run_observe (cognitive 55): artifact_cli.cmd_run_observe has cognitive complexity 55 (threshold 15). Drivers by points: ternaries 19 (38 pts), if/else 5 (7 pts), boolean chains 5, error handling 2 (5 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":"backend/scripts/artifact_cli.py"},"region":{"startLine":5539}}}],"partialFingerprints":{"codehealthFindingId/v1":"682d20224ef8f47b28148b634f0059432553ba31956e63c2718efff259bf8219"}},{"ruleId":"D2","level":"warning","message":{"text":"BaseSchemaValidator.validate_all_relationship_ids (cognitive 55): BaseSchemaValidator.validate_all_relationship_ids has cognitive complexity 55 (threshold 15). Drivers by points: if/else 11 (33 pts), ternaries 3 (13 pts), loops 4 (7 pts), error handling 1 (2 pts) (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":"backend/skills/s_docx/ooxml/scripts/validation/base.py"},"region":{"startLine":388}}}],"partialFingerprints":{"codehealthFindingId/v1":"e24fe8ffd338afc80cf128e181622ea2e8160036ebf2b663295db1f279f89e46"}},{"ruleId":"D2","level":"warning","message":{"text":"BaseSchemaValidator.validate_all_relationship_ids (cognitive 55): BaseSchemaValidator.validate_all_relationship_ids has cognitive complexity 55 (threshold 15). Drivers by points: if/else 11 (33 pts), ternaries 3 (13 pts), loops 4 (7 pts), error handling 1 (2 pts) (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":"backend/skills/s_pptx/ooxml/scripts/validation/base.py"},"region":{"startLine":391}}}],"partialFingerprints":{"codehealthFindingId/v1":"2925b40f686a58e14ceaf22dec579d0b4540d6e416c711bf3d170052b8b0a4d4"}},{"ruleId":"D2","level":"warning","message":{"text":"CsvRenderer.CsvRenderer (cognitive 55): CsvRenderer.CsvRenderer has cognitive complexity 55 (threshold 15). Drivers by points: ternaries 16 (23 pts), if/else 18, boolean chains 12, error handling 1, loops 1 (nesting depth added 7). Most of this is not in the body itself: 15 of the 55 points are its own statements and the rest belongs to 13 function literals inside it that branch (lines 91, 114, 60, \u2026). The decisions are inside those literals, which nothing outside this body can call, review or test on its own, so splitting the enclosing body is not the move available here. To reduce it, lift the literals\u0027 work into a named function or method at the enclosing scope and have each literal call it, then reduce whichever part then reads as the largest."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/file-viewer/renderers/CsvRenderer.tsx"},"region":{"startLine":48}}}],"partialFingerprints":{"codehealthFindingId/v1":"9bbeb6d60e8fa63f9c3c302de4a4c6f2a1430df596a73ffa2d2c03e1072e229e"}},{"ruleId":"D2","level":"warning","message":{"text":"DistillationTriggerHook._enforce_size_valve (cognitive 54): DistillationTriggerHook._enforce_size_valve has cognitive complexity 54 (threshold 15). Drivers by points: if/else 14 (27 pts), loops 6 (12 pts), error handling 2 (6 pts), ternaries 1 (5 pts), boolean chains 4 (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":"backend/hooks/distillation_hook.py"},"region":{"startLine":2571}}}],"partialFingerprints":{"codehealthFindingId/v1":"809283d3cf72053caf38b2565f997f2f87c2d11ff8cf4b9759de5d2e70ac7fa1"}},{"ruleId":"D2","level":"warning","message":{"text":"useVoiceRecorder.useVoiceRecorder (cognitive 54): useVoiceRecorder.useVoiceRecorder has cognitive complexity 54 (threshold 15). Drivers by points: if/else 26 (29 pts), boolean chains 10, ternaries 4 (8 pts), error handling 5 (7 pts) (nesting depth added 9). Most of this is not in the body itself: 1 of the 54 points is its own statement and the rest belongs to 8 function literals inside it that branch (lines 245, 99, 78, \u2026). The decisions are inside those literals, which nothing outside this body can call, review or test on its own, so splitting the enclosing body is not the move available here. To reduce it, lift the literals\u0027 work into a named function or method at the enclosing scope and have each literal call it, then reduce whichever part then reads as the largest."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/hooks/useVoiceRecorder.ts"},"region":{"startLine":48}}}],"partialFingerprints":{"codehealthFindingId/v1":"03975ae8a09b6397cdf19cf4d84941a6dde65e8c4b59b7b22eb81abc483730f7"}},{"ruleId":"D2","level":"warning","message":{"text":"compressDOM::(anonymous)::compress (cognitive 54): compressDOM::(anonymous)::compress has cognitive complexity 54 (threshold 15). Drivers by points: if/else 19 (38 pts), boolean chains 8, ternaries 2 (4 pts), loops 2 (3 pts), error handling 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":"backend/skills/s_browser-agent/browser-agent.mjs"},"region":{"startLine":199}}}],"partialFingerprints":{"codehealthFindingId/v1":"61ec1bcd8302dceb5b0e85f7ed111f707c3f1b9fa3de21912d442f944772f1a7"}},{"ruleId":"D2","level":"warning","message":{"text":"clustering.compute_graph_clusters (cognitive 53): clustering.compute_graph_clusters has cognitive complexity 53 (threshold 15). Drivers by points: if/else 16 (30 pts), loops 9 (15 pts), ternaries 3 (4 pts), boolean chains 2, error handling 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":"backend/core/code_intel/clustering.py"},"region":{"startLine":75}}}],"partialFingerprints":{"codehealthFindingId/v1":"a37d818effec97962417f1192c79722e668f83844c2be3b618c03952e2214390"}},{"ruleId":"D2","level":"warning","message":{"text":"style-extract.extract_fonts (cognitive 53): style-extract.extract_fonts has cognitive complexity 53 (threshold 15). Drivers by points: if/else 8 (30 pts), ternaries 3 (12 pts), loops 3 (9 pts), boolean chains 2 (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":"backend/skills/s_pptx/scripts/style-extract.py"},"region":{"startLine":53}}}],"partialFingerprints":{"codehealthFindingId/v1":"dbf800bde649ce5fe259757c334f8f3fee7e474215f8e7c875386152de975bb9"}},{"ruleId":"D2","level":"warning","message":{"text":"parser.parse_repo_with_coverage (cognitive 52): parser.parse_repo_with_coverage has cognitive complexity 52 (threshold 15). Drivers by points: if/else 20 (34 pts), loops 6 (11 pts), boolean chains 3, error handling 1 (3 pts), ternaries 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":"backend/core/code_intel/parser.py"},"region":{"startLine":1952}}}],"partialFingerprints":{"codehealthFindingId/v1":"910cedbcfdaaf2751837b491fec822c212e17727480ae5b3834da7cdb5c38af1"}},{"ruleId":"D2","level":"warning","message":{"text":"PromptBuilder.build_options (cognitive 52): PromptBuilder.build_options has cognitive complexity 52 (threshold 15). Drivers by points: if/else 23 (34 pts), boolean chains 10, error handling 2 (4 pts), ternaries 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":"backend/core/prompt_builder.py"},"region":{"startLine":1775}}}],"partialFingerprints":{"codehealthFindingId/v1":"5bc70f1b3ec19d1bc53f0bacdd2df91899e8b80cc77d8ec67e8a7c16ec64254f"}},{"ruleId":"D2","level":"warning","message":{"text":"recall_multi._recall_ddd (cognitive 52): recall_multi._recall_ddd has cognitive complexity 52 (threshold 15). Drivers by points: if/else 14 (24 pts), loops 7 (13 pts), error handling 3 (8 pts), boolean chains 4, ternaries 1 (3 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":"backend/core/recall_multi.py"},"region":{"startLine":701}}}],"partialFingerprints":{"codehealthFindingId/v1":"ec42737ed82163710adfa7ca03408ed4472402ef95be65e584d9516d9e4f4b91"}},{"ruleId":"D2","level":"warning","message":{"text":"pollinate._walk_assets (cognitive 52): pollinate._walk_assets has cognitive complexity 52 (threshold 15). Drivers by points: if/else 11 (23 pts), loops 6 (18 pts), ternaries 2 (10 pts), boolean chains 1 (nesting depth added 32). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/routers/pollinate.py"},"region":{"startLine":327}}}],"partialFingerprints":{"codehealthFindingId/v1":"a8631909b94ffa504eec095723f08aad169f97355d750f4976a4071f86c3592b"}},{"ruleId":"D2","level":"warning","message":{"text":"SelfLoopsHealthEngine.to_markdown (cognitive 52): SelfLoopsHealthEngine.to_markdown has cognitive complexity 52 (threshold 15). Drivers by points: if/else 14 (21 pts), ternaries 12 (19 pts), loops 4 (8 pts), boolean chains 2, error handling 1 (2 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":"backend/skills/s_loops-health/scripts/loops_health_check.py"},"region":{"startLine":1228}}}],"partialFingerprints":{"codehealthFindingId/v1":"8e23057546c9c2b635963d07d175c8bac2ddeee68d00a95a85c8f236ee609bfe"}},{"ruleId":"D2","level":"warning","message":{"text":"replace.apply_replacements (cognitive 52): replace.apply_replacements has cognitive complexity 52 (threshold 15). Drivers by points: if/else 12 (27 pts), loops 11 (24 pts), boolean chains 1 (nesting depth added 28). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/skills/s_pptx/scripts/replace.py"},"region":{"startLine":214}}}],"partialFingerprints":{"codehealthFindingId/v1":"ad59aaeba2d8dd036c3c06094ee65c78e7297d0a237571478c6915815717946f"}},{"ruleId":"D2","level":"warning","message":{"text":"ToDoOverlay.TodoForm (cognitive 52): ToDoOverlay.TodoForm has cognitive complexity 52 (threshold 15). Drivers by points: ternaries 11 (19 pts), if/else 11 (13 pts), boolean chains 9, error handling 4 (7 pts), loops 2 (4 pts) (nesting depth added 15). Most of this is not in the body itself: 11 of the 52 points are its own statements and the rest belongs to 6 function literals inside it that branch (lines 1057, 1022, 1014, \u2026). The decisions are inside those literals, which nothing outside this body can call, review or test on its own, so splitting the enclosing body is not the move available here. To reduce it, lift the literals\u0027 work into a named function or method at the enclosing scope and have each literal call it, then reduce whichever part then reads as the largest."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/layout/ToDoOverlay.tsx"},"region":{"startLine":993}}}],"partialFingerprints":{"codehealthFindingId/v1":"474eeb51c65d4d03b1e98f498092e22a1e1623194f843dbeaed674acece35348"}},{"ruleId":"D2","level":"warning","message":{"text":"PluginManager._install_from_marketplace_json (cognitive 51): PluginManager._install_from_marketplace_json has cognitive complexity 51 (threshold 15). Drivers by points: if/else 19 (34 pts), boolean chains 6, loops 3 (6 pts), error handling 2 (4 pts), ternaries 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":"backend/core/plugin_manager.py"},"region":{"startLine":522}}}],"partialFingerprints":{"codehealthFindingId/v1":"da181e072b23ed98fad5ddfcd9750fb57f7cf335baa1f34f042602e439c91046"}},{"ruleId":"D2","level":"warning","message":{"text":"DddCultivationOrchestrator._ch_ddd_staleness (cognitive 50): DddCultivationOrchestrator._ch_ddd_staleness has cognitive complexity 50 (threshold 15). Drivers by points: if/else 11 (27 pts), ternaries 3 (9 pts), loops 3 (6 pts), boolean chains 4, error handling 2 (4 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":"backend/core/ddd_orchestrator.py"},"region":{"startLine":444}}}],"partialFingerprints":{"codehealthFindingId/v1":"25d3cb9b1a73c4da34d6eb364a42756f8ee79a5fee657637cc730513b3105363"}},{"ruleId":"D2","level":"warning","message":{"text":"ai_ready_helpers.validate_code_intel_json (cognitive 50): ai_ready_helpers.validate_code_intel_json has cognitive complexity 50 (threshold 15). Drivers by points: if/else 15 (29 pts), loops 7 (13 pts), boolean chains 8 (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":"backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py"},"region":{"startLine":113}}}],"partialFingerprints":{"codehealthFindingId/v1":"eef5e313437e1159c38c9636e24cea5d89aee3e45afe8af8fae63001972a1419"}},{"ruleId":"D2","level":"warning","message":{"text":"ai_ready_helpers.validate_code_intel_json (cognitive 50): ai_ready_helpers.validate_code_intel_json has cognitive complexity 50 (threshold 15). Drivers by points: if/else 15 (29 pts), loops 7 (13 pts), boolean chains 8 (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":"backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py"},"region":{"startLine":113}}}],"partialFingerprints":{"codehealthFindingId/v1":"d6e0b796913cdea679f76041e62b34856accc47549b89157fccf191659db3f6f"}},{"ruleId":"D2","level":"warning","message":{"text":"Video.SectionComponent (cognitive 50): Video.SectionComponent has cognitive complexity 50 (threshold 15). Drivers by points: ternaries 25 (49 pts), match/switch 1 (nesting depth added 24). Of this number, 46 points are the body\u0027s own statements and 4 belong to one function literal inside it that branches. To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/skills/s_pollinate/templates/remotion/Video.tsx"},"region":{"startLine":43}}}],"partialFingerprints":{"codehealthFindingId/v1":"2b821a8b5bf988dddeb2204419d03d0502f5a9e50f97246a7a1a5d6a7f337381"}},{"ruleId":"D2","level":"warning","message":{"text":"useUnifiedTabState.useUnifiedTabState (cognitive 50): useUnifiedTabState.useUnifiedTabState has cognitive complexity 50 (threshold 15). Drivers by points: if/else 31 (33 pts), boolean chains 5, error handling 3 (5 pts), loops 4, ternaries 3 (nesting depth added 4). Most of this is not in the body itself: 1 of the 50 points is its own statement and the rest belongs to 19 function literals inside it that branch (lines 767, 559, 683, \u2026). The decisions are inside those literals, which nothing outside this body can call, review or test on its own, so splitting the enclosing body is not the move available here. To reduce it, lift the literals\u0027 work into a named function or method at the enclosing scope and have each literal call it, then reduce whichever part then reads as the largest."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/hooks/useUnifiedTabState.ts"},"region":{"startLine":419}}}],"partialFingerprints":{"codehealthFindingId/v1":"ca2b924ca9d33216eea67f5a5969d0929c15c3921700ab1c405aa20d7006a437"}},{"ruleId":"D2","level":"warning","message":{"text":"ChannelGateway.handle_inbound_message (cognitive 49): ChannelGateway.handle_inbound_message has cognitive complexity 49 (threshold 15). Drivers by points: if/else 20 (29 pts), error handling 4 (10 pts), boolean chains 8, ternaries 1 (2 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":"backend/channels/gateway.py"},"region":{"startLine":1248}}}],"partialFingerprints":{"codehealthFindingId/v1":"5b995c584edbd2b810b4f92b3c168b6e5cc35beae442080c04d12830c9ed458a"}},{"ruleId":"D2","level":"warning","message":{"text":"SQLiteDatabase._run_versioned_migrations (cognitive 49): SQLiteDatabase._run_versioned_migrations has cognitive complexity 49 (threshold 15). Drivers by points: if/else 18 (27 pts), error handling 8 (17 pts), ternaries 1 (3 pts), loops 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":"backend/database/sqlite.py"},"region":{"startLine":2386}}}],"partialFingerprints":{"codehealthFindingId/v1":"d0f7852f032ccb4d96462aecd7bf561151230485f6f4a2d3ca70e05c875d171f"}},{"ruleId":"D2","level":"warning","message":{"text":"pptx_to_deck.extract (cognitive 49): pptx_to_deck.extract has cognitive complexity 49 (threshold 15). Drivers by points: if/else 10 (28 pts), loops 5 (12 pts), boolean chains 6, ternaries 2 (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":"backend/skills/s_pollinate/scripts/pptx_to_deck.py"},"region":{"startLine":36}}}],"partialFingerprints":{"codehealthFindingId/v1":"9ca68165b83fd696978cae69a90dffee4aa0ca4b939388279657c59904eb5ec3"}},{"ruleId":"D2","level":"warning","message":{"text":"AskUserQuestion.AskUserQuestion (cognitive 49): AskUserQuestion.AskUserQuestion has cognitive complexity 49 (threshold 15). Drivers by points: ternaries 14 (21 pts), boolean chains 14, if/else 13 (14 pts) (nesting depth added 8). Most of this is not in the body itself: 6 of the 49 points are its own statements and the rest belongs to 9 function literals inside it that branch (lines 176, 163, 37, \u2026). The decisions are inside those literals, which nothing outside this body can call, review or test on its own, so splitting the enclosing body is not the move available here. To reduce it, lift the literals\u0027 work into a named function or method at the enclosing scope and have each literal call it, then reduce whichever part then reads as the largest."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/common/AskUserQuestion.tsx"},"region":{"startLine":19}}}],"partialFingerprints":{"codehealthFindingId/v1":"1035ac8c685c9161de00f0b955d2409c6fd6f8ebb974daf10ba462d29d4f696a"}},{"ruleId":"D2","level":"warning","message":{"text":"_ClaudeClientWrapper._extract_pid (cognitive 48): _ClaudeClientWrapper._extract_pid has cognitive complexity 48 (threshold 15). Drivers by points: if/else 18 (41 pts), error handling 2 (3 pts), loops 2 (3 pts), boolean chains 1 (nesting depth added 25). To reduce it, flatten the nesting: this score is depth rather than breadth \u2014 most of its points come from checks stacked inside one another, so the work sits several levels in. Invert each enclosing check into an early exit (a return, or the language\u0027s equivalent) so the happy path stays at one level, and where a level cannot be exited early, lift the block it encloses into its own named function."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/core/claude_environment.py"},"region":{"startLine":81}}}],"partialFingerprints":{"codehealthFindingId/v1":"31e52af88c04a72031630fba6d5830ad0a6fabe679d3c69045289f58d195bdb0"}},{"ruleId":"D2","level":"warning","message":{"text":"RetryManager._retry_with_resume (cognitive 48): RetryManager._retry_with_resume has cognitive complexity 48 (threshold 15). Drivers by points: if/else 15 (32 pts), error handling 4 (8 pts), boolean chains 5, 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":"backend/core/retry_manager.py"},"region":{"startLine":265}}}],"partialFingerprints":{"codehealthFindingId/v1":"ce916f054ac803035ad10dc8823f240b33ab52aef636448214de3733faf7024e"}},{"ruleId":"D2","level":"warning","message":{"text":"security_hooks._targets_irreplaceable_store (cognitive 48): security_hooks._targets_irreplaceable_store has cognitive complexity 48 (threshold 15). Drivers by points: if/else 19 (37 pts), boolean chains 6, loops 3 (4 pts), error handling 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":"backend/core/security_hooks.py"},"region":{"startLine":430}}}],"partialFingerprints":{"codehealthFindingId/v1":"af5f5d11753390f2897f36876370859bf1c8ea48335b52efd6d774dee2a6da2a"}},{"ruleId":"D2","level":"warning","message":{"text":"ddd_weekly_report._generate_report (cognitive 48): ddd_weekly_report._generate_report has cognitive complexity 48 (threshold 15). Drivers by points: if/else 23 (28 pts), loops 8 (13 pts), ternaries 2 (4 pts), boolean chains 3 (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":"backend/jobs/handlers/ddd_weekly_report.py"},"region":{"startLine":207}}}],"partialFingerprints":{"codehealthFindingId/v1":"8ddc3224c94530217c07af4a25efbe4f4e795977cfdfd1c1f4147e68fb4b6450"}},{"ruleId":"D2","level":"warning","message":{"text":"backfill_cjk_escapes.backfill (cognitive 48): backfill_cjk_escapes.backfill has cognitive complexity 48 (threshold 15). Drivers by points: if/else 16 (26 pts), loops 6 (9 pts), boolean chains 7, error handling 3 (6 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":"backend/scripts/backfill_cjk_escapes.py"},"region":{"startLine":576}}}],"partialFingerprints":{"codehealthFindingId/v1":"8608545a01fda5ec990f61e781e337c44fc120b846097f19e6526c1ff7df7478"}},{"ruleId":"D2","level":"warning","message":{"text":"VirtualizedTree.flattenTree (cognitive 48): VirtualizedTree.flattenTree has cognitive complexity 48 (threshold 15). Drivers by points: if/else 11 (24 pts), loops 10 (14 pts), boolean chains 10 (nesting depth added 17). Of this number, 47 points are the body\u0027s own statements and 1 belongs to one function literal inside it that branches. To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/workspace-explorer/VirtualizedTree.tsx"},"region":{"startLine":255}}}],"partialFingerprints":{"codehealthFindingId/v1":"ff63d6c5e221dc7fd1ba9b0ba96667ca404da247607723d00b5c590afd7dcbf1"}},{"ruleId":"D2","level":"warning","message":{"text":"proactive_learning.update_learning_from_activity (cognitive 47): proactive_learning.update_learning_from_activity has cognitive complexity 47 (threshold 15). Drivers by points: if/else 16 (35 pts), loops 2 (6 pts), error handling 1 (3 pts), ternaries 2, boolean chains 1 (nesting depth added 25). To reduce it, flatten the nesting: this score is depth rather than breadth \u2014 most of its points come from checks stacked inside one another, so the work sits several levels in. Invert each enclosing check into an early exit (a return, or the language\u0027s equivalent) so the happy path stays at one level, and where a level cannot be exited early, lift the block it encloses into its own named function."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/core/proactive_learning.py"},"region":{"startLine":431}}}],"partialFingerprints":{"codehealthFindingId/v1":"453d8c8f6efb07006b3aea773372a2757d8f1b34ee9d85cae2fb9f9cf632cd23"}},{"ruleId":"D2","level":"warning","message":{"text":"SessionUnit._pid_watchdog_loop (cognitive 47): SessionUnit._pid_watchdog_loop has cognitive complexity 47 (threshold 15). Drivers by points: if/else 9 (38 pts), error handling 3 (5 pts), boolean chains 3, loops 1 (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":"backend/core/session_unit.py"},"region":{"startLine":1288}}}],"partialFingerprints":{"codehealthFindingId/v1":"89889883fbc3afea0ed350707a63f05463cdceceed3007a60e8fd97d8cbfab25"}},{"ruleId":"D2","level":"warning","message":{"text":"ai_ready_helpers.compute_subsystem_coverage (cognitive 47): ai_ready_helpers.compute_subsystem_coverage has cognitive complexity 47 (threshold 15). Drivers by points: if/else 14 (26 pts), boolean chains 11, loops 6 (10 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":"backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py"},"region":{"startLine":845}}}],"partialFingerprints":{"codehealthFindingId/v1":"019d868ee61c9c1d3155ca551837be3a06a3f44ff8c297d0d874168f497f1eaf"}},{"ruleId":"D2","level":"warning","message":{"text":"ddd_packager.package_ddd (cognitive 46): ddd_packager.package_ddd has cognitive complexity 46 (threshold 15). Drivers by points: if/else 17 (33 pts), loops 4 (6 pts), boolean chains 5, ternaries 1 (2 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":"backend/core/ddd_packager.py"},"region":{"startLine":1838}}}],"partialFingerprints":{"codehealthFindingId/v1":"116a00a6294850dd01de47c3ac0f5bc56986e0e743306873d9370b491dec3558"}},{"ruleId":"D2","level":"warning","message":{"text":"BaseSchemaValidator.validate_file_references (cognitive 46): BaseSchemaValidator.validate_file_references has cognitive complexity 46 (threshold 15). Drivers by points: if/else 14 (26 pts), loops 6 (11 pts), error handling 2 (6 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":"backend/skills/s_docx/ooxml/scripts/validation/base.py"},"region":{"startLine":277}}}],"partialFingerprints":{"codehealthFindingId/v1":"1bf591939a7cb20599021594d88bbc986efd6ab15d3a6012a7333d8fea06860f"}},{"ruleId":"D2","level":"warning","message":{"text":"BaseSchemaValidator.validate_file_references (cognitive 46): BaseSchemaValidator.validate_file_references has cognitive complexity 46 (threshold 15). Drivers by points: if/else 14 (26 pts), loops 6 (11 pts), error handling 2 (6 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":"backend/skills/s_pptx/ooxml/scripts/validation/base.py"},"region":{"startLine":280}}}],"partialFingerprints":{"codehealthFindingId/v1":"879bae8718d615609e609415884c53ebbb4421ce383c7970b4b9ede7800c4d30"}},{"ruleId":"D2","level":"warning","message":{"text":"AssistantMessageView.AssistantMessageView (cognitive 46): AssistantMessageView.AssistantMessageView has cognitive complexity 46 (threshold 15). Drivers by points: boolean chains 23, ternaries 9 (11 pts), if/else 7 (9 pts), loops 2, error handling 1 (nesting depth added 4). Of this number, 22 points are the body\u0027s own statements and 24 belong to 6 function literals inside it that branch. To reduce it, name the conditions: bind each compound test to a well-named local or a small predicate function, so the body reads as a sequence of named decisions rather than a chain of operators."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/pages/chat/components/AssistantMessageView.tsx"},"region":{"startLine":77}}}],"partialFingerprints":{"codehealthFindingId/v1":"f39643a9afacb036eb8535eeb6d494c00a8a086c6ff5da45b3c3e33634578300"}},{"ruleId":"D2","level":"warning","message":{"text":"eval._build_learning_dashboard (cognitive 45): eval._build_learning_dashboard has cognitive complexity 45 (threshold 15). Drivers by points: if/else 10 (27 pts), loops 4 (11 pts), error handling 2 (6 pts), boolean chains 1 (nesting depth added 28). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/routers/eval.py"},"region":{"startLine":429}}}],"partialFingerprints":{"codehealthFindingId/v1":"2e9bd0d0f1e97585ef9bd208085d6622bc2ae5f3e887648f3f8eefcac9a3b540"}},{"ruleId":"D2","level":"warning","message":{"text":"workspace_api._build_tree (cognitive 45): workspace_api._build_tree has cognitive complexity 45 (threshold 15). Drivers by points: if/else 11 (23 pts), loops 5 (9 pts), ternaries 3 (8 pts), boolean chains 4, 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":"backend/routers/workspace_api.py"},"region":{"startLine":349}}}],"partialFingerprints":{"codehealthFindingId/v1":"93c0cb562242036fbbd8c1f4a77c9aa64bed1b0ad3f8841edd85e6424ec66641"}},{"ruleId":"D2","level":"warning","message":{"text":"locked_write.locked_read_modify_write (cognitive 45): locked_write.locked_read_modify_write has cognitive complexity 45 (threshold 15). Drivers by points: if/else 16 (27 pts), error handling 7 (12 pts), ternaries 1 (3 pts), boolean chains 2, loops 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":"backend/scripts/locked_write.py"},"region":{"startLine":515}}}],"partialFingerprints":{"codehealthFindingId/v1":"12f718f0f9beb2c655ca3dd4b7067ec9a2e14c3d76e56b04904e4dd0c43720ac"}},{"ruleId":"D2","level":"warning","message":{"text":"pipeline_cleanup.reclassify_stale_runs (cognitive 45): pipeline_cleanup.reclassify_stale_runs has cognitive complexity 45 (threshold 15). Drivers by points: if/else 10 (31 pts), error handling 2 (8 pts), boolean chains 3, loops 2 (3 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":"backend/scripts/pipeline_cleanup.py"},"region":{"startLine":31}}}],"partialFingerprints":{"codehealthFindingId/v1":"128a9675fc4691fe04eec76c4e4bc454250fcb9e7e55342fc6b303a13e3399f9"}},{"ruleId":"D2","level":"warning","message":{"text":"pipeline_validator.check_ddd_consistency (cognitive 45): pipeline_validator.check_ddd_consistency has cognitive complexity 45 (threshold 15). Drivers by points: if/else 13 (25 pts), loops 5 (11 pts), boolean chains 4, error handling 1 (3 pts), ternaries 1 (2 pts) (nesting depth added 21). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/scripts/pipeline_validator.py"},"region":{"startLine":1787}}}],"partialFingerprints":{"codehealthFindingId/v1":"086c04e5a7447bd2637e903cff430abbeb320a5c6f866c318a38cd44b5b1ac5e"}},{"ruleId":"D2","level":"warning","message":{"text":"locked_write.locked_read_modify_write (cognitive 45): locked_write.locked_read_modify_write has cognitive complexity 45 (threshold 15). Drivers by points: if/else 16 (27 pts), error handling 7 (12 pts), ternaries 1 (3 pts), boolean chains 2, loops 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":"backend/skills/s_persist/scripts/locked_write.py"},"region":{"startLine":515}}}],"partialFingerprints":{"codehealthFindingId/v1":"b45581206f03e68c0eb9f73fc6a555824bf4f684c72b21e0c19f86fc6f598efc"}},{"ruleId":"D2","level":"warning","message":{"text":"DiagramReveal.autoLayout (cognitive 45): DiagramReveal.autoLayout has cognitive complexity 45 (threshold 15). Drivers by points: ternaries 7 (19 pts), loops 10 (17 pts), if/else 5 (9 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":"backend/skills/s_pollinate/templates/remotion/components/DiagramReveal.tsx"},"region":{"startLine":65}}}],"partialFingerprints":{"codehealthFindingId/v1":"1b739b43167f81a510d8a583dcec28cc9f693f17a4849b48e90eaca9271a81c8"}},{"ruleId":"D2","level":"warning","message":{"text":"parser._build_file_scope_regex (cognitive 44): parser._build_file_scope_regex has cognitive complexity 44 (threshold 15). Drivers by points: loops 14 (30 pts), if/else 3 (9 pts), ternaries 1 (3 pts), boolean chains 2 (nesting depth added 24). 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":"backend/core/code_intel/parser.py"},"region":{"startLine":784}}}],"partialFingerprints":{"codehealthFindingId/v1":"4d17724879b278ae250ff9278fe645ecd60da9b6bf5809af9d4074a6eeb2ad14"}},{"ruleId":"D2","level":"warning","message":{"text":"correction_tracker._merge_drift (cognitive 44): correction_tracker._merge_drift has cognitive complexity 44 (threshold 15). Drivers by points: if/else 13 (29 pts), loops 5 (9 pts), boolean chains 4, ternaries 1 (2 pts) (nesting depth added 21). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/core/evolution/correction_tracker.py"},"region":{"startLine":69}}}],"partialFingerprints":{"codehealthFindingId/v1":"567027e2147355ca7142b65634d82278a2d07b9fa3501bfe3126be39b11a6232"}},{"ruleId":"D2","level":"warning","message":{"text":"eval_scheduled.run_eval_scheduled (cognitive 44): eval_scheduled.run_eval_scheduled has cognitive complexity 44 (threshold 15). Drivers by points: if/else 17 (19 pts), boolean chains 17, error handling 3 (7 pts), ternaries 1 (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":"backend/jobs/handlers/eval_scheduled.py"},"region":{"startLine":138}}}],"partialFingerprints":{"codehealthFindingId/v1":"89a181f07efa928332e258fc381ebd6fb4b2a5b23a46fc1f06c015e5698aeed1"}},{"ruleId":"D2","level":"warning","message":{"text":"DocxXMLEditor.suggest_deletion (cognitive 44): DocxXMLEditor.suggest_deletion has cognitive complexity 44 (threshold 15). Drivers by points: loops 8 (20 pts), if/else 10 (19 pts), ternaries 1 (3 pts), boolean chains 2 (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":"backend/skills/s_docx/scripts/document.py"},"region":{"startLine":482}}}],"partialFingerprints":{"codehealthFindingId/v1":"8219571746001e9c5c538ba51c760418082656dc987fe9da6e404aa281f11ba7"}},{"ruleId":"D2","level":"warning","message":{"text":"memory_extractor.extract_and_save (cognitive 43): memory_extractor.extract_and_save has cognitive complexity 43 (threshold 15). Drivers by points: if/else 14 (20 pts), error handling 8 (15 pts), boolean chains 4, loops 3 (4 pts) (nesting depth added 14). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/core/memory_extractor.py"},"region":{"startLine":367}}}],"partialFingerprints":{"codehealthFindingId/v1":"1d657113970ad44d301b02d97db90b19ad32ae01fc3b14e0b5179cff064ce114"}},{"ruleId":"D2","level":"warning","message":{"text":"backfill_cjk_escapes._populate_seg_columns (cognitive 43): backfill_cjk_escapes._populate_seg_columns has cognitive complexity 43 (threshold 15). Drivers by points: if/else 11 (27 pts), loops 5 (11 pts), boolean chains 5 (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":"backend/scripts/backfill_cjk_escapes.py"},"region":{"startLine":444}}}],"partialFingerprints":{"codehealthFindingId/v1":"16f433908cb9387a5dd8ab88af462b0c7d3ccd2d0109b55846ba63da59bd12e1"}},{"ruleId":"D2","level":"warning","message":{"text":"PollinateOverlay.AssetDrawer (cognitive 43): PollinateOverlay.AssetDrawer has cognitive complexity 43 (threshold 15). Drivers by points: ternaries 14 (25 pts), if/else 7 (9 pts), boolean chains 8, error handling 1 (nesting depth added 13). Of this number, 32 points are the body\u0027s own statements and 11 belong to 5 function literals inside it that branch. To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/layout/PollinateOverlay.tsx"},"region":{"startLine":494}}}],"partialFingerprints":{"codehealthFindingId/v1":"fb97808323c6505b409ae60876dbce74eab34649650997461c38054dd1c255a0"}},{"ruleId":"D2","level":"warning","message":{"text":"ingestion_gate.ingestion_gate (cognitive 42): ingestion_gate.ingestion_gate has cognitive complexity 42 (threshold 15). Drivers by points: if/else 15 (37 pts), boolean chains 2, error handling 1, loops 1, 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":"backend/core/ingestion_gate.py"},"region":{"startLine":633}}}],"partialFingerprints":{"codehealthFindingId/v1":"7e35bc2b09d4df49280660b074e60feccae13a0eb61e4cd41750d18133b0e5da"}},{"ruleId":"D2","level":"warning","message":{"text":"mcp_config_loader.merge_catalog_template (cognitive 42): mcp_config_loader.merge_catalog_template has cognitive complexity 42 (threshold 15). Drivers by points: if/else 13 (29 pts), error handling 4 (6 pts), ternaries 1 (4 pts), loops 2, boolean chains 1 (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":"backend/core/mcp_config_loader.py"},"region":{"startLine":149}}}],"partialFingerprints":{"codehealthFindingId/v1":"6469e284e4a4ac4896dc7ec91d2831b2daa979a8424c92c58a7d493c5bd77d9f"}},{"ruleId":"D2","level":"warning","message":{"text":"SummarizationPipeline._extract_topics (cognitive 42): SummarizationPipeline._extract_topics has cognitive complexity 42 (threshold 15). Drivers by points: if/else 15 (38 pts), boolean chains 3, loops 1 (nesting depth added 23). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/core/summarization.py"},"region":{"startLine":292}}}],"partialFingerprints":{"codehealthFindingId/v1":"714429ee046bc053b5a3ee5f15b16863e6330fb2d077d06f7b146ee71e95d147"}},{"ruleId":"D2","level":"warning","message":{"text":"artifact_cli.cmd_run_status (cognitive 42): artifact_cli.cmd_run_status has cognitive complexity 42 (threshold 15). Drivers by points: if/else 16 (26 pts), error handling 2 (8 pts), loops 4 (8 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":"backend/scripts/artifact_cli.py"},"region":{"startLine":3828}}}],"partialFingerprints":{"codehealthFindingId/v1":"595a8e36f9654eb378b54b72a83a00bde8e5a894b2c78fa344af3b72e08fc51a"}},{"ruleId":"D2","level":"warning","message":{"text":"pipeline_validator._verify_findings_on_disk (cognitive 42): pipeline_validator._verify_findings_on_disk has cognitive complexity 42 (threshold 15). Drivers by points: if/else 13 (29 pts), error handling 3 (8 pts), boolean chains 4, loops 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":"backend/scripts/pipeline_validator.py"},"region":{"startLine":155}}}],"partialFingerprints":{"codehealthFindingId/v1":"14ab056518fdd58a28d91856a0170e621413290ba8fbf54dc311f514e1b959bb"}},{"ruleId":"D2","level":"warning","message":{"text":"SelfLoopsHealthEngine._check_memory (cognitive 42): SelfLoopsHealthEngine._check_memory has cognitive complexity 42 (threshold 15). Drivers by points: if/else 13 (23 pts), ternaries 12 (13 pts), loops 4 (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":"backend/skills/s_loops-health/scripts/loops_health_check.py"},"region":{"startLine":269}}}],"partialFingerprints":{"codehealthFindingId/v1":"855f47f1c1635fcb81d3e5633fee9218de78471a105941f102ed032fd68d2b2e"}},{"ruleId":"D2","level":"warning","message":{"text":"AIModelsTab.AIModelsTab (cognitive 42): AIModelsTab.AIModelsTab has cognitive complexity 42 (threshold 15). Drivers by points: boolean chains 20, ternaries 8 (9 pts), if/else 7, error handling 6 (nesting depth added 1). Most of this is not in the body itself: 6 of the 42 points are its own statements and the rest belongs to 14 function literals inside it that branch (lines 83, 46, 56, \u2026). The decisions are inside those literals, which nothing outside this body can call, review or test on its own, so splitting the enclosing body is not the move available here. To reduce it, lift the literals\u0027 work into a named function or method at the enclosing scope and have each literal call it, then reduce whichever part then reads as the largest."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/settings/AIModelsTab.tsx"},"region":{"startLine":15}}}],"partialFingerprints":{"codehealthFindingId/v1":"737180d0df3d0d1bed22247965f6566dbf26719874e5b62fec13c7e9b9f635a7"}},{"ruleId":"D2","level":"warning","message":{"text":"community_data.build_feed (cognitive 41): community_data.build_feed has cognitive complexity 41 (threshold 15). Drivers by points: if/else 6 (16 pts), ternaries 3 (11 pts), error handling 3 (10 pts), loops 2 (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":"backend/core/community_data.py"},"region":{"startLine":564}}}],"partialFingerprints":{"codehealthFindingId/v1":"d942a27689498c89910999a2658af2d65714c37b280686dadb7a57726ed0dd22"}},{"ruleId":"D2","level":"warning","message":{"text":"proactive_intelligence._detect_temporal_signals (cognitive 41): proactive_intelligence._detect_temporal_signals has cognitive complexity 41 (threshold 15). Drivers by points: if/else 12 (29 pts), error handling 2 (6 pts), boolean chains 3, 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":"backend/core/proactive_intelligence.py"},"region":{"startLine":461}}}],"partialFingerprints":{"codehealthFindingId/v1":"3988c68bd25fa8fcf2447f9fa039a196319df8ee4f0fef467372bd4b3832a60c"}},{"ruleId":"D2","level":"warning","message":{"text":"session_router._maybe_inject_recall_inner (cognitive 41): session_router._maybe_inject_recall_inner has cognitive complexity 41 (threshold 15). Drivers by points: if/else 13 (16 pts), error handling 10 (14 pts), ternaries 5 (7 pts), boolean chains 4 (nesting depth added 9). 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":"backend/core/session_router.py"},"region":{"startLine":969}}}],"partialFingerprints":{"codehealthFindingId/v1":"3a5fc9128a2072903ebd733918c8042b07120f08cc39889e745f461f24bf2509"}},{"ruleId":"D2","level":"warning","message":{"text":"DistillationTriggerHook._enforce_section_caps (cognitive 41): DistillationTriggerHook._enforce_section_caps has cognitive complexity 41 (threshold 15). Drivers by points: if/else 15 (31 pts), loops 4 (8 pts), boolean chains 1, error handling 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":"backend/hooks/distillation_hook.py"},"region":{"startLine":2372}}}],"partialFingerprints":{"codehealthFindingId/v1":"b1835d35daf1781a166cf1346568a077351c57238f88fe5527ada536048ffe89"}},{"ruleId":"D2","level":"warning","message":{"text":"memory_health.run_memory_health (cognitive 41): memory_health.run_memory_health has cognitive complexity 41 (threshold 15). Drivers by points: if/else 15 (21 pts), boolean chains 6, loops 3 (6 pts), error handling 2 (5 pts), ternaries 2 (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":"backend/jobs/handlers/memory_health.py"},"region":{"startLine":150}}}],"partialFingerprints":{"codehealthFindingId/v1":"89845420bc0fdf17accb5704232245357579c86065655794179bf8fef4e61fc5"}},{"ruleId":"D2","level":"warning","message":{"text":"swarmai_monthly_report._collect_cultivation_metrics (cognitive 41): swarmai_monthly_report._collect_cultivation_metrics has cognitive complexity 41 (threshold 15). Drivers by points: if/else 9 (25 pts), error handling 2 (8 pts), loops 3 (7 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":"backend/jobs/handlers/swarmai_monthly_report.py"},"region":{"startLine":213}}}],"partialFingerprints":{"codehealthFindingId/v1":"9560a2fe2a41e6c9640e63f498176b34fe923a1f7c8c3adcf549d9f87820d86f"}},{"ruleId":"D2","level":"warning","message":{"text":"artifact_cli.purge_garbage_runs (cognitive 41): artifact_cli.purge_garbage_runs has cognitive complexity 41 (threshold 15). Drivers by points: if/else 10 (26 pts), error handling 3 (10 pts), loops 2 (3 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":"backend/scripts/artifact_cli.py"},"region":{"startLine":1469}}}],"partialFingerprints":{"codehealthFindingId/v1":"43262212ba127870813414bb8ae163aa7c57aa847804f5a54842a3ce5d507630"}},{"ruleId":"D2","level":"warning","message":{"text":"LifecycleManager._check_streaming_timeout (cognitive 40): LifecycleManager._check_streaming_timeout has cognitive complexity 40 (threshold 15). Drivers by points: if/else 12 (29 pts), ternaries 2 (6 pts), boolean chains 4, loops 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":"backend/core/lifecycle_manager.py"},"region":{"startLine":653}}}],"partialFingerprints":{"codehealthFindingId/v1":"896274a7dfebfee9103fac0a113a0be50cc4d5c5752d2659f9dc1d1b3b7ea07a"}},{"ruleId":"D2","level":"warning","message":{"text":"proactive_intelligence._extract_working_items (cognitive 40): proactive_intelligence._extract_working_items has cognitive complexity 40 (threshold 15). Drivers by points: if/else 9 (24 pts), loops 4 (9 pts), error handling 2 (5 pts), boolean chains 2 (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":"backend/core/proactive_intelligence.py"},"region":{"startLine":1788}}}],"partialFingerprints":{"codehealthFindingId/v1":"8abb6d50b2512511d9d4abd17cffe0b70a0cc2eb874296e161854d26b2b4ae63"}},{"ruleId":"D2","level":"warning","message":{"text":"useHealthMonitor.useHealthMonitor (cognitive 40): useHealthMonitor.useHealthMonitor has cognitive complexity 40 (threshold 15). Drivers by points: if/else 23 (32 pts), boolean chains 5, error handling 2, ternaries 1 (nesting depth added 9). Most of this is not in the body itself: 0 of the 40 points are its own statements and the rest belongs to 13 function literals inside it that branch (lines 222, 176, 293, \u2026). The decisions are inside those literals, which nothing outside this body can call, review or test on its own, so splitting the enclosing body is not the move available here. To reduce it, lift the literals\u0027 work into a named function or method at the enclosing scope and have each literal call it, then reduce whichever part then reads as the largest."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/hooks/useHealthMonitor.ts"},"region":{"startLine":134}}}],"partialFingerprints":{"codehealthFindingId/v1":"a2961368d88720d4fae17c6fc795f177bea1073165bbc514f85f076222e58169"}},{"ruleId":"D2","level":"warning","message":{"text":"FileContextMenu.FileContextMenu (cognitive 40): FileContextMenu.FileContextMenu has cognitive complexity 40 (threshold 15). Drivers by points: if/else 17 (19 pts), ternaries 7 (12 pts), boolean chains 7, error handling 2 (nesting depth added 7). Most of this is not in the body itself: 9 of the 40 points are its own statements and the rest belongs to 8 function literals inside it that branch (lines 101, 141, 167, \u2026). The decisions are inside those literals, which nothing outside this body can call, review or test on its own, so splitting the enclosing body is not the move available here. To reduce it, lift the literals\u0027 work into a named function or method at the enclosing scope and have each literal call it, then reduce whichever part then reads as the largest."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/workspace-explorer/FileContextMenu.tsx"},"region":{"startLine":58}}}],"partialFingerprints":{"codehealthFindingId/v1":"39f26353f2955a55255f8a0c6f0097ee475c11bd60d728c72349f3f8b084b8af"}},{"ruleId":"D2","level":"warning","message":{"text":"ContextHealthHook._refresh_code_intel (cognitive 39): ContextHealthHook._refresh_code_intel has cognitive complexity 39 (threshold 15). Drivers by points: if/else 13 (27 pts), error handling 2 (7 pts), loops 2 (3 pts), boolean chains 2 (nesting depth added 20). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/hooks/context_health_hook.py"},"region":{"startLine":577}}}],"partialFingerprints":{"codehealthFindingId/v1":"96da999fca387a496f69f1ff033456e28a06468135c06f1553d9ab4fa15242c2"}},{"ruleId":"D2","level":"warning","message":{"text":"BaseSchemaValidator.validate_content_types (cognitive 39): BaseSchemaValidator.validate_content_types has cognitive complexity 39 (threshold 15). Drivers by points: if/else 14 (25 pts), loops 5 (6 pts), boolean chains 3, error handling 2 (3 pts), ternaries 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":"backend/skills/s_docx/ooxml/scripts/validation/base.py"},"region":{"startLine":522}}}],"partialFingerprints":{"codehealthFindingId/v1":"30178663695122d791c20b583557dd058eb9f2297cb5ae23d15d5886b4be43a0"}},{"ruleId":"D2","level":"warning","message":{"text":"BaseSchemaValidator.validate_content_types (cognitive 39): BaseSchemaValidator.validate_content_types has cognitive complexity 39 (threshold 15). Drivers by points: if/else 14 (25 pts), loops 5 (6 pts), boolean chains 3, error handling 2 (3 pts), ternaries 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":"backend/skills/s_pptx/ooxml/scripts/validation/base.py"},"region":{"startLine":525}}}],"partialFingerprints":{"codehealthFindingId/v1":"5d83571d1fda8c609d051cd05949dd874eb1c5e7bc21a0dc14566d11b1c547a1"}},{"ruleId":"D2","level":"warning","message":{"text":"ActivityFeed.extractActivities (cognitive 39): ActivityFeed.extractActivities has cognitive complexity 39 (threshold 15). Drivers by points: if/else 12 (25 pts), boolean chains 8, ternaries 2 (5 pts), 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":"desktop/src/pages/chat/components/ActivityFeed.tsx"},"region":{"startLine":24}}}],"partialFingerprints":{"codehealthFindingId/v1":"0e106f1c428017833b528d6c15ec3f61ab67bf62284e36b50886566eff8d4545"}},{"ruleId":"D2","level":"warning","message":{"text":"useVoiceConversation.useVoiceConversation (cognitive 39): useVoiceConversation.useVoiceConversation has cognitive complexity 39 (threshold 15). Drivers by points: if/else 24 (25 pts), boolean chains 12, loops 1 (2 pts) (nesting depth added 2). Most of this is not in the body itself: 0 of the 39 points are its own statements and the rest belongs to 13 function literals inside it that branch (lines 179, 264, 149, \u2026). The decisions are inside those literals, which nothing outside this body can call, review or test on its own, so splitting the enclosing body is not the move available here. To reduce it, lift the literals\u0027 work into a named function or method at the enclosing scope and have each literal call it, then reduce whichever part then reads as the largest."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/hooks/useVoiceConversation.ts"},"region":{"startLine":75}}}],"partialFingerprints":{"codehealthFindingId/v1":"3d00c793dab10dbb6507289ad1c12d9752bb7f2452eb3be3f26f157a49463991"}},{"ruleId":"D2","level":"warning","message":{"text":"ChatErrorMessage.ChatErrorMessage (cognitive 39): ChatErrorMessage.ChatErrorMessage has cognitive complexity 39 (threshold 15). Drivers by points: ternaries 12 (30 pts), boolean chains 8, if/else 1 (nesting depth added 18). Of this number, 38 points are the body\u0027s own statements and 1 belongs to one function literal inside it that branches. 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":"desktop/src/components/chat/ChatErrorMessage.tsx"},"region":{"startLine":35}}}],"partialFingerprints":{"codehealthFindingId/v1":"70af6691bf577d05a98c52049939f65bacc6a7ac5b61d09453869d93e4eb1b79"}},{"ruleId":"D2","level":"warning","message":{"text":"blast_radius.analyze_diff (cognitive 38): blast_radius.analyze_diff has cognitive complexity 38 (threshold 15). Drivers by points: if/else 8 (14 pts), loops 7 (11 pts), ternaries 3 (6 pts), error handling 3 (4 pts), boolean chains 3 (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":"backend/core/code_intel/blast_radius.py"},"region":{"startLine":180}}}],"partialFingerprints":{"codehealthFindingId/v1":"8bdcf3c31c000f55279cffc1ce5267be933f3e804a61f3e8e74704a99fe31fd3"}},{"ruleId":"D2","level":"warning","message":{"text":"code_intel_feed.detect_tech_drift (cognitive 38): code_intel_feed.detect_tech_drift has cognitive complexity 38 (threshold 15). Drivers by points: if/else 16 (32 pts), boolean chains 2, error handling 2, loops 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":"backend/core/code_intel_feed.py"},"region":{"startLine":59}}}],"partialFingerprints":{"codehealthFindingId/v1":"9fb794b56387e3da04775b7880d7257f610ca0bb4404f74ea90e5ba5a00d27d8"}},{"ruleId":"D2","level":"warning","message":{"text":"context_injector._extract_tool_summary (cognitive 38): context_injector._extract_tool_summary has cognitive complexity 38 (threshold 15). Drivers by points: if/else 10 (27 pts), boolean chains 7, loops 2 (3 pts), error handling 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":"backend/core/context_injector.py"},"region":{"startLine":215}}}],"partialFingerprints":{"codehealthFindingId/v1":"25725c5503d6ce17465a689006443211581080054c572c553068a0530e86bdac"}},{"ruleId":"D2","level":"warning","message":{"text":"SessionUnit._emit_post_stream_metadata (cognitive 38): SessionUnit._emit_post_stream_metadata has cognitive complexity 38 (threshold 15). Drivers by points: if/else 10 (15 pts), ternaries 7 (11 pts), error handling 4 (7 pts), boolean chains 5 (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":"backend/core/session_unit.py"},"region":{"startLine":2976}}}],"partialFingerprints":{"codehealthFindingId/v1":"49976d60907634aa3f6fbc3e30b7179b97aa05e03cbe81135c777ebd6da8cebf"}},{"ruleId":"D2","level":"warning","message":{"text":"ContextHealthHook._set_verified_from_pipeline_runs (cognitive 38): ContextHealthHook._set_verified_from_pipeline_runs has cognitive complexity 38 (threshold 15). Drivers by points: if/else 14 (28 pts), error handling 2 (4 pts), loops 3 (4 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":"backend/hooks/context_health_hook.py"},"region":{"startLine":1433}}}],"partialFingerprints":{"codehealthFindingId/v1":"cba3fc4f8e8693ad13f163bf1acf2dcbe0edb94ae0726d3fc4b7f7ef555642cb"}},{"ruleId":"D2","level":"warning","message":{"text":"ImprovementWritebackHook._detect_project (cognitive 38): ImprovementWritebackHook._detect_project has cognitive complexity 38 (threshold 15). Drivers by points: if/else 10 (23 pts), ternaries 3 (8 pts), boolean chains 3, loops 2 (3 pts), error handling 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":"backend/hooks/improvement_writeback_hook.py"},"region":{"startLine":151}}}],"partialFingerprints":{"codehealthFindingId/v1":"49af5cdd117e3f93811283a599ea0c3bc0a47c47a7edcdcf543621aa48cd9173"}},{"ruleId":"D2","level":"warning","message":{"text":"channels.update_channel (cognitive 38): channels.update_channel has cognitive complexity 38 (threshold 15). Drivers by points: if/else 18 (24 pts), error handling 2 (6 pts), ternaries 4 (5 pts), boolean chains 3 (nesting depth added 11). 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":"backend/routers/channels.py"},"region":{"startLine":180}}}],"partialFingerprints":{"codehealthFindingId/v1":"b610df72523ff995ccbcde01f6bc5380caa6d23ed6d60d6de7c6fa47287cd50d"}},{"ruleId":"D2","level":"warning","message":{"text":"artifact_cli._stage_publish_times (cognitive 38): artifact_cli._stage_publish_times has cognitive complexity 38 (threshold 15). Drivers by points: if/else 9 (18 pts), error handling 2 (6 pts), ternaries 3 (6 pts), loops 3 (5 pts), boolean chains 3 (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":"backend/scripts/artifact_cli.py"},"region":{"startLine":5027}}}],"partialFingerprints":{"codehealthFindingId/v1":"7ef6064660bccbd19c92755e8a5e9f430327b53bc46d4aaa1082b52ad3d4b6db"}},{"ruleId":"D2","level":"warning","message":{"text":"eval_runner.evaluate_case (cognitive 38): eval_runner.evaluate_case has cognitive complexity 38 (threshold 15). Drivers by points: if/else 13 (33 pts), loops 3 (5 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":"backend/scripts/eval_runner.py"},"region":{"startLine":1606}}}],"partialFingerprints":{"codehealthFindingId/v1":"de2ac1a4fd9be9e770df19a65876b0b1e8b7239d16865a917718c8a652bb565d"}},{"ruleId":"D2","level":"warning","message":{"text":"replace.validate_replacements (cognitive 38): replace.validate_replacements has cognitive complexity 38 (threshold 15). Drivers by points: if/else 7 (26 pts), loops 3 (7 pts), ternaries 1 (4 pts), boolean chains 1 (nesting depth added 26). 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":"backend/skills/s_pptx/scripts/replace.py"},"region":{"startLine":162}}}],"partialFingerprints":{"codehealthFindingId/v1":"44cfd5e9c9cb7ab2b67d0e2936280f23c4a2bb38d91af7f1500246cf357be5e7"}},{"ruleId":"D2","level":"warning","message":{"text":"ContentBlockRenderer.ContentBlockRenderer (cognitive 38): ContentBlockRenderer.ContentBlockRenderer has cognitive complexity 38 (threshold 15). Drivers by points: boolean chains 15, if/else 11 (15 pts), ternaries 4 (8 pts) (nesting depth added 8). Of this number, 37 points are the body\u0027s own statements and 1 belongs to one function literal inside it that branches. To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/pages/chat/components/ContentBlockRenderer.tsx"},"region":{"startLine":122}}}],"partialFingerprints":{"codehealthFindingId/v1":"814a56f54fc4ce7e26d2428b80750971f978164e54c552b7345d6b3fe80633cb"}},{"ruleId":"D2","level":"warning","message":{"text":"FolderPickerModal.FolderPickerModal (cognitive 38): FolderPickerModal.FolderPickerModal has cognitive complexity 38 (threshold 15). Drivers by points: ternaries 8 (19 pts), boolean chains 10, if/else 9 (nesting depth added 11). Of this number, 16 points are the body\u0027s own statements and 22 belong to 10 function literals inside it that branch. To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/workspace/FolderPickerModal.tsx"},"region":{"startLine":21}}}],"partialFingerprints":{"codehealthFindingId/v1":"ba3f5c7b3b0f80ff4cea00d1a06e5882788d91b2a1956ab49b91e21dcf4aac25"}},{"ruleId":"D2","level":"warning","message":{"text":"SlackChannelAdapter._text_to_blocks (cognitive 37): SlackChannelAdapter._text_to_blocks has cognitive complexity 37 (threshold 15). Drivers by points: if/else 12 (21 pts), loops 4 (7 pts), boolean chains 6, 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":"backend/channels/adapters/slack.py"},"region":{"startLine":1923}}}],"partialFingerprints":{"codehealthFindingId/v1":"3e0d4c11dd93a0e0dd9483334eb8e7e2a4d8888a5cdf661eb913bc66a9c45151"}},{"ruleId":"D2","level":"warning","message":{"text":"codebase_map._format_briefing (cognitive 37): codebase_map._format_briefing has cognitive complexity 37 (threshold 15). Drivers by points: if/else 13 (18 pts), loops 4 (8 pts), ternaries 3 (8 pts), error handling 1 (2 pts), boolean chains 1 (nesting depth added 15). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/core/code_intel/codebase_map.py"},"region":{"startLine":43}}}],"partialFingerprints":{"codehealthFindingId/v1":"f14ee020d4cfe8359865f8be954e1ca067f41640f1463385fc8285aebd0aee56"}},{"ruleId":"D2","level":"warning","message":{"text":"parser._extract_from_tree (cognitive 37): parser._extract_from_tree has cognitive complexity 37 (threshold 15). Drivers by points: if/else 6 (19 pts), loops 4 (11 pts), ternaries 4, boolean chains 3 (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":"backend/core/code_intel/parser.py"},"region":{"startLine":997}}}],"partialFingerprints":{"codehealthFindingId/v1":"cc0233574013ea0040c13ee015e43976e44efd634b23173bd2ac295fe4aa2993"}},{"ruleId":"D2","level":"warning","message":{"text":"ddd_cultivation.apply_to_ddd (cognitive 37): ddd_cultivation.apply_to_ddd has cognitive complexity 37 (threshold 15). Drivers by points: if/else 16 (21 pts), boolean chains 7, ternaries 4 (7 pts), loops 1 (2 pts) (nesting depth added 9). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/core/ddd_cultivation.py"},"region":{"startLine":984}}}],"partialFingerprints":{"codehealthFindingId/v1":"2db55b3ad64122b71bce1c9affe761050eea59455b2d6d8d57843f18032be917"}},{"ruleId":"D2","level":"warning","message":{"text":"mcp_migration.migrate_if_needed (cognitive 37): mcp_migration.migrate_if_needed has cognitive complexity 37 (threshold 15). Drivers by points: if/else 13 (28 pts), error handling 3 (4 pts), loops 3 (4 pts), 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":"backend/core/mcp_migration.py"},"region":{"startLine":28}}}],"partialFingerprints":{"codehealthFindingId/v1":"21e795346e7cde349570a3802bca4c8fe0e154850f17c9b0e41aea73c2d86066"}},{"ruleId":"D2","level":"warning","message":{"text":"PluginManager.sync_git_marketplace (cognitive 37): PluginManager.sync_git_marketplace has cognitive complexity 37 (threshold 15). Drivers by points: if/else 12 (25 pts), error handling 2 (6 pts), loops 3 (4 pts), boolean chains 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":"backend/core/plugin_manager.py"},"region":{"startLine":118}}}],"partialFingerprints":{"codehealthFindingId/v1":"ce6b94e66aabc0be501adce5fd48f64d6acfcbe33f339afeb45107ea014aa41d"}},{"ruleId":"D2","level":"warning","message":{"text":"artifact_cli._load_completed_runs (cognitive 37): artifact_cli._load_completed_runs has cognitive complexity 37 (threshold 15). Drivers by points: if/else 8 (24 pts), error handling 2 (7 pts), loops 2 (4 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":"backend/scripts/artifact_cli.py"},"region":{"startLine":1596}}}],"partialFingerprints":{"codehealthFindingId/v1":"5a8874f9203f209785d4b16db3e2a647980e49da9cd1220e2795608e6beb0afe"}},{"ruleId":"D2","level":"warning","message":{"text":"ai_ready_helpers.compute_business_rules_dimension (cognitive 37): ai_ready_helpers.compute_business_rules_dimension has cognitive complexity 37 (threshold 15). Drivers by points: if/else 10 (20 pts), boolean chains 9, loops 2 (5 pts), ternaries 3 (nesting depth added 13). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py"},"region":{"startLine":3973}}}],"partialFingerprints":{"codehealthFindingId/v1":"c56a318122cdc542a0d6fe0acdc7b4e482cbddd3ec3bbef18c76775d5f424206"}},{"ruleId":"D2","level":"warning","message":{"text":"steeringify.group_and_propose (cognitive 37): steeringify.group_and_propose has cognitive complexity 37 (threshold 15). Drivers by points: if/else 10 (23 pts), loops 6 (10 pts), error handling 1 (3 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":"backend/skills/s_steeringify/steeringify.py"},"region":{"startLine":198}}}],"partialFingerprints":{"codehealthFindingId/v1":"e7051124f73cabee4c99013e67206c93c2a3a538282b817efbd4c94c02f57648"}},{"ruleId":"D2","level":"warning","message":{"text":"ExplorerContext.ExplorerProvider (cognitive 37): ExplorerContext.ExplorerProvider has cognitive complexity 37 (threshold 15). Drivers by points: if/else 18 (23 pts), ternaries 3 (5 pts), boolean chains 4, error handling 3, loops 2 (nesting depth added 7). Most of this is not in the body itself: 0 of the 37 points are its own statements and the rest belongs to 11 function literals inside it that branch (lines 616, 531, 489, \u2026). The decisions are inside those literals, which nothing outside this body can call, review or test on its own, so splitting the enclosing body is not the move available here. To reduce it, lift the literals\u0027 work into a named function or method at the enclosing scope and have each literal call it, then reduce whichever part then reads as the largest."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/contexts/ExplorerContext.tsx"},"region":{"startLine":369}}}],"partialFingerprints":{"codehealthFindingId/v1":"9d48914fd15e64e53ac8d98805b7e7081fbf41d9ff83e0b4bcce30cddfce77a5"}},{"ruleId":"D2","level":"warning","message":{"text":"ddd_entry_lifecycle._strip_entries (cognitive 36): ddd_entry_lifecycle._strip_entries has cognitive complexity 36 (threshold 15). Drivers by points: if/else 9 (26 pts), boolean chains 6, loops 2 (4 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":"backend/core/ddd_entry_lifecycle.py"},"region":{"startLine":1789}}}],"partialFingerprints":{"codehealthFindingId/v1":"1e8b2f427eecf0cd36dbc73f66cf43c84393bc03dd52c7d75219bb59e730aabb"}},{"ruleId":"D2","level":"warning","message":{"text":"proactive_intelligence._parse_continue_hints (cognitive 36): proactive_intelligence._parse_continue_hints has cognitive complexity 36 (threshold 15). Drivers by points: if/else 11 (22 pts), loops 4 (6 pts), boolean chains 3, ternaries 1 (3 pts), error handling 1 (2 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":"backend/core/proactive_intelligence.py"},"region":{"startLine":176}}}],"partialFingerprints":{"codehealthFindingId/v1":"bfb4458bff652ac72c25bc23e5e6850f1ac137a6a7895d422be2451ae84ca40d"}},{"ruleId":"D2","level":"warning","message":{"text":"SwarmWorkspaceManager._cleanup_legacy_content (cognitive 36): SwarmWorkspaceManager._cleanup_legacy_content has cognitive complexity 36 (threshold 15). Drivers by points: if/else 11 (22 pts), loops 8 (13 pts), error handling 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":"backend/core/swarm_workspace_manager.py"},"region":{"startLine":2092}}}],"partialFingerprints":{"codehealthFindingId/v1":"1cc6770e074cc4b1ef05ba36fa9ec6d3efeafc286059465515852b6ec646c82c"}},{"ruleId":"D2","level":"warning","message":{"text":"DailyActivityExtractionHook._capture_git_activity (cognitive 36): DailyActivityExtractionHook._capture_git_activity has cognitive complexity 36 (threshold 15). Drivers by points: if/else 6 (19 pts), loops 4 (11 pts), error handling 3 (5 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":"backend/hooks/daily_activity_hook.py"},"region":{"startLine":333}}}],"partialFingerprints":{"codehealthFindingId/v1":"3198d8f6d88338853f3dfd832f9477bcfd2e30a478745ec9e6f8449cc5c2be9e"}},{"ruleId":"D2","level":"warning","message":{"text":"memory_health._resolve_open_thread (cognitive 36): memory_health._resolve_open_thread has cognitive complexity 36 (threshold 15). Drivers by points: if/else 14 (25 pts), loops 4 (5 pts), ternaries 2 (3 pts), boolean chains 2, error handling 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":"backend/jobs/handlers/memory_health.py"},"region":{"startLine":887}}}],"partialFingerprints":{"codehealthFindingId/v1":"15d7ad92cdf4b3e76fdea85632dfe62c0aef7700399ecbd01c13feda5449b473"}},{"ruleId":"D2","level":"warning","message":{"text":"tasks.create_task (cognitive 36): tasks.create_task has cognitive complexity 36 (threshold 15). Drivers by points: if/else 9 (19 pts), loops 2 (6 pts), boolean chains 4, error handling 3 (4 pts), ternaries 1 (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":"backend/routers/tasks.py"},"region":{"startLine":66}}}],"partialFingerprints":{"codehealthFindingId/v1":"06cb46ab690db9634e8981c4f002c2d66d9b526feb2882db3366ea458fc26271"}},{"ruleId":"D2","level":"warning","message":{"text":"migrate_memory_lifecycle.migrate_file (cognitive 36): migrate_memory_lifecycle.migrate_file has cognitive complexity 36 (threshold 15). Drivers by points: if/else 13 (28 pts), boolean chains 4, loops 2 (4 pts) (nesting depth added 17). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/scripts/migrate_memory_lifecycle.py"},"region":{"startLine":95}}}],"partialFingerprints":{"codehealthFindingId/v1":"d9856cc540ee24b99e626ed6d32cef324cb1c6c5617d425081a3450ef971c3b4"}},{"ruleId":"D2","level":"warning","message":{"text":"XMLEditor.get_node (cognitive 36): XMLEditor.get_node has cognitive complexity 36 (threshold 15). Drivers by points: if/else 14 (30 pts), ternaries 2 (5 pts), loops 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":"backend/skills/s_docx/scripts/utilities.py"},"region":{"startLine":76}}}],"partialFingerprints":{"codehealthFindingId/v1":"9e1ad05209027c30df1a901293f262135152772f137beb01e1d2cc82dffcac9b"}},{"ruleId":"D2","level":"warning","message":{"text":"ai_ready_helpers.select_verification_tasks (cognitive 36): ai_ready_helpers.select_verification_tasks has cognitive complexity 36 (threshold 15). Drivers by points: if/else 12 (25 pts), loops 5 (6 pts), boolean chains 4, error handling 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":"backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py"},"region":{"startLine":3252}}}],"partialFingerprints":{"codehealthFindingId/v1":"8883b7d81515ecd7b0dfa5dd8d6048278845e20b93888631ef0f67054127194d"}},{"ruleId":"D2","level":"warning","message":{"text":"locked_write.locked_read_modify_write (cognitive 36): locked_write.locked_read_modify_write has cognitive complexity 36 (threshold 15). Drivers by points: if/else 14 (24 pts), error handling 6 (10 pts), boolean chains 1, loops 1 (nesting depth added 14). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/templates/ddd-skills/s_ddd-persist/scripts/locked_write.py"},"region":{"startLine":515}}}],"partialFingerprints":{"codehealthFindingId/v1":"1a549aaff769a2b99d28f39a33a9ce3b21e3bbda9d9c9fa52395d0d20a1ef95f"}},{"ruleId":"D2","level":"warning","message":{"text":"TreeNodeRow.TreeNodeRow (cognitive 36): TreeNodeRow.TreeNodeRow has cognitive complexity 36 (threshold 15). Drivers by points: ternaries 15 (18 pts), boolean chains 9, if/else 8 (9 pts) (nesting depth added 4). Of this number, 28 points are the body\u0027s own statements and 8 belong to 2 function literals inside it that branch. 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":"desktop/src/components/workspace-explorer/TreeNodeRow.tsx"},"region":{"startLine":188}}}],"partialFingerprints":{"codehealthFindingId/v1":"80a8d92c43d6ea8c22d9a6bde355b6c60a17c55b2d9397b26b2905edb6467ae6"}},{"ruleId":"D2","level":"warning","message":{"text":"VirtualizedTree.VirtualizedTree (cognitive 36): VirtualizedTree.VirtualizedTree has cognitive complexity 36 (threshold 15). Drivers by points: if/else 15, ternaries 8 (11 pts), error handling 5, boolean chains 4, loops 1 (nesting depth added 3). Most of this is not in the body itself: 1 of the 36 points is its own statement and the rest belongs to 11 function literals inside it that branch (lines 881, 925, 813, \u2026). The decisions are inside those literals, which nothing outside this body can call, review or test on its own, so splitting the enclosing body is not the move available here. To reduce it, lift the literals\u0027 work into a named function or method at the enclosing scope and have each literal call it, then reduce whichever part then reads as the largest."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/workspace-explorer/VirtualizedTree.tsx"},"region":{"startLine":688}}}],"partialFingerprints":{"codehealthFindingId/v1":"a60f91561e9594d9030c3a2f285b6ba823d3542fddcebf16d35a85b6965953c8"}},{"ruleId":"D2","level":"warning","message":{"text":"LibraryTree.LibraryTree (cognitive 36): LibraryTree.LibraryTree has cognitive complexity 36 (threshold 15). Drivers by points: ternaries 13 (20 pts), if/else 8, boolean chains 7, error handling 1 (nesting depth added 7). Of this number, 17 points are the body\u0027s own statements and 19 belong to 8 function literals inside it that branch. To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/layout/LibraryTree.tsx"},"region":{"startLine":218}}}],"partialFingerprints":{"codehealthFindingId/v1":"5f8063f200c352e6e4985926cc06b6d498c7eebe728504c9735a5d8a917d887e"}},{"ruleId":"D2","level":"warning","message":{"text":"sentenceSplitter.extractSentences (cognitive 36): sentenceSplitter.extractSentences has cognitive complexity 36 (threshold 15). Drivers by points: if/else 10 (27 pts), boolean chains 4, ternaries 1 (4 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":"desktop/src/utils/sentenceSplitter.ts"},"region":{"startLine":127}}}],"partialFingerprints":{"codehealthFindingId/v1":"f309a629ef7f74b33bf9e0b28449ef39d357389f73cdb01117aeced05cb01738"}},{"ruleId":"D2","level":"warning","message":{"text":"domain_rules.compute_domain_rules (cognitive 35): domain_rules.compute_domain_rules has cognitive complexity 35 (threshold 15). Drivers by points: if/else 7 (14 pts), ternaries 5 (13 pts), loops 4 (7 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":"backend/core/code_intel/domain_rules.py"},"region":{"startLine":136}}}],"partialFingerprints":{"codehealthFindingId/v1":"411a7128cfdc5b4037ea504686a571420a56e96700db060e020b6c540e2a21ff"}},{"ruleId":"D2","level":"warning","message":{"text":"daily_activity_writer._format_session_entry (cognitive 35): daily_activity_writer._format_session_entry has cognitive complexity 35 (threshold 15). Drivers by points: loops 9 (18 pts), if/else 14, boolean chains 2, ternaries 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":"backend/core/daily_activity_writer.py"},"region":{"startLine":134}}}],"partialFingerprints":{"codehealthFindingId/v1":"3e4cb29aca15e7abd879a8b363373771ee0ab89400b38e28f44ed016daf0474e"}},{"ruleId":"D2","level":"warning","message":{"text":"proactive_scoring.detect_blocking (cognitive 35): proactive_scoring.detect_blocking has cognitive complexity 35 (threshold 15). Drivers by points: if/else 10 (30 pts), loops 2 (4 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":"backend/core/proactive_scoring.py"},"region":{"startLine":109}}}],"partialFingerprints":{"codehealthFindingId/v1":"39d3229b443feb1ef1aa61276f42c6fad1d29763d673c92776e0c0ff0953948e"}},{"ruleId":"D2","level":"warning","message":{"text":"SQLiteDatabase._run_data_cleanups (cognitive 35): SQLiteDatabase._run_data_cleanups has cognitive complexity 35 (threshold 15). Drivers by points: if/else 7 (17 pts), error handling 5 (13 pts), loops 1 (2 pts), ternaries 1 (2 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":"backend/database/sqlite.py"},"region":{"startLine":3248}}}],"partialFingerprints":{"codehealthFindingId/v1":"4f2bc41f8dab7abf812833ddfacdf207a80a6dc8d8cc97ab18589fddf9349422"}},{"ruleId":"D2","level":"warning","message":{"text":"ContextHealthHook._extract_lessons_to_memory (cognitive 35): ContextHealthHook._extract_lessons_to_memory has cognitive complexity 35 (threshold 15). Drivers by points: if/else 9 (16 pts), error handling 3 (6 pts), loops 4 (5 pts), boolean chains 4, ternaries 2 (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":"backend/hooks/context_health_hook.py"},"region":{"startLine":969}}}],"partialFingerprints":{"codehealthFindingId/v1":"04011834491d9fa7ce0ed1268d0608bd86557770e4e267163663ec010c409460"}},{"ruleId":"D2","level":"warning","message":{"text":"ContextHealthHook._detect_stale_memory_claims (cognitive 35): ContextHealthHook._detect_stale_memory_claims has cognitive complexity 35 (threshold 15). Drivers by points: if/else 7 (17 pts), loops 4 (8 pts), error handling 2 (4 pts), ternaries 1 (4 pts), boolean chains 2 (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":"backend/hooks/context_health_hook.py"},"region":{"startLine":2941}}}],"partialFingerprints":{"codehealthFindingId/v1":"2992664f783bb1633b46f5dfd1b0a0295f69add02e5405475a6113fbf56e2f76"}},{"ruleId":"D2","level":"warning","message":{"text":"ddd_self_audit.run_ddd_self_audit (cognitive 35): ddd_self_audit.run_ddd_self_audit has cognitive complexity 35 (threshold 15). Drivers by points: if/else 10 (16 pts), ternaries 5 (9 pts), error handling 2 (5 pts), boolean chains 4, loops 1 (nesting depth added 13). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/jobs/handlers/ddd_self_audit.py"},"region":{"startLine":221}}}],"partialFingerprints":{"codehealthFindingId/v1":"edde216c57b1057110aedb3b941783fe06cd3f36e9436673ea7eedac3f1acf36"}},{"ruleId":"D2","level":"warning","message":{"text":"chat.get_streaming_state_endpoint (cognitive 35): chat.get_streaming_state_endpoint has cognitive complexity 35 (threshold 15). Drivers by points: error handling 4 (13 pts), if/else 4 (13 pts), loops 2 (4 pts), boolean chains 3, ternaries 1 (2 pts) (nesting depth added 21). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/routers/chat.py"},"region":{"startLine":907}}}],"partialFingerprints":{"codehealthFindingId/v1":"2b8f857c6da96769a67b3b70ae2538243c4be97e736b1462d01fc384e7bc502f"}},{"ruleId":"D2","level":"warning","message":{"text":"system._probe_ada_details (cognitive 35): system._probe_ada_details has cognitive complexity 35 (threshold 15). Drivers by points: if/else 7 (18 pts), loops 3 (6 pts), ternaries 2 (6 pts), error handling 2 (4 pts), boolean chains 1 (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":"backend/routers/system.py"},"region":{"startLine":751}}}],"partialFingerprints":{"codehealthFindingId/v1":"e9d3fbe89193ef8ea0413975609c0d544066fa827d638b8502b1a7a36adbcd63"}},{"ruleId":"D2","level":"warning","message":{"text":"pipeline_analytics.analyze_stage_efficiency (cognitive 35): pipeline_analytics.analyze_stage_efficiency has cognitive complexity 35 (threshold 15). Drivers by points: if/else 9 (20 pts), loops 5 (8 pts), boolean chains 7 (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":"backend/scripts/pipeline_analytics.py"},"region":{"startLine":503}}}],"partialFingerprints":{"codehealthFindingId/v1":"9640051b8dd581f36144d6557e7c0ed07f28e7edd4f9c2a4ccf4707234e794f8"}},{"ruleId":"D2","level":"warning","message":{"text":"design_system.format_ascii_box (cognitive 35): design_system.format_ascii_box has cognitive complexity 35 (threshold 15). Drivers by points: loops 10 (17 pts), if/else 15 (16 pts), boolean chains 2 (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":"backend/skills/s_frontend-design/scripts/design_system.py"},"region":{"startLine":282}}}],"partialFingerprints":{"codehealthFindingId/v1":"de302a33b159b01473c95193a49b31ca0865212eb3fec464062972b44ee03fc1"}},{"ruleId":"D2","level":"warning","message":{"text":"ShapeData._estimate_frame_overflow (cognitive 35): ShapeData._estimate_frame_overflow has cognitive complexity 35 (threshold 15). Drivers by points: if/else 13 (23 pts), boolean chains 6, error handling 1 (3 pts), loops 2 (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":"backend/skills/s_pptx/scripts/inventory.py"},"region":{"startLine":562}}}],"partialFingerprints":{"codehealthFindingId/v1":"83d899c947d62c4fa3e0965e0788fcddddf1006489a01c2a2fd16b939152bd7f"}},{"ruleId":"D2","level":"warning","message":{"text":"streaming-machine.streamingReducer (cognitive 35): streaming-machine.streamingReducer has cognitive complexity 35 (threshold 15). Drivers by points: match/switch 12 (23 pts), if/else 3 (9 pts), ternaries 1 (3 pts) (nesting depth added 19). To reduce it, keep the dispatch but shrink the arms: move each non-trivial case body into its own named function (or onto the value being matched) so the dispatch reads one line per case, and group related cases into a sub-dispatch. Keep every case explicit, and make the behaviour for cases you do not list a deliberate choice rather than an accident."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/hooks/streaming-machine.ts"},"region":{"startLine":110}}}],"partialFingerprints":{"codehealthFindingId/v1":"ebb024ae6a83e744952f8f559eddc81ccedd79745c116ffd6c75a56b39d68c0c"}},{"ruleId":"D2","level":"warning","message":{"text":"CapabilitiesOverlay.CapabilitiesContent (cognitive 35): CapabilitiesOverlay.CapabilitiesContent has cognitive complexity 35 (threshold 15). Drivers by points: boolean chains 14, if/else 11 (12 pts), ternaries 6 (7 pts), error handling 2 (nesting depth added 2). Most of this is not in the body itself: 12 of the 35 points are its own statements and the rest belongs to 14 function literals inside it that branch (lines 227, 327, 189, \u2026). The decisions are inside those literals, which nothing outside this body can call, review or test on its own, so splitting the enclosing body is not the move available here. To reduce it, lift the literals\u0027 work into a named function or method at the enclosing scope and have each literal call it, then reduce whichever part then reads as the largest."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/layout/CapabilitiesOverlay.tsx"},"region":{"startLine":173}}}],"partialFingerprints":{"codehealthFindingId/v1":"fabf89fd6827ed3d459e461e056756b3f1018a2dab6a27476e4b0407670a0f13"}},{"ruleId":"D2","level":"warning","message":{"text":"library_health.scan_library_health (cognitive 34): library_health.scan_library_health has cognitive complexity 34 (threshold 15). Drivers by points: if/else 13 (25 pts), loops 4 (5 pts), boolean chains 3, ternaries 1 (nesting depth added 13). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/core/library_health.py"},"region":{"startLine":103}}}],"partialFingerprints":{"codehealthFindingId/v1":"eb668c428b19d95af9cb9b7646ee3245f08e2f81746047d187ea97383463419e"}},{"ruleId":"D2","level":"warning","message":{"text":"proactive_intelligence._get_job_result_highlights (cognitive 34): proactive_intelligence._get_job_result_highlights has cognitive complexity 34 (threshold 15). Drivers by points: if/else 10 (19 pts), error handling 3 (6 pts), ternaries 3 (6 pts), loops 2, boolean chains 1 (nesting depth added 15). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/core/proactive_intelligence.py"},"region":{"startLine":627}}}],"partialFingerprints":{"codehealthFindingId/v1":"380a5813808b98853857a6fd25c07e39015103b79765fb718a92ce135b1cd721"}},{"ruleId":"D2","level":"warning","message":{"text":"skill_migration.migrate_skill_ids_to_allowed_skills (cognitive 34): skill_migration.migrate_skill_ids_to_allowed_skills has cognitive complexity 34 (threshold 15). Drivers by points: if/else 11 (17 pts), error handling 7 (9 pts), loops 4 (6 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":"backend/core/skill_migration.py"},"region":{"startLine":25}}}],"partialFingerprints":{"codehealthFindingId/v1":"d498d0bf25ee6186dbebf2ac5ccdddc40d1680a5e32d926083d8b769ffa4e519"}},{"ruleId":"D2","level":"warning","message":{"text":"SummarizationPipeline._extract_decisions (cognitive 34): SummarizationPipeline._extract_decisions has cognitive complexity 34 (threshold 15). Drivers by points: if/else 9 (30 pts), loops 2 (3 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":"backend/core/summarization.py"},"region":{"startLine":382}}}],"partialFingerprints":{"codehealthFindingId/v1":"7f03f8bd5fe847cb256a84efc84f73cc98b37657cecd7f38cdb5bd8f31fae82d"}},{"ruleId":"D2","level":"warning","message":{"text":"ContextHealthHook._deep_check (cognitive 34): ContextHealthHook._deep_check has cognitive complexity 34 (threshold 15). Drivers by points: if/else 15 (20 pts), error handling 7 (10 pts), boolean chains 2, loops 1 (2 pts) (nesting depth added 9). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/hooks/context_health_hook.py"},"region":{"startLine":2492}}}],"partialFingerprints":{"codehealthFindingId/v1":"9f87ddc0c102625a18e95b2b7d21e6ae7bbd8f07baa739cf15934106d5aeaa13"}},{"ruleId":"D2","level":"warning","message":{"text":"PPTXSchemaValidator.validate_notes_slide_references (cognitive 34): PPTXSchemaValidator.validate_notes_slide_references has cognitive complexity 34 (threshold 15). Drivers by points: if/else 10 (23 pts), loops 5 (9 pts), error handling 1 (2 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":"backend/skills/s_docx/ooxml/scripts/validation/pptx.py"},"region":{"startLine":243}}}],"partialFingerprints":{"codehealthFindingId/v1":"79c5ab53c22c34278b5d01d559646e1465d9dcdd5aa8d14dad5bf982a65d2135"}},{"ruleId":"D2","level":"warning","message":{"text":"publish_dashboard.scan_deliver (cognitive 34): publish_dashboard.scan_deliver has cognitive complexity 34 (threshold 15). Drivers by points: ternaries 5 (19 pts), if/else 5 (11 pts), loops 2 (3 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":"backend/skills/s_pollinate/scripts/publish_dashboard.py"},"region":{"startLine":44}}}],"partialFingerprints":{"codehealthFindingId/v1":"c53952960357206be13d0898f4f41110a0f592ccbe355479a99643a3140209bd"}},{"ruleId":"D2","level":"warning","message":{"text":"PPTXSchemaValidator.validate_notes_slide_references (cognitive 34): PPTXSchemaValidator.validate_notes_slide_references has cognitive complexity 34 (threshold 15). Drivers by points: if/else 10 (23 pts), loops 5 (9 pts), error handling 1 (2 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":"backend/skills/s_pptx/ooxml/scripts/validation/pptx.py"},"region":{"startLine":243}}}],"partialFingerprints":{"codehealthFindingId/v1":"929fe4e7703168ec10c19f49e1e5810171994f67e3dee9126617894669d48c39"}},{"ruleId":"D2","level":"warning","message":{"text":"CMBrainOverlay.ArchivePanel (cognitive 34): CMBrainOverlay.ArchivePanel has cognitive complexity 34 (threshold 15). Drivers by points: ternaries 9 (29 pts), boolean chains 5 (nesting depth added 20). Of this number, 28 points are the body\u0027s own statements and 6 belong to 2 function literals inside it that branch. 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":"desktop/src/components/layout/CMBrainOverlay.tsx"},"region":{"startLine":772}}}],"partialFingerprints":{"codehealthFindingId/v1":"097bb0f0b117cc102964f5d389c402b92b2c1fabd608217b1c013edaf4edf662"}},{"ruleId":"D2","level":"warning","message":{"text":"BrainHub.DistributeView (cognitive 34): BrainHub.DistributeView has cognitive complexity 34 (threshold 15). Drivers by points: ternaries 13 (23 pts), boolean chains 6, if/else 4 (5 pts) (nesting depth added 11). Of this number, 22 points are the body\u0027s own statements and 12 belong to 2 function literals inside it that branch. To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/layout/BrainHub.tsx"},"region":{"startLine":1173}}}],"partialFingerprints":{"codehealthFindingId/v1":"37337e174edf9f679bc9f3735c8bf35f7977f621f8d81ce02c7fba5a7867ca21"}},{"ruleId":"D2","level":"warning","message":{"text":"ReviewModeGutter.ReviewModeGutter (cognitive 34): ReviewModeGutter.ReviewModeGutter has cognitive complexity 34 (threshold 15). Drivers by points: ternaries 17 (23 pts), boolean chains 11 (nesting depth added 6). Most of this is not in the body itself: 14 of the 34 points are its own statements and the rest belongs to 3 function literals inside it that branch (lines 114, 156, 169). The decisions are inside those literals, which nothing outside this body can call, review or test on its own, so splitting the enclosing body is not the move available here. To reduce it, lift the literals\u0027 work into a named function or method at the enclosing scope and have each literal call it, then reduce whichever part then reads as the largest."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/common/ReviewModeGutter.tsx"},"region":{"startLine":42}}}],"partialFingerprints":{"codehealthFindingId/v1":"1707500e4650c99c8f158b560d16c88097bb51b6ee94b30e286ec5ae3067fefe"}},{"ruleId":"D2","level":"warning","message":{"text":"code_intel_hook._build_context (cognitive 33): code_intel_hook._build_context has cognitive complexity 33 (threshold 15). Drivers by points: ternaries 7 (13 pts), if/else 9 (12 pts), loops 3 (6 pts), error handling 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":"backend/core/code_intel/code_intel_hook.py"},"region":{"startLine":235}}}],"partialFingerprints":{"codehealthFindingId/v1":"50e3915c08f52335abe1885333432da3ea177dfaef00254b0fa8bd09e23d5b06"}},{"ruleId":"D2","level":"warning","message":{"text":"parser._c_family_declarator_name (cognitive 33): parser._c_family_declarator_name has cognitive complexity 33 (threshold 15). Drivers by points: if/else 8 (24 pts), ternaries 1 (4 pts), loops 2 (3 pts), boolean chains 2 (nesting depth added 20). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/core/code_intel/parser.py"},"region":{"startLine":1292}}}],"partialFingerprints":{"codehealthFindingId/v1":"1180a1bc93ca59a084a4ab5918fcc86bfe0ad1b974b1f2203244e98041ee5ee9"}},{"ruleId":"D2","level":"warning","message":{"text":"ddd_cultivation.backfill_proposals (cognitive 33): ddd_cultivation.backfill_proposals has cognitive complexity 33 (threshold 15). Drivers by points: if/else 7 (14 pts), error handling 4 (13 pts), boolean chains 3, ternaries 1 (2 pts), loops 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":"backend/core/ddd_cultivation.py"},"region":{"startLine":2196}}}],"partialFingerprints":{"codehealthFindingId/v1":"30f7f693d8271143f8fa8d08bfe34fea7dfe871ee896ea2918690b3e2fe34756"}},{"ruleId":"D2","level":"warning","message":{"text":"knowledge_store.sync_knowledge_index (cognitive 33): knowledge_store.sync_knowledge_index has cognitive complexity 33 (threshold 15). Drivers by points: if/else 9 (19 pts), loops 6 (9 pts), boolean chains 3, error handling 1 (2 pts) (nesting depth added 14). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/core/knowledge_store.py"},"region":{"startLine":737}}}],"partialFingerprints":{"codehealthFindingId/v1":"d4292aee9a07dae5a8ad926ba2a5b7521fdc9c4af686b9c4471cd4b550cdd7e6"}},{"ruleId":"D2","level":"warning","message":{"text":"persist_routing.classify_content (cognitive 33): persist_routing.classify_content has cognitive complexity 33 (threshold 15). Drivers by points: if/else 15 (20 pts), boolean chains 9, ternaries 2 (4 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":"backend/core/persist_routing.py"},"region":{"startLine":248}}}],"partialFingerprints":{"codehealthFindingId/v1":"8ab1edc6bf1f84e03e59f629d53e2e3aaccefcdc80fb4517cd1c9f409bc1eee2"}},{"ruleId":"D2","level":"warning","message":{"text":"SummarizationPipeline._parse_enrichment (cognitive 33): SummarizationPipeline._parse_enrichment has cognitive complexity 33 (threshold 15). Drivers by points: if/else 10 (15 pts), ternaries 6 (10 pts), boolean chains 4, loops 3, error handling 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":"backend/core/summarization.py"},"region":{"startLine":823}}}],"partialFingerprints":{"codehealthFindingId/v1":"f5d727f6b21194edbd609613b7094c90cc08d56543d78468049ac7300a9842bf"}},{"ruleId":"D2","level":"warning","message":{"text":"SQLiteDatabase._migrate_existing_task_data (cognitive 33): SQLiteDatabase._migrate_existing_task_data has cognitive complexity 33 (threshold 15). Drivers by points: if/else 16 (24 pts), error handling 2 (5 pts), ternaries 3 (4 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":"backend/database/sqlite.py"},"region":{"startLine":3328}}}],"partialFingerprints":{"codehealthFindingId/v1":"7a7d7790025d69628ee0530b33b9536e5940f1c9d6dba47daab10b89ebd01000"}},{"ruleId":"D2","level":"warning","message":{"text":"agents.update_agent (cognitive 33): agents.update_agent has cognitive complexity 33 (threshold 15). Drivers by points: if/else 17 (30 pts), loops 1 (2 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":"backend/routers/agents.py"},"region":{"startLine":168}}}],"partialFingerprints":{"codehealthFindingId/v1":"b4f05d194b6cc87646e0d31d6ebaab19c6e9fbd5a4b52d88db115d275f3b5708"}},{"ruleId":"D2","level":"warning","message":{"text":"pipeline_analytics.generate_report (cognitive 33): pipeline_analytics.generate_report has cognitive complexity 33 (threshold 15). Drivers by points: if/else 13 (17 pts), loops 7 (11 pts), ternaries 3 (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":"backend/scripts/pipeline_analytics.py"},"region":{"startLine":761}}}],"partialFingerprints":{"codehealthFindingId/v1":"2a80e3d0d085455ef654f500053bce2ca8faa1dec420f46a82d351e5263e09a0"}},{"ruleId":"D2","level":"warning","message":{"text":"DOCXSchemaValidator.validate_whitespace_preservation (cognitive 33): DOCXSchemaValidator.validate_whitespace_preservation has cognitive complexity 33 (threshold 15). Drivers by points: if/else 7 (18 pts), ternaries 1 (6 pts), loops 3 (5 pts), boolean chains 2, error handling 1 (2 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":"backend/skills/s_docx/ooxml/scripts/validation/docx.py"},"region":{"startLine":72}}}],"partialFingerprints":{"codehealthFindingId/v1":"16151e65ba85e14afe31b79ab6c33383b299beb659423e1d475f3170d2ef7b05"}},{"ruleId":"D2","level":"warning","message":{"text":"extract_form_field_info.get_field_info (cognitive 33): extract_form_field_info.get_field_info has cognitive complexity 33 (threshold 15). Drivers by points: if/else 8 (24 pts), loops 4 (5 pts), error handling 1 (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":"backend/skills/s_pdf/scripts/extract_form_field_info.py"},"region":{"startLine":62}}}],"partialFingerprints":{"codehealthFindingId/v1":"b4ba2f197c166d5c45415d389a63c938d5f7bc32e95051ab12539ce8bae3e052"}},{"ruleId":"D2","level":"warning","message":{"text":"DOCXSchemaValidator.validate_whitespace_preservation (cognitive 33): DOCXSchemaValidator.validate_whitespace_preservation has cognitive complexity 33 (threshold 15). Drivers by points: if/else 7 (18 pts), ternaries 1 (6 pts), loops 3 (5 pts), boolean chains 2, error handling 1 (2 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":"backend/skills/s_pptx/ooxml/scripts/validation/docx.py"},"region":{"startLine":72}}}],"partialFingerprints":{"codehealthFindingId/v1":"493a08640b3b66cc31030e65e85142a2ef302640dbe0551a1fd1daba66ddf361"}},{"ruleId":"D2","level":"warning","message":{"text":"rearrange.rearrange_presentation (cognitive 33): rearrange.rearrange_presentation has cognitive complexity 33 (threshold 15). Drivers by points: if/else 8 (15 pts), loops 6 (10 pts), boolean chains 5, ternaries 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":"backend/skills/s_pptx/scripts/rearrange.py"},"region":{"startLine":149}}}],"partialFingerprints":{"codehealthFindingId/v1":"0a097f943cc1ac604df0406f96ca3c47ca659a0c56bc9928fdfe476bba41bded"}},{"ruleId":"D2","level":"warning","message":{"text":"swarmai::sync_daemon_version (cognitive 33): swarmai::sync_daemon_version has cognitive complexity 33 (threshold 15). Drivers by points: if/else 14 (26 pts), loops 2 (6 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":"desktop/src-tauri/src/lib.rs"},"region":{"startLine":1130}}}],"partialFingerprints":{"codehealthFindingId/v1":"d26848e83b6b91ff9eb0af004220295d41f45c25e6da207d3da561daf5c133da"}},{"ruleId":"D2","level":"warning","message":{"text":"context_injector._extract_files_touched (cognitive 32): context_injector._extract_files_touched has cognitive complexity 32 (threshold 15). Drivers by points: if/else 4 (17 pts), loops 3 (6 pts), ternaries 1 (6 pts), boolean chains 2, 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":"backend/core/context_injector.py"},"region":{"startLine":271}}}],"partialFingerprints":{"codehealthFindingId/v1":"42df3e8b8624c1ced87bfcfe4d72fa73a242888594a6f8c07c1e5cc2425cf0c3"}},{"ruleId":"D2","level":"warning","message":{"text":"context_injector._extract_git_activity (cognitive 32): context_injector._extract_git_activity has cognitive complexity 32 (threshold 15). Drivers by points: if/else 8 (26 pts), loops 2 (3 pts), boolean chains 2, error handling 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":"backend/core/context_injector.py"},"region":{"startLine":324}}}],"partialFingerprints":{"codehealthFindingId/v1":"70173ba60613d61dccc10313cc9354cfb73352841db2454f0fe4d7ed2eacb746"}},{"ruleId":"D2","level":"warning","message":{"text":"context_injector.build_resume_context (cognitive 32): context_injector.build_resume_context has cognitive complexity 32 (threshold 15). Drivers by points: if/else 15 (23 pts), ternaries 4 (5 pts), boolean chains 2, error handling 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":"backend/core/context_injector.py"},"region":{"startLine":1139}}}],"partialFingerprints":{"codehealthFindingId/v1":"65eccaecd8826c4b545f33bf08de8cc8ea465c1d75695544566a0956995c5801"}},{"ruleId":"D2","level":"warning","message":{"text":"ddd_entry_lifecycle._strip_entries_by_line (cognitive 32): ddd_entry_lifecycle._strip_entries_by_line has cognitive complexity 32 (threshold 15). Drivers by points: if/else 8 (24 pts), boolean chains 4, loops 2 (4 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":"backend/core/ddd_entry_lifecycle.py"},"region":{"startLine":1857}}}],"partialFingerprints":{"codehealthFindingId/v1":"4e2e4b4414c800e1c12f76d9b8e4cb709cfa3cd0f5811dbb77c28a5cc6a75dd2"}},{"ruleId":"D2","level":"warning","message":{"text":"file_change_classifier.parse_bash_write_targets (cognitive 32): file_change_classifier.parse_bash_write_targets has cognitive complexity 32 (threshold 15). Drivers by points: if/else 8 (23 pts), loops 3 (5 pts), boolean chains 3, error handling 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":"backend/core/file_change_classifier.py"},"region":{"startLine":73}}}],"partialFingerprints":{"codehealthFindingId/v1":"eb30224d4e745636368d6c8443514c772affd251714d4797127d665a5d90efed"}},{"ruleId":"D2","level":"warning","message":{"text":"bedrock._resolve_credentials (cognitive 32): bedrock._resolve_credentials has cognitive complexity 32 (threshold 15). Drivers by points: if/else 8 (19 pts), error handling 3 (5 pts), loops 2 (5 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":"backend/jobs/bedrock.py"},"region":{"startLine":62}}}],"partialFingerprints":{"codehealthFindingId/v1":"697346c23dbdf04f8e69266b615a963fd8d013b4e786d61d882057899d18e70b"}},{"ruleId":"D2","level":"warning","message":{"text":"settings.update_app_configuration (cognitive 32): settings.update_app_configuration has cognitive complexity 32 (threshold 15). Drivers by points: if/else 16 (24 pts), boolean chains 6, error handling 1, 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":"backend/routers/settings.py"},"region":{"startLine":263}}}],"partialFingerprints":{"codehealthFindingId/v1":"57398780cecfa2bcc3b60c258a11686d00f6ec6adcd733ca3701cc3e38c068e5"}},{"ruleId":"D2","level":"warning","message":{"text":"artifact_cli.cmd_run_analytics (cognitive 32): artifact_cli.cmd_run_analytics has cognitive complexity 32 (threshold 15). Drivers by points: if/else 12 (15 pts), ternaries 7, error handling 2 (5 pts), loops 4 (5 pts) (nesting depth added 7). 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":"backend/scripts/artifact_cli.py"},"region":{"startLine":5272}}}],"partialFingerprints":{"codehealthFindingId/v1":"ced00a59136b7f82c3336cc7e88dd9bc08cf5a0ebc15ffec0f378e31d12a0e9b"}},{"ruleId":"D2","level":"warning","message":{"text":"eval_runner._load_rules_context (cognitive 32): eval_runner._load_rules_context has cognitive complexity 32 (threshold 15). Drivers by points: if/else 9 (20 pts), loops 3 (9 pts), boolean chains 1, error handling 1, ternaries 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":"backend/scripts/eval_runner.py"},"region":{"startLine":803}}}],"partialFingerprints":{"codehealthFindingId/v1":"1a71c2f6fd3bb1ac2773882a461d4c013e0f6f394c23b0025e3a100f2831554a"}},{"ruleId":"D2","level":"warning","message":{"text":"pipeline_validator._parse_failed_patterns (cognitive 32): pipeline_validator._parse_failed_patterns has cognitive complexity 32 (threshold 15). Drivers by points: if/else 8 (24 pts), loops 2 (5 pts), boolean chains 3 (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":"backend/scripts/pipeline_validator.py"},"region":{"startLine":1745}}}],"partialFingerprints":{"codehealthFindingId/v1":"78ba7d91a1029d5df84440841d862ccdad0dea3fe74bc825cdc86cd5cf6a7431"}},{"ruleId":"D2","level":"warning","message":{"text":"Document._update_settings (cognitive 32): Document._update_settings has cognitive complexity 32 (threshold 15). Drivers by points: if/else 13 (28 pts), loops 1 (3 pts), ternaries 1 (nesting depth added 17). 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":"backend/skills/s_docx/scripts/document.py"},"region":{"startLine":988}}}],"partialFingerprints":{"codehealthFindingId/v1":"089b6a1798c9ac86a451b41e6bd8b93abc454d393c01a81ad53d8f28913b67e6"}},{"ruleId":"D2","level":"warning","message":{"text":"check_bounding_boxes.get_bounding_box_messages (cognitive 32): check_bounding_boxes.get_bounding_box_messages has cognitive complexity 32 (threshold 15). Drivers by points: if/else 9 (27 pts), loops 3 (4 pts), boolean chains 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":"backend/skills/s_pdf/scripts/check_bounding_boxes.py"},"region":{"startLine":18}}}],"partialFingerprints":{"codehealthFindingId/v1":"0c1113ae21867cb94868019cc1436ab9e2a9da5cf1da85925f5f36223bff9c4a"}},{"ruleId":"D2","level":"warning","message":{"text":"publish_dashboard.generate_markdown (cognitive 32): publish_dashboard.generate_markdown has cognitive complexity 32 (threshold 15). Drivers by points: if/else 5 (11 pts), loops 7 (10 pts), ternaries 4 (10 pts), boolean chains 1 (nesting depth added 15). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/skills/s_pollinate/scripts/publish_dashboard.py"},"region":{"startLine":114}}}],"partialFingerprints":{"codehealthFindingId/v1":"36118b1591f96ab1c2f2fec2907a428fb908b9edba723995b442ab37fee22ba0"}},{"ruleId":"D2","level":"warning","message":{"text":"ai_ready_helpers.generate_learning_tour (cognitive 32): ai_ready_helpers.generate_learning_tour has cognitive complexity 32 (threshold 15). Drivers by points: if/else 10 (22 pts), loops 7 (9 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":"backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py"},"region":{"startLine":2862}}}],"partialFingerprints":{"codehealthFindingId/v1":"7946fc49e90c8056f8facbf5bdbe0ba296e52b26b24a90e113cb14131e2b4771"}},{"ruleId":"D2","level":"warning","message":{"text":"ai_ready_helpers.generate_learning_tour (cognitive 32): ai_ready_helpers.generate_learning_tour has cognitive complexity 32 (threshold 15). Drivers by points: if/else 10 (22 pts), loops 7 (9 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":"backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py"},"region":{"startLine":2515}}}],"partialFingerprints":{"codehealthFindingId/v1":"07bf1f527547557cef7b5c8f2269f0851bab0bde9dff4cc51f2f0d8fa244f566"}},{"ruleId":"D2","level":"warning","message":{"text":"InlinePermissionRequest.InlinePermissionRequest (cognitive 32): InlinePermissionRequest.InlinePermissionRequest has cognitive complexity 32 (threshold 15). Drivers by points: ternaries 7 (14 pts), if/else 10, boolean chains 8 (nesting depth added 7). Of this number, 20 points are the body\u0027s own statements and 12 belong to 6 function literals inside it that branch. To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/pages/chat/components/InlinePermissionRequest.tsx"},"region":{"startLine":40}}}],"partialFingerprints":{"codehealthFindingId/v1":"421c507efbaf47299293983c93a7e81cd002644c58111910ac3bc01e9f09c291"}},{"ruleId":"D2","level":"warning","message":{"text":"ChannelsTab.ChannelsTab (cognitive 32): ChannelsTab.ChannelsTab has cognitive complexity 32 (threshold 15). Drivers by points: boolean chains 14, ternaries 6 (14 pts), error handling 3, if/else 1 (nesting depth added 8). Of this number, 25 points are the body\u0027s own statements and 7 belong to 3 function literals inside it that branch. 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":"desktop/src/components/settings/ChannelsTab.tsx"},"region":{"startLine":13}}}],"partialFingerprints":{"codehealthFindingId/v1":"c7cdc110dabb60b84a3b79b5aed945d40a510e6ed0ab0dfc0d7f1f50dfc42ab4"}},{"ruleId":"D2","level":"warning","message":{"text":"OverlayHost.OverlayHost (cognitive 32): OverlayHost.OverlayHost has cognitive complexity 32 (threshold 15). Drivers by points: if/else 18 (23 pts), boolean chains 5, ternaries 4 (nesting depth added 5). Most of this is not in the body itself: 8 of the 32 points are its own statements and the rest belongs to 8 function literals inside it that branch (lines 77, 153, 106, \u2026). The decisions are inside those literals, which nothing outside this body can call, review or test on its own, so splitting the enclosing body is not the move available here. To reduce it, lift the literals\u0027 work into a named function or method at the enclosing scope and have each literal call it, then reduce whichever part then reads as the largest."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/layout/OverlayHost.tsx"},"region":{"startLine":58}}}],"partialFingerprints":{"codehealthFindingId/v1":"1ed99eff81393e84d45ca5a585224c6885de5e1638c8df525aba161be193880f"}},{"ruleId":"D2","level":"warning","message":{"text":"ddd_maturity.update_evidence_from_changelog (cognitive 31): ddd_maturity.update_evidence_from_changelog has cognitive complexity 31 (threshold 15). Drivers by points: if/else 10 (26 pts), loops 2 (3 pts), error handling 1 (2 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":"backend/core/ddd_maturity.py"},"region":{"startLine":459}}}],"partialFingerprints":{"codehealthFindingId/v1":"2ed5a64cc6be0bcf2c5925610af8aa8fc34811896452e587d2c984a26d258a93"}},{"ruleId":"D2","level":"warning","message":{"text":"recall_multi._render_domain_hits (cognitive 31): recall_multi._render_domain_hits has cognitive complexity 31 (threshold 15). Drivers by points: if/else 8 (21 pts), boolean chains 6, ternaries 1 (3 pts), 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":"backend/core/recall_multi.py"},"region":{"startLine":625}}}],"partialFingerprints":{"codehealthFindingId/v1":"9aa4f46ab287d9bdd22dba7dc1e6162ddd1817939c0c6a65fe6d71bca3b81515"}},{"ruleId":"D2","level":"warning","message":{"text":"SQLiteDatabase._run_legacy_migrations (cognitive 31): SQLiteDatabase._run_legacy_migrations has cognitive complexity 31 (threshold 15). Drivers by points: if/else 23 (25 pts), error handling 3 (4 pts), 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."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/database/sqlite.py"},"region":{"startLine":2885}}}],"partialFingerprints":{"codehealthFindingId/v1":"271af18e63c21b8b9b6c38ee19a8d113802a5cd17a7e43f2e55005bc62d2a706"}},{"ruleId":"D2","level":"warning","message":{"text":"ContextHealthHook._enforce_retention_policies (cognitive 31): ContextHealthHook._enforce_retention_policies has cognitive complexity 31 (threshold 15). Drivers by points: if/else 8 (21 pts), error handling 2 (6 pts), loops 2 (4 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":"backend/hooks/context_health_hook.py"},"region":{"startLine":3410}}}],"partialFingerprints":{"codehealthFindingId/v1":"3a6de088a02a31d6fcbf8fea4105d3d3770930ec787fe368bcc9becf6a382ec4"}},{"ruleId":"D2","level":"warning","message":{"text":"EvolutionMaintenanceHook.execute (cognitive 31): EvolutionMaintenanceHook.execute has cognitive complexity 31 (threshold 15). Drivers by points: if/else 9 (12 pts), error handling 6 (8 pts), loops 4 (6 pts), boolean chains 3, ternaries 1 (2 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":"backend/hooks/evolution_maintenance_hook.py"},"region":{"startLine":196}}}],"partialFingerprints":{"codehealthFindingId/v1":"5daad703f5ffb7f36ff48ff31e1a98e034b33b20c8e885f0dc9f2f401859933b"}},{"ruleId":"D2","level":"warning","message":{"text":"executor._handle_agent_task (cognitive 31): executor._handle_agent_task has cognitive complexity 31 (threshold 15). Drivers by points: if/else 15 (16 pts), error handling 4 (6 pts), boolean chains 4, ternaries 3 (4 pts), loops 1 (nesting depth added 4). To reduce it, split the body: most of this score is breadth rather than depth \u2014 checks laid out side by side rather than stacked \u2014 so group the statements between the checks into named steps and move each step into its own function. Some of it IS depth: where a check sits inside another whose only job is to reach it, merge the two into one condition, 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":"backend/jobs/executor.py"},"region":{"startLine":739}}}],"partialFingerprints":{"codehealthFindingId/v1":"e77d3c8c01793c560a5ff26d911ad8ed2129e0a0b44f093ad8b321a922354c23"}},{"ruleId":"D2","level":"warning","message":{"text":"font_link_backfill.main (cognitive 31): font_link_backfill.main has cognitive complexity 31 (threshold 15). Drivers by points: if/else 13 (23 pts), loops 5 (6 pts), ternaries 1 (2 pts) (nesting depth added 12). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/skills/s_pollinate/scripts/font_link_backfill.py"},"region":{"startLine":94}}}],"partialFingerprints":{"codehealthFindingId/v1":"dac4c4a7ad33cd72d056f653a5047c9db8a5fbceae80358afb30ab874af1e6f8"}},{"ruleId":"D2","level":"warning","message":{"text":"publish_dashboard.generate_html (cognitive 31): publish_dashboard.generate_html has cognitive complexity 31 (threshold 15). Drivers by points: if/else 7 (18 pts), loops 5 (6 pts), boolean chains 3, error handling 1 (3 pts), ternaries 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":"backend/skills/s_pollinate/scripts/publish_dashboard.py"},"region":{"startLine":194}}}],"partialFingerprints":{"codehealthFindingId/v1":"fecc6f2193f07233ed6be79feac4289cddc25f522c033b310cfe9643e1e633b8"}},{"ruleId":"D2","level":"warning","message":{"text":"ai_ready_helpers._validate_v3_domain_layer (cognitive 31): ai_ready_helpers._validate_v3_domain_layer has cognitive complexity 31 (threshold 15). Drivers by points: if/else 7 (17 pts), loops 7 (10 pts), ternaries 3, 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":"backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py"},"region":{"startLine":213}}}],"partialFingerprints":{"codehealthFindingId/v1":"707890141b66ab903bb1c73ff942c831c745805f9f3e6d97b0ec426e766bb4eb"}},{"ruleId":"D2","level":"warning","message":{"text":"ai_ready_helpers._render_domain_skeleton_body (cognitive 31): ai_ready_helpers._render_domain_skeleton_body has cognitive complexity 31 (threshold 15). Drivers by points: if/else 7 (11 pts), boolean chains 10, loops 5 (6 pts), ternaries 2 (4 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":"backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py"},"region":{"startLine":1568}}}],"partialFingerprints":{"codehealthFindingId/v1":"3ff04ac4ee9eee8e96859a094c92eaa59ab65c7c80ecaee8c897e7d643752732"}},{"ruleId":"D2","level":"warning","message":{"text":"ai_ready_helpers._validate_v3_domain_layer (cognitive 31): ai_ready_helpers._validate_v3_domain_layer has cognitive complexity 31 (threshold 15). Drivers by points: if/else 7 (17 pts), loops 7 (10 pts), ternaries 3, 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":"backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py"},"region":{"startLine":212}}}],"partialFingerprints":{"codehealthFindingId/v1":"c84a4621520c44947aae78f2d37368bc414be9274e5551143af0aca6abc8f68e"}},{"ruleId":"D2","level":"warning","message":{"text":"ai_ready_helpers.project_domain_skeleton (cognitive 31): ai_ready_helpers.project_domain_skeleton has cognitive complexity 31 (threshold 15). Drivers by points: if/else 7 (11 pts), boolean chains 10, loops 5 (6 pts), ternaries 2 (4 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":"backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py"},"region":{"startLine":1225}}}],"partialFingerprints":{"codehealthFindingId/v1":"3d938f6dec1e558f1630b009d02e1586ec23d53aed22a9615e5f77c20cf5bc9a"}},{"ruleId":"D2","level":"warning","message":{"text":"NewBrainOverlay.NewBrainContent (cognitive 31): NewBrainOverlay.NewBrainContent has cognitive complexity 31 (threshold 15). Drivers by points: if/else 9 (11 pts), ternaries 8 (11 pts), boolean chains 4, error handling 3 (4 pts), loops 1 (nesting depth added 6). Most of this is not in the body itself: 1 of the 31 points is its own statement and the rest belongs to 9 function literals inside it that branch (lines 215, 142, 185, \u2026). The decisions are inside those literals, which nothing outside this body can call, review or test on its own, so splitting the enclosing body is not the move available here. To reduce it, lift the literals\u0027 work into a named function or method at the enclosing scope and have each literal call it, then reduce whichever part then reads as the largest."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/layout/NewBrainOverlay.tsx"},"region":{"startLine":92}}}],"partialFingerprints":{"codehealthFindingId/v1":"156a953e7217ef13162b1a4a19b0cce457bcc8cba913ac7032e70966b30fa8cc"}},{"ruleId":"D2","level":"warning","message":{"text":"EvalDashboard.GuideTab (cognitive 31): EvalDashboard.GuideTab has cognitive complexity 31 (threshold 15). Drivers by points: ternaries 24 (30 pts), boolean chains 1 (nesting depth added 6). Of this number, 20 points are the body\u0027s own statements and 11 belong to one function literal inside it that branches. 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":"desktop/src/pages/EvalDashboard.tsx"},"region":{"startLine":1698}}}],"partialFingerprints":{"codehealthFindingId/v1":"f5a610fdc2dfefc24f0f1b96e542856869ae8756c2b213615864b23b83b5eec1"}},{"ruleId":"D2","level":"warning","message":{"text":"FileViewerPanel.FileViewerPanelImpl (cognitive 31): FileViewerPanel.FileViewerPanelImpl has cognitive complexity 31 (threshold 15). Drivers by points: boolean chains 15, if/else 11, ternaries 5. Of this number, 19 points are the body\u0027s own statements and 12 belong to 7 function literals inside it that branch. 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":"desktop/src/components/file-viewer/FileViewerPanel.tsx"},"region":{"startLine":139}}}],"partialFingerprints":{"codehealthFindingId/v1":"5a24aad45e87228962ed036c70e7ff0e7dbbd5d9147342963ed1de4b600b6a38"}},{"ruleId":"D2","level":"warning","message":{"text":"ddd_entry_lifecycle.assess_decay (cognitive 30): ddd_entry_lifecycle.assess_decay has cognitive complexity 30 (threshold 15). Drivers by points: if/else 12 (25 pts), boolean chains 2, ternaries 1 (2 pts), loops 1 (nesting depth added 14). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/core/ddd_entry_lifecycle.py"},"region":{"startLine":855}}}],"partialFingerprints":{"codehealthFindingId/v1":"caf4948e9b9021b39c0bb391c59eedc2d5ed0ae5f165efc8e66ebbf48d8a43d8"}},{"ruleId":"D2","level":"warning","message":{"text":"mcp_config_loader.add_mcp_server_to_dict (cognitive 30): mcp_config_loader.add_mcp_server_to_dict has cognitive complexity 30 (threshold 15). Drivers by points: if/else 7 (18 pts), loops 4 (7 pts), boolean chains 5 (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":"backend/core/mcp_config_loader.py"},"region":{"startLine":303}}}],"partialFingerprints":{"codehealthFindingId/v1":"b282dbf5214ebc9c9dad0f7d1b799b2e1ae86d67e58ca4454dc1af83877bf1a6"}},{"ruleId":"D2","level":"warning","message":{"text":"PluginManager.list_cached_plugins (cognitive 30): PluginManager.list_cached_plugins has cognitive complexity 30 (threshold 15). Drivers by points: if/else 7 (18 pts), error handling 1 (5 pts), loops 4 (5 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":"backend/core/plugin_manager.py"},"region":{"startLine":954}}}],"partialFingerprints":{"codehealthFindingId/v1":"0e8eb7b0b9630e515f21d63d41d3b085b510aaa4f6782e2e222bb669b6828b1a"}},{"ruleId":"D2","level":"warning","message":{"text":"SkillManager._scan_tier (cognitive 30): SkillManager._scan_tier has cognitive complexity 30 (threshold 15). Drivers by points: if/else 10 (18 pts), error handling 6 (10 pts), boolean chains 1, 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":"backend/core/skill_manager.py"},"region":{"startLine":576}}}],"partialFingerprints":{"codehealthFindingId/v1":"36939d12ed9f8ccc0ca0b52534ae8f051ed5ae2773d9f395ed3d897976ba2e55"}},{"ruleId":"D2","level":"warning","message":{"text":"DistillationTriggerHook._supersede_by_topic (cognitive 30): DistillationTriggerHook._supersede_by_topic has cognitive complexity 30 (threshold 15). Drivers by points: if/else 9 (18 pts), ternaries 2 (6 pts), loops 3 (4 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":"backend/hooks/distillation_hook.py"},"region":{"startLine":1276}}}],"partialFingerprints":{"codehealthFindingId/v1":"af0a3f5e6ad967080a8ced881531b392cc303a5798dce54db813103e16232172"}},{"ruleId":"D2","level":"warning","message":{"text":"eval_runner.eval_trajectory (cognitive 30): eval_runner.eval_trajectory has cognitive complexity 30 (threshold 15). Drivers by points: if/else 10 (21 pts), loops 4 (9 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":"backend/scripts/eval_runner.py"},"region":{"startLine":440}}}],"partialFingerprints":{"codehealthFindingId/v1":"1e404a479d3d731bc1ec105ee2af910a7d33ea807afb8629c30277bae62ac972"}},{"ruleId":"D2","level":"warning","message":{"text":"pipeline_validator._check_security_boundaries (cognitive 30): pipeline_validator._check_security_boundaries has cognitive complexity 30 (threshold 15). Drivers by points: if/else 11 (19 pts), boolean chains 5, ternaries 4 (5 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":"backend/scripts/pipeline_validator.py"},"region":{"startLine":1124}}}],"partialFingerprints":{"codehealthFindingId/v1":"f7e2e7d9fc3b5955bd9995f45cb7d4aed5fdc00900c1039d179c5075e0949a82"}},{"ruleId":"D2","level":"warning","message":{"text":"PPTXSchemaValidator.validate_uuid_ids (cognitive 30): PPTXSchemaValidator.validate_uuid_ids has cognitive complexity 30 (threshold 15). Drivers by points: if/else 6 (19 pts), loops 4 (8 pts), error handling 1 (2 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":"backend/skills/s_docx/ooxml/scripts/validation/pptx.py"},"region":{"startLine":77}}}],"partialFingerprints":{"codehealthFindingId/v1":"6791d87aa33d05b4eb86c538d1ae7b046d299fa30961ed61b77af7fa3c72ed4d"}},{"ruleId":"D2","level":"warning","message":{"text":"SelfLoopsHealthEngine._auto_remediate (cognitive 30): SelfLoopsHealthEngine._auto_remediate has cognitive complexity 30 (threshold 15). Drivers by points: if/else 10 (26 pts), error handling 1 (2 pts), boolean chains 1, loops 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":"backend/skills/s_loops-health/scripts/loops_health_check.py"},"region":{"startLine":692}}}],"partialFingerprints":{"codehealthFindingId/v1":"4156b82cc21be1d23ebf0555768a119109dba814572512d4075b863cc7eae552"}},{"ruleId":"D2","level":"warning","message":{"text":"format_recommend.recommend (cognitive 30): format_recommend.recommend has cognitive complexity 30 (threshold 15). Drivers by points: if/else 11 (21 pts), loops 3 (5 pts), boolean chains 3, 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":"backend/skills/s_pollinate/scripts/format_recommend.py"},"region":{"startLine":158}}}],"partialFingerprints":{"codehealthFindingId/v1":"1e669e4997513d4d63d3fabe96beeaa12376b45231b50a6d08deaee9a4d2314b"}},{"ruleId":"D2","level":"warning","message":{"text":"generate_tts.main (cognitive 30): generate_tts.main has cognitive complexity 30 (threshold 15). Drivers by points: if/else 16 (20 pts), loops 3 (5 pts), ternaries 1 (3 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":"backend/skills/s_pollinate/scripts/generate_tts.py"},"region":{"startLine":109}}}],"partialFingerprints":{"codehealthFindingId/v1":"b598f369b42df244248028aa1108b909ed71eb8a5abbc9dda4a1131eada59dc8"}},{"ruleId":"D2","level":"warning","message":{"text":"publish_meta.generate_publish_info (cognitive 30): publish_meta.generate_publish_info has cognitive complexity 30 (threshold 15). Drivers by points: if/else 9 (19 pts), loops 2 (5 pts), boolean chains 3, 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":"backend/skills/s_pollinate/scripts/publish_meta.py"},"region":{"startLine":143}}}],"partialFingerprints":{"codehealthFindingId/v1":"8466e4bf9e3ade1ce3dc907d16ad1553353986109010f9a08dd7417f9bd00c8b"}},{"ruleId":"D2","level":"warning","message":{"text":"PPTXSchemaValidator.validate_uuid_ids (cognitive 30): PPTXSchemaValidator.validate_uuid_ids has cognitive complexity 30 (threshold 15). Drivers by points: if/else 6 (19 pts), loops 4 (8 pts), error handling 1 (2 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":"backend/skills/s_pptx/ooxml/scripts/validation/pptx.py"},"region":{"startLine":77}}}],"partialFingerprints":{"codehealthFindingId/v1":"4c001d9475a11dfb1a23670b6f356aebd94174cb1dbcc577a6a2221ee17076d5"}},{"ruleId":"D2","level":"warning","message":{"text":"ai_ready_helpers.run_multi_package (cognitive 30): ai_ready_helpers.run_multi_package has cognitive complexity 30 (threshold 15). Drivers by points: if/else 7 (13 pts), loops 6 (11 pts), boolean chains 2, error handling 1 (2 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":"backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py"},"region":{"startLine":2948}}}],"partialFingerprints":{"codehealthFindingId/v1":"a6f8a77c18e042bc95bb845df4ec5ad8da9a1995498a3fc25e819e2f6b63f8f6"}},{"ruleId":"D2","level":"warning","message":{"text":"ai_ready_helpers.run_multi_package (cognitive 30): ai_ready_helpers.run_multi_package has cognitive complexity 30 (threshold 15). Drivers by points: if/else 7 (13 pts), loops 6 (11 pts), boolean chains 2, error handling 1 (2 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":"backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py"},"region":{"startLine":2601}}}],"partialFingerprints":{"codehealthFindingId/v1":"88f3fb4bb933acc84736091ed70ca1e643c6b428244841e12055607d5efb1754"}},{"ruleId":"D2","level":"warning","message":{"text":"HistoryView.HistoryView (cognitive 30): HistoryView.HistoryView has cognitive complexity 30 (threshold 15). Drivers by points: ternaries 10 (20 pts), boolean chains 6, if/else 4 (nesting depth added 10). Of this number, 20 points are the body\u0027s own statements and 10 belong to 5 function literals inside it that branch. To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/pages/chat/components/RightSidebar/HistoryView.tsx"},"region":{"startLine":34}}}],"partialFingerprints":{"codehealthFindingId/v1":"2bd690b74d9b2b691e9af62c2b61a9406db826043056734e57d19f1aeea42e1f"}},{"ruleId":"D2","level":"warning","message":{"text":"OnboardingPage.OnboardingPage (cognitive 30): OnboardingPage.OnboardingPage has cognitive complexity 30 (threshold 15). Drivers by points: if/else 8 (11 pts), boolean chains 9, ternaries 5 (6 pts), error handling 3 (4 pts) (nesting depth added 5). Most of this is not in the body itself: 7 of the 30 points are its own statements and the rest belongs to 7 function literals inside it that branch (lines 59, 144, 58, \u2026). The decisions are inside those literals, which nothing outside this body can call, review or test on its own, so splitting the enclosing body is not the move available here. To reduce it, lift the literals\u0027 work into a named function or method at the enclosing scope and have each literal call it, then reduce whichever part then reads as the largest."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/pages/OnboardingPage.tsx"},"region":{"startLine":40}}}],"partialFingerprints":{"codehealthFindingId/v1":"6439b5004698111d8b92b5f0d844448ecfd61edc40996474ce818033876f017f"}},{"ruleId":"D2","level":"warning","message":{"text":"ddd_cultivation.detect_contradiction (cognitive 29): ddd_cultivation.detect_contradiction has cognitive complexity 29 (threshold 15). Drivers by points: if/else 12 (16 pts), boolean chains 7, loops 4 (5 pts), error handling 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":"backend/core/ddd_cultivation.py"},"region":{"startLine":1446}}}],"partialFingerprints":{"codehealthFindingId/v1":"f5110b7ddfdf5b7230472182a24f3e623ba254c37c6789affb560d5a6d833729"}},{"ruleId":"D2","level":"warning","message":{"text":"ddd_entry_lifecycle.bump_references (cognitive 29): ddd_entry_lifecycle.bump_references has cognitive complexity 29 (threshold 15). Drivers by points: if/else 7 (15 pts), loops 3 (6 pts), error handling 2 (5 pts), boolean chains 3 (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":"backend/core/ddd_entry_lifecycle.py"},"region":{"startLine":783}}}],"partialFingerprints":{"codehealthFindingId/v1":"b86f6a8b73b1a6f03c12f93e4093bc76d9066d7ccafcffb4c10ade7413c17ff2"}},{"ruleId":"D2","level":"warning","message":{"text":"knowledge_store.chunk_markdown (cognitive 29): knowledge_store.chunk_markdown has cognitive complexity 29 (threshold 15). Drivers by points: if/else 8 (16 pts), loops 2 (5 pts), ternaries 2 (5 pts), boolean chains 3 (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":"backend/core/knowledge_store.py"},"region":{"startLine":67}}}],"partialFingerprints":{"codehealthFindingId/v1":"53d1d26c15b80e8b8239fa5d489e7773740bba5387b26d1ef7bb4285f33833d4"}},{"ruleId":"D2","level":"warning","message":{"text":"SessionUnit._check_mcp_health (cognitive 29): SessionUnit._check_mcp_health has cognitive complexity 29 (threshold 15). Drivers by points: if/else 13 (21 pts), boolean chains 5, 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":"backend/core/session_unit.py"},"region":{"startLine":3111}}}],"partialFingerprints":{"codehealthFindingId/v1":"b61a8d6f3d844c4a2c87c49f5ac3433eb2cb876d17495925fe138b3cb9bb521c"}},{"ruleId":"D2","level":"warning","message":{"text":"SwarmWorkspaceManager._seed_hive_from_package (cognitive 29): SwarmWorkspaceManager._seed_hive_from_package has cognitive complexity 29 (threshold 15). Drivers by points: if/else 10 (21 pts), boolean chains 4, loops 2 (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":"backend/core/swarm_workspace_manager.py"},"region":{"startLine":1243}}}],"partialFingerprints":{"codehealthFindingId/v1":"11989db0361b25523e3f6c0b3f87921889f783cb1b555ca208c71637f5a21b08"}},{"ruleId":"D2","level":"warning","message":{"text":"ui_actions.format_attention_for_agent (cognitive 29): ui_actions.format_attention_for_agent has cognitive complexity 29 (threshold 15). Drivers by points: if/else 6 (15 pts), loops 4 (8 pts), ternaries 2 (3 pts), boolean chains 2, error handling 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":"backend/core/ui_actions.py"},"region":{"startLine":773}}}],"partialFingerprints":{"codehealthFindingId/v1":"62a0a6fca600389667dfc7f338e482e7de3d6a4892efa335b17bec03b079fe63"}},{"ruleId":"D2","level":"warning","message":{"text":"EvolutionMaintenanceHook._size_evict_locked (cognitive 29): EvolutionMaintenanceHook._size_evict_locked has cognitive complexity 29 (threshold 15). Drivers by points: if/else 8 (16 pts), loops 5 (6 pts), ternaries 2 (5 pts), error handling 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":"backend/hooks/evolution_maintenance_hook.py"},"region":{"startLine":793}}}],"partialFingerprints":{"codehealthFindingId/v1":"f20231eddd81a721398a97e84dc34a57fb408b550ad23460f0221424aef3842f"}},{"ruleId":"D2","level":"warning","message":{"text":"swarmai_monthly_report._collect_pipeline_metrics (cognitive 29): swarmai_monthly_report._collect_pipeline_metrics has cognitive complexity 29 (threshold 15). Drivers by points: if/else 8 (17 pts), loops 3 (5 pts), error handling 2 (4 pts), boolean chains 2, ternaries 1 (nesting depth added 13). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/jobs/handlers/swarmai_monthly_report.py"},"region":{"startLine":153}}}],"partialFingerprints":{"codehealthFindingId/v1":"e1373a4fcf4ee64a55d9c2647d03094756a84c842a183a1ed0b4b8bede090228"}},{"ruleId":"D2","level":"warning","message":{"text":"job_manager.cmd_edit (cognitive 29): job_manager.cmd_edit has cognitive complexity 29 (threshold 15). Drivers by points: if/else 9 (24 pts), loops 2 (4 pts), error handling 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":"backend/jobs/job_manager.py"},"region":{"startLine":210}}}],"partialFingerprints":{"codehealthFindingId/v1":"add0661b57d399ab2f1c5281ed34a918904dea42ee486e74e0768b094bbaa6ff"}},{"ruleId":"D2","level":"warning","message":{"text":"artifact_cli._lookup_already_committed (cognitive 29): artifact_cli._lookup_already_committed has cognitive complexity 29 (threshold 15). Drivers by points: if/else 8 (18 pts), loops 4 (6 pts), error handling 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":"backend/scripts/artifact_cli.py"},"region":{"startLine":2852}}}],"partialFingerprints":{"codehealthFindingId/v1":"c7168f77dd47ef44e0dd9b8060477ed9de6eaad51e0933c00ebbaf5b8b0b0d18"}},{"ruleId":"D2","level":"warning","message":{"text":"artifact_cli.cmd_release_gate (cognitive 29): artifact_cli.cmd_release_gate has cognitive complexity 29 (threshold 15). Drivers by points: if/else 11 (13 pts), ternaries 4 (7 pts), error handling 4 (6 pts), boolean chains 3 (nesting depth added 7). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/scripts/artifact_cli.py"},"region":{"startLine":3258}}}],"partialFingerprints":{"codehealthFindingId/v1":"94cd2b19dd29b9f05780b42cc054e59585b5b8e98bf882c5e4bf635d4037cfa7"}},{"ruleId":"D2","level":"warning","message":{"text":"pipeline_validator._check_output_routing (cognitive 29): pipeline_validator._check_output_routing has cognitive complexity 29 (threshold 15). Drivers by points: if/else 10 (23 pts), loops 2 (4 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":"backend/scripts/pipeline_validator.py"},"region":{"startLine":2424}}}],"partialFingerprints":{"codehealthFindingId/v1":"0cc47d4e300e591088632f78b4a4061243c488297c5661d298bc158589b130dc"}},{"ruleId":"D2","level":"warning","message":{"text":"distribute.main (cognitive 29): distribute.main has cognitive complexity 29 (threshold 15). Drivers by points: if/else 8 (13 pts), ternaries 4 (9 pts), loops 4 (6 pts), error handling 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":"backend/skills/s_ddd-distribute/scripts/distribute.py"},"region":{"startLine":57}}}],"partialFingerprints":{"codehealthFindingId/v1":"7d4cf17747d9632292ed5181ec3b82f3dd1c9d1c627683f82e04800bb1622953"}},{"ruleId":"D2","level":"warning","message":{"text":"ai_ready_helpers.render_agents_md (cognitive 29): ai_ready_helpers.render_agents_md has cognitive complexity 29 (threshold 15). Drivers by points: if/else 9 (17 pts), loops 5 (9 pts), 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":"backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py"},"region":{"startLine":2270}}}],"partialFingerprints":{"codehealthFindingId/v1":"85a1ee6281c0f93083d829f65686bd299820c8846442c2746870ebb0adceb458"}},{"ruleId":"D2","level":"warning","message":{"text":"ai_ready_helpers.render_agents_md (cognitive 29): ai_ready_helpers.render_agents_md has cognitive complexity 29 (threshold 15). Drivers by points: if/else 9 (17 pts), loops 5 (9 pts), 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":"backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py"},"region":{"startLine":1922}}}],"partialFingerprints":{"codehealthFindingId/v1":"161f0b7497a5a92b270fd0b96d5910e46a4dcf6e2e6772ab82ad0d5c4d11f433"}},{"ruleId":"D2","level":"warning","message":{"text":"EvalDashboard.GoldenSetTab (cognitive 29): EvalDashboard.GoldenSetTab has cognitive complexity 29 (threshold 15). Drivers by points: boolean chains 16, if/else 8, ternaries 4, loops 1. Most of this is not in the body itself: 10 of the 29 points are its own statements and the rest belongs to 7 function literals inside it that branch (lines 519, 607, 531, \u2026). The decisions are inside those literals, which nothing outside this body can call, review or test on its own, so splitting the enclosing body is not the move available here. To reduce it, lift the literals\u0027 work into a named function or method at the enclosing scope and have each literal call it, then reduce whichever part then reads as the largest."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/pages/EvalDashboard.tsx"},"region":{"startLine":495}}}],"partialFingerprints":{"codehealthFindingId/v1":"292077afe2fd2234ee49e348f02a4bc3fb162336cc022920725134550672a789"}},{"ruleId":"D2","level":"warning","message":{"text":"useCanvasHost.useCanvasHost (cognitive 29): useCanvasHost.useCanvasHost has cognitive complexity 29 (threshold 15). Drivers by points: if/else 12 (15 pts), boolean chains 9, ternaries 4, error handling 1 (nesting depth added 3). Most of this is not in the body itself: 1 of the 29 points is its own statement and the rest belongs to 7 function literals inside it that branch (lines 311, 233, 251, \u2026). The decisions are inside those literals, which nothing outside this body can call, review or test on its own, so splitting the enclosing body is not the move available here. To reduce it, lift the literals\u0027 work into a named function or method at the enclosing scope and have each literal call it, then reduce whichever part then reads as the largest."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/hooks/useCanvasHost.ts"},"region":{"startLine":148}}}],"partialFingerprints":{"codehealthFindingId/v1":"11bf410df9c3aecfc2bc5f3d9ee381029b76a3bd3f6e4dc4442f8f0139f0719d"}},{"ruleId":"D2","level":"warning","message":{"text":"daemon_guard._main (cognitive 28): daemon_guard._main has cognitive complexity 28 (threshold 15). Drivers by points: ternaries 7 (14 pts), if/else 10 (13 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":"backend/core/daemon_guard.py"},"region":{"startLine":413}}}],"partialFingerprints":{"codehealthFindingId/v1":"104dfed5fd4d525c87a7f2ee87ab2375acd80b8b80fd6f669542ad417b9cf3f1"}},{"ruleId":"D2","level":"warning","message":{"text":"ddd_drift_signal.map_at_risk_cases (cognitive 28): ddd_drift_signal.map_at_risk_cases has cognitive complexity 28 (threshold 15). Drivers by points: if/else 4 (17 pts), loops 4 (10 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":"backend/core/ddd_drift_signal.py"},"region":{"startLine":158}}}],"partialFingerprints":{"codehealthFindingId/v1":"4e011c2494ff864abba211d9f78171c5cb1eaaa80ad35842da9ecf36ee5f2642"}},{"ruleId":"D2","level":"warning","message":{"text":"ddd_packager._scan_text (cognitive 28): ddd_packager._scan_text has cognitive complexity 28 (threshold 15). Drivers by points: if/else 6 (17 pts), loops 4 (8 pts), boolean chains 3 (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":"backend/core/ddd_packager.py"},"region":{"startLine":244}}}],"partialFingerprints":{"codehealthFindingId/v1":"1045bf78e8f7d12057a8790add3c35dafcdbb663521590180da3928dc57d9c7e"}},{"ruleId":"D2","level":"warning","message":{"text":"engine_metrics.collect_ddd_change_suggestions (cognitive 28): engine_metrics.collect_ddd_change_suggestions has cognitive complexity 28 (threshold 15). Drivers by points: if/else 18 (21 pts), boolean chains 5, error handling 1, loops 1 (nesting depth added 3). To reduce it, split the body: most of this score is breadth rather than depth \u2014 checks laid out side by side rather than stacked \u2014 so group the statements between the checks into named steps and move each step into its own function. Some of it IS depth: where a check sits inside another whose only job is to reach it, merge the two into one condition."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/core/engine_metrics.py"},"region":{"startLine":154}}}],"partialFingerprints":{"codehealthFindingId/v1":"137236006ab0f860cccd592287bb414c790510769da1a7f554adb7d8e3510b68"}},{"ruleId":"D2","level":"warning","message":{"text":"ingestion_gate.admit_memory_lesson (cognitive 28): ingestion_gate.admit_memory_lesson has cognitive complexity 28 (threshold 15). Drivers by points: if/else 6 (15 pts), error handling 2 (7 pts), boolean chains 5, ternaries 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":"backend/core/ingestion_gate.py"},"region":{"startLine":840}}}],"partialFingerprints":{"codehealthFindingId/v1":"d625b7e6ffa64923ec91e22295860d3cb80f096cdf75489bec33c21f38fbfaa3"}},{"ruleId":"D2","level":"warning","message":{"text":"library_mounts.index_docs_mount (cognitive 28): library_mounts.index_docs_mount has cognitive complexity 28 (threshold 15). Drivers by points: if/else 12 (20 pts), loops 3 (4 pts), boolean chains 2, error handling 1 (2 pts) (nesting depth added 10). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/core/library_mounts.py"},"region":{"startLine":579}}}],"partialFingerprints":{"codehealthFindingId/v1":"9624ba7821ee4425d1d28c83604e8cc6e84c7195cc5cafd2f8826de3f44894e5"}},{"ruleId":"D2","level":"warning","message":{"text":"LifecycleManager._get_mcp_server_patterns (cognitive 28): LifecycleManager._get_mcp_server_patterns has cognitive complexity 28 (threshold 15). Drivers by points: if/else 7 (17 pts), loops 2 (4 pts), ternaries 2 (4 pts), boolean chains 2, error handling 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":"backend/core/lifecycle_manager.py"},"region":{"startLine":1901}}}],"partialFingerprints":{"codehealthFindingId/v1":"942fed389c5b6d997917ad69a8916e30d6f928db4004305e8fe2a280ab66151c"}},{"ruleId":"D2","level":"warning","message":{"text":"prompt_builder._render_ui_context_section (cognitive 28): prompt_builder._render_ui_context_section has cognitive complexity 28 (threshold 15). Drivers by points: if/else 10 (14 pts), boolean chains 10, ternaries 2 (4 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":"backend/core/prompt_builder.py"},"region":{"startLine":202}}}],"partialFingerprints":{"codehealthFindingId/v1":"f1c68ffa2b4a1d09e0c9bb8be87cf83dd651a47e48e2aac1d94715eff8b13d8a"}},{"ruleId":"D2","level":"warning","message":{"text":"ProposalFeedbackTracker.compute_channel_stats (cognitive 28): ProposalFeedbackTracker.compute_channel_stats has cognitive complexity 28 (threshold 15). Drivers by points: if/else 8 (16 pts), ternaries 2 (5 pts), error handling 2 (4 pts), loops 2, 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":"backend/core/proposal_feedback.py"},"region":{"startLine":158}}}],"partialFingerprints":{"codehealthFindingId/v1":"e49b6e3f2997304a01b3fbd2745a697afed36398b754a882dcc6f5e6deb53790"}},{"ruleId":"D2","level":"warning","message":{"text":"recall_multi.detect_active_project (cognitive 28): recall_multi.detect_active_project has cognitive complexity 28 (threshold 15). Drivers by points: if/else 11 (21 pts), loops 1 (3 pts), ternaries 1 (3 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":"backend/core/recall_multi.py"},"region":{"startLine":1064}}}],"partialFingerprints":{"codehealthFindingId/v1":"9c8b94b9f053100e35ae94965a26661439ae1d1c955a2924c97ba11c5cad8f84"}},{"ruleId":"D2","level":"warning","message":{"text":"ContextHealthHook._run_eval_canary (cognitive 28): ContextHealthHook._run_eval_canary has cognitive complexity 28 (threshold 15). Drivers by points: if/else 15 (20 pts), ternaries 3 (6 pts), error handling 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":"backend/hooks/context_health_hook.py"},"region":{"startLine":346}}}],"partialFingerprints":{"codehealthFindingId/v1":"ade15b38c4a64bb4b269bc2144f25d85dbf4b55783d0e569d361f314fc0d924c"}},{"ruleId":"D2","level":"warning","message":{"text":"ContextHealthHook._check_governance_budgets (cognitive 28): ContextHealthHook._check_governance_budgets has cognitive complexity 28 (threshold 15). Drivers by points: if/else 9 (18 pts), error handling 3 (6 pts), boolean chains 2, loops 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":"backend/hooks/context_health_hook.py"},"region":{"startLine":3291}}}],"partialFingerprints":{"codehealthFindingId/v1":"8e37bc910060f4a552ffd02b1811cc3eafed2f0c8ad058d22c7f272046a1aba0"}},{"ruleId":"D2","level":"warning","message":{"text":"DistillationTriggerHook._extract_lessons (cognitive 28): DistillationTriggerHook._extract_lessons has cognitive complexity 28 (threshold 15). Drivers by points: if/else 8 (19 pts), boolean chains 7, 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":"backend/hooks/distillation_hook.py"},"region":{"startLine":1161}}}],"partialFingerprints":{"codehealthFindingId/v1":"aee239f210ffcfdcaacd930b8e51b608e8c4b5065ae2e73836be5e0b6b4ce04e"}},{"ruleId":"D2","level":"warning","message":{"text":"EvolutionMaintenanceHook._check_promotion_threshold (cognitive 28): EvolutionMaintenanceHook._check_promotion_threshold has cognitive complexity 28 (threshold 15). Drivers by points: if/else 9 (16 pts), boolean chains 4, error handling 2 (4 pts), ternaries 1 (3 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":"backend/hooks/evolution_maintenance_hook.py"},"region":{"startLine":961}}}],"partialFingerprints":{"codehealthFindingId/v1":"78bce0f0aeaac882b50499ef0054093b3552a38f4e13f4d74e78dc26a122b9ab"}},{"ruleId":"D2","level":"warning","message":{"text":"pipelines._load_pipeline_runs (cognitive 28): pipelines._load_pipeline_runs has cognitive complexity 28 (threshold 15). Drivers by points: if/else 6 (14 pts), error handling 2 (8 pts), loops 3 (6 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":"backend/routers/pipelines.py"},"region":{"startLine":116}}}],"partialFingerprints":{"codehealthFindingId/v1":"be290d779b93d0bfe9b0760e70eef861b98d4fae3b33815e849d871a577a169b"}},{"ruleId":"D2","level":"warning","message":{"text":"context_recall_cli.main (cognitive 28): context_recall_cli.main has cognitive complexity 28 (threshold 15). Drivers by points: if/else 11 (19 pts), error handling 2 (3 pts), ternaries 2 (3 pts), loops 1 (2 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":"backend/scripts/context_recall_cli.py"},"region":{"startLine":52}}}],"partialFingerprints":{"codehealthFindingId/v1":"0b5d39655bd67ce4c4ebdf18e9f0b230c1733ee42bf52bfcca39b00b77bc4612"}},{"ruleId":"D2","level":"warning","message":{"text":"evolution_escalation_probe.main (cognitive 28): evolution_escalation_probe.main has cognitive complexity 28 (threshold 15). Drivers by points: if/else 14, boolean chains 7, loops 6 (7 pts) (nesting depth added 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":"backend/scripts/evolution_escalation_probe.py"},"region":{"startLine":73}}}],"partialFingerprints":{"codehealthFindingId/v1":"04696cc48a813a2a5e2e0e9dc440838dccb0d94573b9c98648999fdac5aca8e3"}},{"ruleId":"D2","level":"warning","message":{"text":"locked_write.locked_field_modify (cognitive 28): locked_write.locked_field_modify has cognitive complexity 28 (threshold 15). Drivers by points: if/else 12 (17 pts), error handling 5 (10 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":"backend/scripts/locked_write.py"},"region":{"startLine":409}}}],"partialFingerprints":{"codehealthFindingId/v1":"075701cf22aade31d61f37ccc4f885d1abebc848a454ad008e90f0276cf1bd84"}},{"ruleId":"D2","level":"warning","message":{"text":"migrate_skills.migrate_skill (cognitive 28): migrate_skills.migrate_skill has cognitive complexity 28 (threshold 15). Drivers by points: if/else 19 (25 pts), boolean chains 1, error handling 1, ternaries 1 (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":"backend/scripts/migrate_skills.py"},"region":{"startLine":400}}}],"partialFingerprints":{"codehealthFindingId/v1":"145bb632a6c0bff8ec2e628ea57d1220068b453fd1b75400ddd14a1be288caaa"}},{"ruleId":"D2","level":"warning","message":{"text":"scan.main (cognitive 28): scan.main has cognitive complexity 28 (threshold 15). Drivers by points: if/else 12 (17 pts), loops 4 (9 pts), boolean chains 1, ternaries 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":"backend/skills/s_context-hygiene/scripts/scan.py"},"region":{"startLine":201}}}],"partialFingerprints":{"codehealthFindingId/v1":"cad1a2b903cb36f2a41ec8af5d93f8db0d446694ca028d9c24ed9ebb3f2ed06d"}},{"ruleId":"D2","level":"warning","message":{"text":"RedliningValidator._remove_claude_tracked_changes (cognitive 28): RedliningValidator._remove_claude_tracked_changes has cognitive complexity 28 (threshold 15). Drivers by points: loops 8 (16 pts), if/else 3 (10 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":"backend/skills/s_docx/ooxml/scripts/validation/redlining.py"},"region":{"startLine":217}}}],"partialFingerprints":{"codehealthFindingId/v1":"3401b4287352e6623827fccb09c6bb2422d623e4c10af5c9cfbcb8da1f231f32"}},{"ruleId":"D2","level":"warning","message":{"text":"DocxXMLEditor.revert_deletion (cognitive 28): DocxXMLEditor.revert_deletion has cognitive complexity 28 (threshold 15). Drivers by points: loops 5 (14 pts), if/else 8 (12 pts), boolean chains 2 (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":"backend/skills/s_docx/scripts/document.py"},"region":{"startLine":342}}}],"partialFingerprints":{"codehealthFindingId/v1":"011c76e00512b5f9067e585719640d62851d700a6836804feef57982d1487d76"}},{"ruleId":"D2","level":"warning","message":{"text":"SelfLoopsHealthEngine._check_infrastructure (cognitive 28): SelfLoopsHealthEngine._check_infrastructure has cognitive complexity 28 (threshold 15). Drivers by points: ternaries 12 (16 pts), if/else 7 (9 pts), boolean chains 2, loops 1 (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":"backend/skills/s_loops-health/scripts/loops_health_check.py"},"region":{"startLine":609}}}],"partialFingerprints":{"codehealthFindingId/v1":"f2126d9e6e11861b25399a5d6a9951db6e66c5f8cce27c29c66e815822efea9e"}},{"ruleId":"D2","level":"warning","message":{"text":"SelfLoopsHealthEngine._find_stale_pipelines (cognitive 28): SelfLoopsHealthEngine._find_stale_pipelines has cognitive complexity 28 (threshold 15). Drivers by points: if/else 7 (18 pts), loops 3 (6 pts), error handling 1 (3 pts), boolean chains 1 (nesting depth added 16). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/skills/s_loops-health/scripts/loops_health_check.py"},"region":{"startLine":893}}}],"partialFingerprints":{"codehealthFindingId/v1":"363c8f517dc69b21838bb2f13633516e644d72ae65cf6ee1a4717c3cf6f15116"}},{"ruleId":"D2","level":"warning","message":{"text":"locked_write.locked_field_modify (cognitive 28): locked_write.locked_field_modify has cognitive complexity 28 (threshold 15). Drivers by points: if/else 12 (17 pts), error handling 5 (10 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":"backend/skills/s_persist/scripts/locked_write.py"},"region":{"startLine":409}}}],"partialFingerprints":{"codehealthFindingId/v1":"6df9ce0c0d12022b6ea33723b5b9d7c98db9ee08d808c6f63c4977db9cec69ff"}},{"ruleId":"D2","level":"warning","message":{"text":"RedliningValidator._remove_claude_tracked_changes (cognitive 28): RedliningValidator._remove_claude_tracked_changes has cognitive complexity 28 (threshold 15). Drivers by points: loops 8 (16 pts), if/else 3 (10 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":"backend/skills/s_pptx/ooxml/scripts/validation/redlining.py"},"region":{"startLine":217}}}],"partialFingerprints":{"codehealthFindingId/v1":"c40052e89b12055b28a9b955961be9b05dbf4627fd035a2bcec1af4fe22f2ded"}},{"ruleId":"D2","level":"warning","message":{"text":"ai_ready_helpers.check_domain_referential_integrity (cognitive 28): ai_ready_helpers.check_domain_referential_integrity has cognitive complexity 28 (threshold 15). Drivers by points: if/else 10 (18 pts), boolean chains 5, loops 4 (5 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":"backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py"},"region":{"startLine":250}}}],"partialFingerprints":{"codehealthFindingId/v1":"909fb990e8693677272c9b6ab52c6c39b7e5bb01ede96df6c3ec23e423ca530d"}},{"ruleId":"D2","level":"warning","message":{"text":"locked_write.locked_field_modify (cognitive 28): locked_write.locked_field_modify has cognitive complexity 28 (threshold 15). Drivers by points: if/else 12 (17 pts), error handling 5 (10 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":"backend/templates/ddd-skills/s_ddd-persist/scripts/locked_write.py"},"region":{"startLine":409}}}],"partialFingerprints":{"codehealthFindingId/v1":"6a3f91ef8b686f76c94c6edf81dccab4b947ce9062d00a9849d1b663bf7a362a"}},{"ruleId":"D2","level":"warning","message":{"text":"ai_ready_helpers.check_domain_referential_integrity (cognitive 28): ai_ready_helpers.check_domain_referential_integrity has cognitive complexity 28 (threshold 15). Drivers by points: if/else 10 (18 pts), boolean chains 5, loops 4 (5 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":"backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py"},"region":{"startLine":249}}}],"partialFingerprints":{"codehealthFindingId/v1":"4470b246a23dec62e495e62d0071e518aae5c40db5062084e537f3cb55a6ef45"}},{"ruleId":"D2","level":"warning","message":{"text":"daemon_guard._main (cognitive 28): daemon_guard._main has cognitive complexity 28 (threshold 15). Drivers by points: ternaries 7 (14 pts), if/else 10 (13 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":"desktop/resources/daemon/daemon_guard.py"},"region":{"startLine":413}}}],"partialFingerprints":{"codehealthFindingId/v1":"b43b47b0f622486367128acf6ef3376763ac6c06813a91885165cb87d4468890"}},{"ruleId":"D2","level":"warning","message":{"text":"ExplorerToolbar.ExplorerToolbar (cognitive 28): ExplorerToolbar.ExplorerToolbar has cognitive complexity 28 (threshold 15). Drivers by points: if/else 17, ternaries 4 (5 pts), boolean chains 4, error handling 2 (nesting depth added 1). Most of this is not in the body itself: 6 of the 28 points are its own statements and the rest belongs to 9 function literals inside it that branch (lines 89, 146, 127, \u2026). The decisions are inside those literals, which nothing outside this body can call, review or test on its own, so splitting the enclosing body is not the move available here. To reduce it, lift the literals\u0027 work into a named function or method at the enclosing scope and have each literal call it, then reduce whichever part then reads as the largest."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/workspace-explorer/ExplorerToolbar.tsx"},"region":{"startLine":34}}}],"partialFingerprints":{"codehealthFindingId/v1":"97719baf927109ea2b76c944e718fd1b927c5417aeffbd6dc31a8e2cbb3348fb"}},{"ruleId":"D2","level":"warning","message":{"text":"CMBrainOverlay.CMBrainContent (cognitive 28): CMBrainOverlay.CMBrainContent has cognitive complexity 28 (threshold 15). Drivers by points: ternaries 10 (17 pts), boolean chains 9, if/else 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":"desktop/src/components/layout/CMBrainOverlay.tsx"},"region":{"startLine":167}}}],"partialFingerprints":{"codehealthFindingId/v1":"69c3ec30289d4e2b212d38d8565515acc2ae5d1dea858e6597d4dd76915ac3c2"}},{"ruleId":"D2","level":"warning","message":{"text":"ToDoOverlay.ToDoContent (cognitive 28): ToDoOverlay.ToDoContent has cognitive complexity 28 (threshold 15). Drivers by points: ternaries 6 (11 pts), boolean chains 7, if/else 7, error handling 3 (nesting depth added 5). Most of this is not in the body itself: 6 of the 28 points are its own statements and the rest belongs to 8 function literals inside it that branch (lines 299, 249, 214, \u2026). The decisions are inside those literals, which nothing outside this body can call, review or test on its own, so splitting the enclosing body is not the move available here. To reduce it, lift the literals\u0027 work into a named function or method at the enclosing scope and have each literal call it, then reduce whichever part then reads as the largest."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/layout/ToDoOverlay.tsx"},"region":{"startLine":195}}}],"partialFingerprints":{"codehealthFindingId/v1":"71b7ffbcfa4ff7170c4bbfd82c735724fcd3328466227b9fd289b623fc44cd50"}},{"ruleId":"D2","level":"warning","message":{"text":"PollinateOverlay.PollinateContent (cognitive 28): PollinateOverlay.PollinateContent has cognitive complexity 28 (threshold 15). Drivers by points: if/else 12, boolean chains 11, ternaries 4 (5 pts) (nesting depth added 1). Most of this is not in the body itself: 9 of the 28 points are its own statements and the rest belongs to 11 function literals inside it that branch (lines 168, 148, 213, \u2026). The decisions are inside those literals, which nothing outside this body can call, review or test on its own, so splitting the enclosing body is not the move available here. To reduce it, lift the literals\u0027 work into a named function or method at the enclosing scope and have each literal call it, then reduce whichever part then reads as the largest."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/layout/PollinateOverlay.tsx"},"region":{"startLine":108}}}],"partialFingerprints":{"codehealthFindingId/v1":"871cf357782794a2e3f52cf2e175ef7077c9341c03ca33bd2ba60769c0c742db"}},{"ruleId":"D2","level":"warning","message":{"text":"EngineMetricsTab.EngineMetricsTab (cognitive 28): EngineMetricsTab.EngineMetricsTab has cognitive complexity 28 (threshold 15). Drivers by points: boolean chains 12, ternaries 8 (12 pts), if/else 3, error handling 1 (nesting depth added 4). Of this number, 16 points are the body\u0027s own statements and 12 belong to 6 function literals inside it that branch. To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/settings/EngineMetricsTab.tsx"},"region":{"startLine":54}}}],"partialFingerprints":{"codehealthFindingId/v1":"8425420ae412e00f80a6c3ac5197f0af5ed9c56e06d0857ae581c582c4a37f9e"}},{"ruleId":"D2","level":"warning","message":{"text":"SlackChannelAdapter._ws_health_monitor (cognitive 27): SlackChannelAdapter._ws_health_monitor has cognitive complexity 27 (threshold 15). Drivers by points: if/else 7 (18 pts), error handling 1 (5 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":"backend/channels/adapters/slack.py"},"region":{"startLine":1650}}}],"partialFingerprints":{"codehealthFindingId/v1":"d07803d14b69c50f163b5c485ac0e74eac10cd86a4994639884bf6527d3b2e16"}},{"ruleId":"D2","level":"warning","message":{"text":"ddd_cultivation._cultivate_proposals (cognitive 27): ddd_cultivation._cultivate_proposals has cognitive complexity 27 (threshold 15). Drivers by points: if/else 12 (24 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":"backend/core/ddd_cultivation.py"},"region":{"startLine":2603}}}],"partialFingerprints":{"codehealthFindingId/v1":"77b13c0b03346fa1af278cf52895e66b7ebbd7f0dc6707c498ec045839b7bdb6"}},{"ruleId":"D2","level":"warning","message":{"text":"needs_human_review.needs_human_review_batch (cognitive 27): needs_human_review.needs_human_review_batch has cognitive complexity 27 (threshold 15). Drivers by points: if/else 10 (17 pts), error handling 3 (5 pts), loops 3 (4 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":"backend/core/needs_human_review.py"},"region":{"startLine":369}}}],"partialFingerprints":{"codehealthFindingId/v1":"d7ad71ebde85086eaa0b17eeb783adf4ee014eccd9451e94344475658e153893"}},{"ruleId":"D2","level":"warning","message":{"text":"PluginManager._parse_marketplace_json_with_name (cognitive 27): PluginManager._parse_marketplace_json_with_name has cognitive complexity 27 (threshold 15). Drivers by points: if/else 7 (21 pts), boolean chains 4, error handling 1, loops 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":"backend/core/plugin_manager.py"},"region":{"startLine":250}}}],"partialFingerprints":{"codehealthFindingId/v1":"057007f31b2f4a849f7d71b00d2b471647b5dbcc60c0e8a8c7fcb2a60c118ade"}},{"ruleId":"D2","level":"warning","message":{"text":"proactive_intelligence._get_signal_highlights (cognitive 27): proactive_intelligence._get_signal_highlights has cognitive complexity 27 (threshold 15). Drivers by points: if/else 7 (13 pts), ternaries 3 (7 pts), error handling 2 (4 pts), loops 2, 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":"backend/core/proactive_intelligence.py"},"region":{"startLine":556}}}],"partialFingerprints":{"codehealthFindingId/v1":"02ccd0c7db953a1e689908ea722f3ab4e313de12a6cbab5030ed477f1f72595d"}},{"ruleId":"D2","level":"warning","message":{"text":"scheduler.load_user_context (cognitive 27): scheduler.load_user_context has cognitive complexity 27 (threshold 15). Drivers by points: if/else 8 (16 pts), error handling 3 (5 pts), ternaries 2 (4 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":"backend/jobs/scheduler.py"},"region":{"startLine":242}}}],"partialFingerprints":{"codehealthFindingId/v1":"34a49ee7a52efe4ba864eeccd4073c36a109d078b52d1ad53826b8d067116ee8"}},{"ruleId":"D2","level":"warning","message":{"text":"design_system.format_page_override_md (cognitive 27): design_system.format_page_override_md has cognitive complexity 27 (threshold 15). Drivers by points: loops 7 (14 pts), if/else 13 (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":"backend/skills/s_frontend-design/scripts/design_system.py"},"region":{"startLine":886}}}],"partialFingerprints":{"codehealthFindingId/v1":"4c3382752f402128a77569ca0b8b071bb315730596508fa95fdbf76f8ef2d777"}},{"ruleId":"D2","level":"warning","message":{"text":"swarmai::check_python_version (cognitive 27): swarmai::check_python_version has cognitive complexity 27 (threshold 15). Drivers by points: if/else 11 (26 pts), 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":"desktop/src-tauri/src/lib.rs"},"region":{"startLine":2564}}}],"partialFingerprints":{"codehealthFindingId/v1":"82d9423d4e133afa1ce82d5981ff49d730c1eead205dccfb3f6e6492d00e8caf"}},{"ruleId":"D2","level":"warning","message":{"text":"hiveComponents.AuthDisplay (cognitive 27): hiveComponents.AuthDisplay has cognitive complexity 27 (threshold 15). Drivers by points: ternaries 8 (11 pts), if/else 8, error handling 3 (6 pts), boolean chains 2 (nesting depth added 6). Most of this is not in the body itself: 13 of the 27 points are its own statements and the rest belongs to 5 function literals inside it that branch (lines 275, 310, 324, \u2026). The decisions are inside those literals, which nothing outside this body can call, review or test on its own, so splitting the enclosing body is not the move available here. To reduce it, lift the literals\u0027 work into a named function or method at the enclosing scope and have each literal call it, then reduce whichever part then reads as the largest."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/settings/hiveComponents.tsx"},"region":{"startLine":256}}}],"partialFingerprints":{"codehealthFindingId/v1":"eaa263822d80126b20f9df7a719b8c23a08faf2bbcebf7a6a8d72e903de618bb"}},{"ruleId":"D2","level":"warning","message":{"text":"EvalDashboard.OverviewTab (cognitive 27): EvalDashboard.OverviewTab has cognitive complexity 27 (threshold 15). Drivers by points: ternaries 13 (14 pts), boolean chains 11, if/else 2 (nesting depth added 1). Of this number, 26 points are the body\u0027s own statements and 1 belongs to 2 function literals inside it that branch. 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":"desktop/src/pages/EvalDashboard.tsx"},"region":{"startLine":289}}}],"partialFingerprints":{"codehealthFindingId/v1":"dfed6787ed19681f326b6002414c6b7018eafcd0808c1f41b1a23d04a0f42680"}},{"ruleId":"D2","level":"warning","message":{"text":"FilePreviewModal.FilePreviewModal (cognitive 27): FilePreviewModal.FilePreviewModal has cognitive complexity 27 (threshold 15). Drivers by points: if/else 11, boolean chains 8, ternaries 5 (6 pts), error handling 1 (2 pts) (nesting depth added 2). Most of this is not in the body itself: 6 of the 27 points are its own statements and the rest belongs to 2 function literals inside it that branch (lines 102, 79). The decisions are inside those literals, which nothing outside this body can call, review or test on its own, so splitting the enclosing body is not the move available here. To reduce it, lift the literals\u0027 work into a named function or method at the enclosing scope and have each literal call it, then reduce whichever part then reads as the largest."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/workspace/FilePreviewModal.tsx"},"region":{"startLine":48}}}],"partialFingerprints":{"codehealthFindingId/v1":"b0eb4935b5e7511be1e534b40059a55559823bc5fa050c702884a638538f725c"}},{"ruleId":"D2","level":"warning","message":{"text":"context_injector._extract_agent_spawns (cognitive 26): context_injector._extract_agent_spawns has cognitive complexity 26 (threshold 15). Drivers by points: if/else 7 (21 pts), loops 2 (3 pts), boolean chains 1, error handling 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":"backend/core/context_injector.py"},"region":{"startLine":362}}}],"partialFingerprints":{"codehealthFindingId/v1":"0c626cecbaa7bd6e8032f15eafaae2337977a13b77e76887477d4f7a96876a5c"}},{"ruleId":"D2","level":"warning","message":{"text":"engine_metrics._collect_ddd_health (cognitive 26): engine_metrics._collect_ddd_health has cognitive complexity 26 (threshold 15). Drivers by points: if/else 7 (15 pts), loops 4 (8 pts), boolean chains 2, error handling 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":"backend/core/engine_metrics.py"},"region":{"startLine":477}}}],"partialFingerprints":{"codehealthFindingId/v1":"8fca468aad501c6285f9ec8ffea935a1f1d6e097c039e104d41af7ce967e86c7"}},{"ruleId":"D2","level":"warning","message":{"text":"proactive_intelligence._parse_open_threads (cognitive 26): proactive_intelligence._parse_open_threads has cognitive complexity 26 (threshold 15). Drivers by points: if/else 10 (22 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":"backend/core/proactive_intelligence.py"},"region":{"startLine":100}}}],"partialFingerprints":{"codehealthFindingId/v1":"3a34bcb1f37e7e662c39a7bbb277f9930265d95d385c01243f53753f2034aed4"}},{"ruleId":"D2","level":"warning","message":{"text":"proactive_intelligence._extract_report_field (cognitive 26): proactive_intelligence._extract_report_field has cognitive complexity 26 (threshold 15). Drivers by points: if/else 9 (18 pts), loops 3 (6 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":"backend/core/proactive_intelligence.py"},"region":{"startLine":1589}}}],"partialFingerprints":{"codehealthFindingId/v1":"7dc1990f06fae1e3f8d1df0b8dc4647967fedd7fa39301dc7fc8275d38f6796f"}},{"ruleId":"D2","level":"warning","message":{"text":"security_hooks._is_irreversible_external_op (cognitive 26): security_hooks._is_irreversible_external_op has cognitive complexity 26 (threshold 15). Drivers by points: if/else 9 (19 pts), loops 3 (5 pts), boolean chains 1, error handling 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. This shape REPEATS in the file: 2 other methods here (security_hooks._is_history_rewrite, security_hooks._command_has_git_commit) have the same decision points, in the same order, at the same nesting depths \u2014 so this is one pattern written 3 times rather than 3 independent problems. Splitting this body alone leaves the other 2 exactly as they are. Where these are variations on one operation, the change that clears all 3 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":"backend/core/security_hooks.py"},"region":{"startLine":182}}}],"partialFingerprints":{"codehealthFindingId/v1":"2085ac53a80bbf8e22c41134e6a5b0a44fe826347c1d8c75c4e47a747aa39710"}},{"ruleId":"D2","level":"warning","message":{"text":"security_hooks._is_history_rewrite (cognitive 26): security_hooks._is_history_rewrite has cognitive complexity 26 (threshold 15). Drivers by points: if/else 9 (19 pts), loops 3 (5 pts), boolean chains 1, error handling 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. This shape REPEATS in the file: 2 other methods here (security_hooks._is_irreversible_external_op, security_hooks._command_has_git_commit) have the same decision points, in the same order, at the same nesting depths \u2014 so this is one pattern written 3 times rather than 3 independent problems. Splitting this body alone leaves the other 2 exactly as they are. Where these are variations on one operation, the change that clears all 3 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":"backend/core/security_hooks.py"},"region":{"startLine":610}}}],"partialFingerprints":{"codehealthFindingId/v1":"27f87d560e87e37101ca026c0debe67bba8401c121d06aac42d969f18ed9a6ff"}},{"ruleId":"D2","level":"warning","message":{"text":"security_hooks._command_has_git_commit (cognitive 26): security_hooks._command_has_git_commit has cognitive complexity 26 (threshold 15). Drivers by points: if/else 9 (19 pts), loops 3 (5 pts), boolean chains 1, error handling 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. This shape REPEATS in the file: 2 other methods here (security_hooks._is_irreversible_external_op, security_hooks._is_history_rewrite) have the same decision points, in the same order, at the same nesting depths \u2014 so this is one pattern written 3 times rather than 3 independent problems. Splitting this body alone leaves the other 2 exactly as they are. Where these are variations on one operation, the change that clears all 3 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":"backend/core/security_hooks.py"},"region":{"startLine":1625}}}],"partialFingerprints":{"codehealthFindingId/v1":"26afd19a1384399f8c345bd042066d422a6f2acbcfb516d705e401e6d8568268"}},{"ruleId":"D2","level":"warning","message":{"text":"DistillationTriggerHook._apply_deliverable_reconciliation (cognitive 26): DistillationTriggerHook._apply_deliverable_reconciliation has cognitive complexity 26 (threshold 15). Drivers by points: if/else 8 (16 pts), loops 5 (7 pts), boolean chains 3 (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":"backend/hooks/distillation_hook.py"},"region":{"startLine":2117}}}],"partialFingerprints":{"codehealthFindingId/v1":"d47098645c8e505c5f332d8cc82b3ccde5c5a4597997ee848c079997e1fc124b"}},{"ruleId":"D2","level":"warning","message":{"text":"swarmai_monthly_report._collect_eval_metrics (cognitive 26): swarmai_monthly_report._collect_eval_metrics has cognitive complexity 26 (threshold 15). Drivers by points: if/else 10 (18 pts), error handling 2 (4 pts), loops 2, 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":"backend/jobs/handlers/swarmai_monthly_report.py"},"region":{"startLine":297}}}],"partialFingerprints":{"codehealthFindingId/v1":"1d472a6d25fb88dfb73130357e90461d5df92118ee46aa9a9e8d2fd0152aacc7"}},{"ruleId":"D2","level":"warning","message":{"text":"self_tune.suggest_new_feeds (cognitive 26): self_tune.suggest_new_feeds has cognitive complexity 26 (threshold 15). Drivers by points: if/else 9 (16 pts), loops 5 (9 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":"backend/jobs/self_tune.py"},"region":{"startLine":349}}}],"partialFingerprints":{"codehealthFindingId/v1":"06948310c4016d7c149d2e9206a8227557ac20a95f66556b69b64d76f375e7af"}},{"ruleId":"D2","level":"warning","message":{"text":"pipelines.pipeline_run_detail (cognitive 26): pipelines.pipeline_run_detail has cognitive complexity 26 (threshold 15). Drivers by points: if/else 7 (13 pts), boolean chains 7, ternaries 2 (4 pts), loops 1 (2 pts) (nesting depth added 9). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/routers/pipelines.py"},"region":{"startLine":645}}}],"partialFingerprints":{"codehealthFindingId/v1":"258fda7f19557c76f99631b1fd14fe47c2673da42677429f6f3f680948204680"}},{"ruleId":"D2","level":"warning","message":{"text":"pollinate._publish_status_for (cognitive 26): pollinate._publish_status_for has cognitive complexity 26 (threshold 15). Drivers by points: if/else 5 (14 pts), ternaries 1 (6 pts), loops 2 (4 pts), error handling 1 (2 pts) (nesting depth added 17). 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":"backend/routers/pollinate.py"},"region":{"startLine":232}}}],"partialFingerprints":{"codehealthFindingId/v1":"97561838c2b2d04be57f732b450dad6357170473ad454ad8b5115a48c8cec472"}},{"ruleId":"D2","level":"warning","message":{"text":"migrate_skills.generate_manifest (cognitive 26): migrate_skills.generate_manifest has cognitive complexity 26 (threshold 15). Drivers by points: if/else 9 (13 pts), loops 4 (7 pts), boolean chains 3, error handling 1 (2 pts), 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":"backend/scripts/migrate_skills.py"},"region":{"startLine":235}}}],"partialFingerprints":{"codehealthFindingId/v1":"d6a66f8b62608bb6c2fb35a3df72d553571543a30081a896ffea05ef98ac0517"}},{"ruleId":"D2","level":"warning","message":{"text":"pipeline_pr.create_pr (cognitive 26): pipeline_pr.create_pr has cognitive complexity 26 (threshold 15). Drivers by points: if/else 14 (16 pts), error handling 5 (9 pts), loops 1 (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":"backend/skills/s_autonomous-pipeline/scripts/pipeline_pr.py"},"region":{"startLine":240}}}],"partialFingerprints":{"codehealthFindingId/v1":"b297bb370e95f2405eee1540f751ade30346f9aedb342b99ec437dedfd409fcc"}},{"ruleId":"D2","level":"warning","message":{"text":"brand_chart.apply_brand_to_charts (cognitive 26): brand_chart.apply_brand_to_charts has cognitive complexity 26 (threshold 15). Drivers by points: error handling 4 (14 pts), if/else 2 (6 pts), loops 3 (6 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":"backend/skills/s_pollinate/scripts/brand_chart.py"},"region":{"startLine":58}}}],"partialFingerprints":{"codehealthFindingId/v1":"1bc564a930ebd5a9e575c936405add580e4abb83fa776fc60d5166dadd2d63de"}},{"ruleId":"D2","level":"warning","message":{"text":"generate_shorts.main (cognitive 26): generate_shorts.main has cognitive complexity 26 (threshold 15). Drivers by points: if/else 14 (20 pts), loops 4 (5 pts), ternaries 1 (nesting depth added 7). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/skills/s_pollinate/scripts/generate_shorts.py"},"region":{"startLine":522}}}],"partialFingerprints":{"codehealthFindingId/v1":"becac9580ec0f246d2ae17c6c1b90d83530564e60f9bda62ee8135efb0f2e0ac"}},{"ruleId":"D2","level":"warning","message":{"text":"ShapeData.get_font_path (cognitive 26): ShapeData.get_font_path has cognitive complexity 26 (threshold 15). Drivers by points: if/else 6 (15 pts), loops 4 (8 pts), error handling 1 (2 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":"backend/skills/s_pptx/scripts/inventory.py"},"region":{"startLine":280}}}],"partialFingerprints":{"codehealthFindingId/v1":"eebffb0c6e60e2e7df8bd75cb0b5725b0766c4ff06e60a529a3a5bbfe2919309"}},{"ruleId":"D2","level":"warning","message":{"text":"ai_ready_helpers.extract_human_spec_blocks (cognitive 26): ai_ready_helpers.extract_human_spec_blocks has cognitive complexity 26 (threshold 15). Drivers by points: if/else 6 (15 pts), loops 3 (7 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":"backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py"},"region":{"startLine":1652}}}],"partialFingerprints":{"codehealthFindingId/v1":"09564ca31ed06261b1e1c7319851450fcb0c07f986766bdab8385e281b2a60d9"}},{"ruleId":"D2","level":"warning","message":{"text":"ai_ready_helpers.extract_human_spec_blocks (cognitive 26): ai_ready_helpers.extract_human_spec_blocks has cognitive complexity 26 (threshold 15). Drivers by points: if/else 6 (15 pts), loops 3 (7 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":"backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py"},"region":{"startLine":1316}}}],"partialFingerprints":{"codehealthFindingId/v1":"4d9a016d8a0eca1523e05d262ae48b3298506e3de843a41cedc075b754d3b55b"}},{"ruleId":"D2","level":"warning","message":{"text":"MultiSelect.MultiSelect (cognitive 26): MultiSelect.MultiSelect has cognitive complexity 26 (threshold 15). Drivers by points: boolean chains 15, if/else 8 (9 pts), ternaries 2 (nesting depth added 1). Most of this is not in the body itself: 12 of the 26 points are its own statements and the rest belongs to 7 function literals inside it that branch (lines 69, 60, 44, \u2026). The decisions are inside those literals, which nothing outside this body can call, review or test on its own, so splitting the enclosing body is not the move available here. To reduce it, lift the literals\u0027 work into a named function or method at the enclosing scope and have each literal call it, then reduce whichever part then reads as the largest."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/common/MultiSelect.tsx"},"region":{"startLine":25}}}],"partialFingerprints":{"codehealthFindingId/v1":"803f5b99f2043bc53eabf9b3fedaaf92b131710f99d2403e8c51c598281ecad9"}},{"ruleId":"D2","level":"warning","message":{"text":"CodeGraph.CodeGraph (cognitive 26): CodeGraph.CodeGraph has cognitive complexity 26 (threshold 15). Drivers by points: if/else 12, boolean chains 11, loops 2, ternaries 1. Most of this is not in the body itself: 9 of the 26 points are its own statements and the rest belongs to 10 function literals inside it that branch (lines 168, 156, 100, \u2026). The decisions are inside those literals, which nothing outside this body can call, review or test on its own, so splitting the enclosing body is not the move available here. To reduce it, lift the literals\u0027 work into a named function or method at the enclosing scope and have each literal call it, then reduce whichever part then reads as the largest."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/code-intel/CodeGraph.tsx"},"region":{"startLine":76}}}],"partialFingerprints":{"codehealthFindingId/v1":"016008d7c40eb18e25b23fcc4cfaef4699871285df09d1e1c42a0eb2d4c8de46"}},{"ruleId":"D2","level":"warning","message":{"text":"PdfRenderer.PdfRenderer (cognitive 26): PdfRenderer.PdfRenderer has cognitive complexity 26 (threshold 15). Drivers by points: if/else 12, ternaries 6 (7 pts), boolean chains 5, error handling 1, loops 1 (nesting depth added 1). Most of this is not in the body itself: 8 of the 26 points are its own statements and the rest belongs to 7 function literals inside it that branch (lines 167, 59, 78, \u2026). The decisions are inside those literals, which nothing outside this body can call, review or test on its own, so splitting the enclosing body is not the move available here. To reduce it, lift the literals\u0027 work into a named function or method at the enclosing scope and have each literal call it, then reduce whichever part then reads as the largest."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/file-viewer/renderers/PdfRenderer.tsx"},"region":{"startLine":44}}}],"partialFingerprints":{"codehealthFindingId/v1":"18d6493ed55882f39fb1d02db6f3f64470380b94fbf7438aafa76264e5ec9c0b"}},{"ruleId":"D2","level":"warning","message":{"text":"TSCCModules.SystemPromptModule (cognitive 26): TSCCModules.SystemPromptModule has cognitive complexity 26 (threshold 15). Drivers by points: boolean chains 14, if/else 11, ternaries 1. Most of this is not in the body itself: 8 of the 26 points are its own statements and the rest belongs to 11 function literals inside it that branch (lines 713, 663, 726, \u2026). The decisions are inside those literals, which nothing outside this body can call, review or test on its own, so splitting the enclosing body is not the move available here. To reduce it, lift the literals\u0027 work into a named function or method at the enclosing scope and have each literal call it, then reduce whichever part then reads as the largest."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/pages/chat/components/TSCCModules.tsx"},"region":{"startLine":655}}}],"partialFingerprints":{"codehealthFindingId/v1":"b90b482bdd303263cc9aaa8f648cb95dfbfb1fab8fc1186a2932ece189f49869"}},{"ruleId":"D2","level":"warning","message":{"text":"dead_code._is_entry_point (cognitive 25): dead_code._is_entry_point has cognitive complexity 25 (threshold 15). Drivers by points: if/else 13 (22 pts), boolean chains 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":"backend/core/code_intel/dead_code.py"},"region":{"startLine":59}}}],"partialFingerprints":{"codehealthFindingId/v1":"31fbb7eab207fa2595234ed6feec8e1fb4ff1da9fe6098fa5b740f90ba3d1839"}},{"ruleId":"D2","level":"warning","message":{"text":"community_data.parse_hot_topics (cognitive 25): community_data.parse_hot_topics has cognitive complexity 25 (threshold 15). Drivers by points: if/else 7 (10 pts), boolean chains 7, ternaries 2 (4 pts), error handling 2, 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":"backend/core/community_data.py"},"region":{"startLine":732}}}],"partialFingerprints":{"codehealthFindingId/v1":"1467b92573cbc501786a1081c4e5fc774db5906067eb28c3ee2f96eed763f9ab"}},{"ruleId":"D2","level":"warning","message":{"text":"CompactionGuard.check (cognitive 25): CompactionGuard.check has cognitive complexity 25 (threshold 15). Drivers by points: if/else 10 (14 pts), ternaries 3 (10 pts), 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":"backend/core/compaction_guard.py"},"region":{"startLine":609}}}],"partialFingerprints":{"codehealthFindingId/v1":"4073e411a2e5d628375e3776122d229f4e58c28f149e305c449211b2509004a3"}},{"ruleId":"D2","level":"warning","message":{"text":"ddd_health.compute_section_health (cognitive 25): ddd_health.compute_section_health has cognitive complexity 25 (threshold 15). Drivers by points: if/else 6 (15 pts), error handling 3 (7 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":"backend/core/ddd_health.py"},"region":{"startLine":256}}}],"partialFingerprints":{"codehealthFindingId/v1":"c171ab1122cb923909de4304c4c5512be4769effa210bc2101a40251e1961f7e"}},{"ruleId":"D2","level":"warning","message":{"text":"ddd_job_registry.build_manifest_jobs (cognitive 25): ddd_job_registry.build_manifest_jobs has cognitive complexity 25 (threshold 15). Drivers by points: if/else 7 (13 pts), loops 3 (4 pts), error handling 2 (3 pts), ternaries 1 (3 pts), boolean chains 2 (nesting depth added 10). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/core/ddd_job_registry.py"},"region":{"startLine":121}}}],"partialFingerprints":{"codehealthFindingId/v1":"7455a3f31f09d1b304dbd6489dad57db6a86ce0021815848426c4881160285f3"}},{"ruleId":"D2","level":"warning","message":{"text":"ddd_orchestrator._watch_paths_for (cognitive 25): ddd_orchestrator._watch_paths_for has cognitive complexity 25 (threshold 15). Drivers by points: if/else 6 (19 pts), loops 1 (4 pts), boolean chains 2 (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":"backend/core/ddd_orchestrator.py"},"region":{"startLine":215}}}],"partialFingerprints":{"codehealthFindingId/v1":"604ef8ee573c6bd3057e2e29235d7a687e1417baf7a5ad29f8b12fc0f8745a8a"}},{"ruleId":"D2","level":"warning","message":{"text":"ddd_packager._materialize_shared (cognitive 25): ddd_packager._materialize_shared has cognitive complexity 25 (threshold 15). Drivers by points: if/else 7 (15 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":"backend/core/ddd_packager.py"},"region":{"startLine":913}}}],"partialFingerprints":{"codehealthFindingId/v1":"9aa5397ca80a863971e47d2d05c6b6345a8e52d8222b43bf4276cf3dd11b7a50"}},{"ruleId":"D2","level":"warning","message":{"text":"security_hooks._is_dangerous_rm (cognitive 25): security_hooks._is_dangerous_rm has cognitive complexity 25 (threshold 15). Drivers by points: if/else 10 (16 pts), boolean chains 6, loops 2, error handling 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":"backend/core/security_hooks.py"},"region":{"startLine":99}}}],"partialFingerprints":{"codehealthFindingId/v1":"45a3640ab5ab6ceb82a3adc38e7f2911387f92aa990be55b56819dc6efa2d8ad"}},{"ruleId":"D2","level":"warning","message":{"text":"session_registry.kill_all_claude_processes (cognitive 25): session_registry.kill_all_claude_processes has cognitive complexity 25 (threshold 15). Drivers by points: error handling 6 (12 pts), if/else 7 (10 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":"backend/core/session_registry.py"},"region":{"startLine":175}}}],"partialFingerprints":{"codehealthFindingId/v1":"064f26c97efb08719a20081117114493b9add51a9754bb00ee01dcca28f66944"}},{"ruleId":"D2","level":"warning","message":{"text":"SessionRouter._evict_idle (cognitive 25): SessionRouter._evict_idle has cognitive complexity 25 (threshold 15). Drivers by points: if/else 14 (21 pts), boolean chains 3, ternaries 1 (nesting depth added 7). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/core/session_router.py"},"region":{"startLine":2431}}}],"partialFingerprints":{"codehealthFindingId/v1":"de89841ab8538f6f46ee33b398b7da8bb00912c6d4abf53100a0a65b8d1ed8aa"}},{"ruleId":"D2","level":"warning","message":{"text":"session_utils._build_error_event (cognitive 25): session_utils._build_error_event has cognitive complexity 25 (threshold 15). Drivers by points: if/else 8 (20 pts), loops 1 (3 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":"backend/core/session_utils.py"},"region":{"startLine":498}}}],"partialFingerprints":{"codehealthFindingId/v1":"6c7c8421d07a787fc6ec06c12344b6cbd796041794b10e50ecda0d7e27a389b0"}},{"ruleId":"D2","level":"warning","message":{"text":"ContextHealthHook._light_refresh (cognitive 25): ContextHealthHook._light_refresh has cognitive complexity 25 (threshold 15). Drivers by points: error handling 16 (19 pts), if/else 5 (6 pts) (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":"backend/hooks/context_health_hook.py"},"region":{"startLine":175}}}],"partialFingerprints":{"codehealthFindingId/v1":"13c599fca3454d0436bcb40cf68529b2a9abd8e1ec158a4f22da5f4d8ae40402"}},{"ruleId":"D2","level":"warning","message":{"text":"EvolutionMaintenanceHook._quality_gate (cognitive 25): EvolutionMaintenanceHook._quality_gate has cognitive complexity 25 (threshold 15). Drivers by points: if/else 9 (18 pts), error handling 2 (3 pts), loops 3, 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":"backend/hooks/evolution_maintenance_hook.py"},"region":{"startLine":361}}}],"partialFingerprints":{"codehealthFindingId/v1":"b8e05f5281c15c89d5a564c69152d3a4bba683727d8ad730514aff7302738068"}},{"ruleId":"D2","level":"warning","message":{"text":"swarmai_monthly_report._collect_git_metrics (cognitive 25): swarmai_monthly_report._collect_git_metrics has cognitive complexity 25 (threshold 15). Drivers by points: if/else 7 (17 pts), loops 2 (5 pts), error handling 2, boolean chains 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":"backend/jobs/handlers/swarmai_monthly_report.py"},"region":{"startLine":537}}}],"partialFingerprints":{"codehealthFindingId/v1":"682a9697c09d6194e1a8d5a706200b548a660847c15e6d091b7c18f95108c1d1"}},{"ruleId":"D2","level":"warning","message":{"text":"model_resolve.resolve_job_model (cognitive 25): model_resolve.resolve_job_model has cognitive complexity 25 (threshold 15). Drivers by points: if/else 8 (10 pts), error handling 4 (8 pts), boolean chains 6, ternaries 1 (nesting depth added 6). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/jobs/model_resolve.py"},"region":{"startLine":36}}}],"partialFingerprints":{"codehealthFindingId/v1":"5bae377bef0ec9e3f3519bc52a8e7b33221140cd7e2691b3d9fa1e4ef8866972"}},{"ruleId":"D2","level":"warning","message":{"text":"ddd_brain._brain_detail_metrics (cognitive 25): ddd_brain._brain_detail_metrics has cognitive complexity 25 (threshold 15). Drivers by points: if/else 8 (15 pts), error handling 5 (7 pts), loops 1 (2 pts), ternaries 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":"backend/routers/ddd_brain.py"},"region":{"startLine":763}}}],"partialFingerprints":{"codehealthFindingId/v1":"e7032f47dabaa4615f96cb8e201c8c6c62bdc73ecde1a656b1d5a6c1e4536a2e"}},{"ruleId":"D2","level":"warning","message":{"text":"tscc.get_security_scan (cognitive 25): tscc.get_security_scan has cognitive complexity 25 (threshold 15). Drivers by points: if/else 13 (14 pts), boolean chains 6, ternaries 2 (3 pts), loops 2 (nesting depth added 2). To reduce it, split the body: most of this score is breadth rather than depth \u2014 checks laid out side by side rather than stacked \u2014 so group the statements between the checks into named steps and move each step into its own function. Some of it IS depth: where a check sits inside another whose only job is to reach it, merge the two into one condition, and where an else follows a branch that already returns, drop the trailing else and let the rest of the body continue at one level."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/routers/tscc.py"},"region":{"startLine":159}}}],"partialFingerprints":{"codehealthFindingId/v1":"f0ca6d6901378a4d71704966d9a285785381d462ffab4c3e01a16047a83fa4a9"}},{"ruleId":"D2","level":"warning","message":{"text":"artifact_cli._next_stage_continuation (cognitive 25): artifact_cli._next_stage_continuation has cognitive complexity 25 (threshold 15). Drivers by points: if/else 11 (18 pts), ternaries 2 (3 pts), boolean chains 2, error handling 1 (2 pts) (nesting depth added 9). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/scripts/artifact_cli.py"},"region":{"startLine":617}}}],"partialFingerprints":{"codehealthFindingId/v1":"f16fb735fc50d593780f057d187b78f176bc0c4cc35818ab9cd17f5b146232cd"}},{"ruleId":"D2","level":"warning","message":{"text":"check_migration_class.check_migration_class (cognitive 25): check_migration_class.check_migration_class has cognitive complexity 25 (threshold 15). Drivers by points: if/else 13 (21 pts), loops 2, boolean chains 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":"backend/scripts/check_migration_class.py"},"region":{"startLine":197}}}],"partialFingerprints":{"codehealthFindingId/v1":"ae8356d038cde1a5841ec6c505779aaeb72abc73f33cc47e4d905334dee3da6c"}},{"ruleId":"D2","level":"warning","message":{"text":"scenario_runner.parse_final_text (cognitive 25): scenario_runner.parse_final_text has cognitive complexity 25 (threshold 15). Drivers by points: if/else 8 (18 pts), loops 2 (3 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":"backend/scripts/scenario_runner.py"},"region":{"startLine":114}}}],"partialFingerprints":{"codehealthFindingId/v1":"1ed5cd8e794f1a045c3333a68cf82d76e81ac269d734e5e17e856bcad4ff72eb"}},{"ruleId":"D2","level":"warning","message":{"text":"PPTXSchemaValidator.validate_slide_layout_ids (cognitive 25): PPTXSchemaValidator.validate_slide_layout_ids has cognitive complexity 25 (threshold 15). Drivers by points: if/else 8 (15 pts), loops 4 (7 pts), error handling 1 (2 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":"backend/skills/s_docx/ooxml/scripts/validation/pptx.py"},"region":{"startLine":128}}}],"partialFingerprints":{"codehealthFindingId/v1":"6f6112773df26e507d4ccbcb31417896bbef00b9835b6f3be8f8f274811740c9"}},{"ruleId":"D2","level":"warning","message":{"text":"SelfLoopsHealthEngine._compute_compound_score (cognitive 25): SelfLoopsHealthEngine._compute_compound_score has cognitive complexity 25 (threshold 15). Drivers by points: if/else 11 (15 pts), ternaries 2 (5 pts), error handling 2 (4 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":"backend/skills/s_loops-health/scripts/loops_health_check.py"},"region":{"startLine":1051}}}],"partialFingerprints":{"codehealthFindingId/v1":"cda99fe286661df69d0bb3e38dc5ec7989f612d2e5d2b41347ada102c6c9b78b"}},{"ruleId":"D2","level":"warning","message":{"text":"cross_format_check.main (cognitive 25): cross_format_check.main has cognitive complexity 25 (threshold 15). Drivers by points: if/else 12 (22 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":"backend/skills/s_pollinate/scripts/cross_format_check.py"},"region":{"startLine":266}}}],"partialFingerprints":{"codehealthFindingId/v1":"545c10f7f024573fd3a567364d89487d4c270a892ce97b6cb7c622fbb0dc0389"}},{"ruleId":"D2","level":"warning","message":{"text":"format_recommend.detect_fast_path (cognitive 25): format_recommend.detect_fast_path has cognitive complexity 25 (threshold 15). Drivers by points: if/else 6 (18 pts), boolean chains 3, loops 2 (3 pts), ternaries 1 (nesting depth added 13). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/skills/s_pollinate/scripts/format_recommend.py"},"region":{"startLine":412}}}],"partialFingerprints":{"codehealthFindingId/v1":"5ea514cd14b90195b4be41678cae22a3a2daee0c1da8daf9c11a909b8eef726d"}},{"ruleId":"D2","level":"warning","message":{"text":"PPTXSchemaValidator.validate_slide_layout_ids (cognitive 25): PPTXSchemaValidator.validate_slide_layout_ids has cognitive complexity 25 (threshold 15). Drivers by points: if/else 8 (15 pts), loops 4 (7 pts), error handling 1 (2 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":"backend/skills/s_pptx/ooxml/scripts/validation/pptx.py"},"region":{"startLine":128}}}],"partialFingerprints":{"codehealthFindingId/v1":"2095270cf65e3dc01c9511e4335ab8b15a679adf3a8cd939a87fe428780dfba2"}},{"ruleId":"D2","level":"warning","message":{"text":"steeringify.extract_corrections (cognitive 25): steeringify.extract_corrections has cognitive complexity 25 (threshold 15). Drivers by points: if/else 9 (20 pts), boolean chains 4, 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":"backend/skills/s_steeringify/steeringify.py"},"region":{"startLine":94}}}],"partialFingerprints":{"codehealthFindingId/v1":"9055fd8af545792094b11894c8c3622d679950984f48201eb3414ddc777573cb"}},{"ruleId":"D2","level":"warning","message":{"text":"lint_skills.corpus_files (cognitive 25): lint_skills.corpus_files has cognitive complexity 25 (threshold 15). Drivers by points: if/else 7 (17 pts), loops 2 (3 pts), error handling 1 (2 pts), ternaries 1 (2 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":"scripts/lint_skills.py"},"region":{"startLine":262}}}],"partialFingerprints":{"codehealthFindingId/v1":"84c81201fa31f228e5bbd44ef543a9cd1733fa2476aa58f224102dd8336b798b"}},{"ruleId":"D2","level":"warning","message":{"text":"UpdateNotification.UpdateNotification (cognitive 25): UpdateNotification.UpdateNotification has cognitive complexity 25 (threshold 15). Drivers by points: boolean chains 13, ternaries 3 (5 pts), if/else 4, error handling 3 (nesting depth added 2). Of this number, 15 points are the body\u0027s own statements and 10 belong to 3 function literals inside it that branch. To reduce it, name the conditions: bind each compound test to a well-named local or a small predicate function, so the body reads as a sequence of named decisions rather than a chain of operators."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/common/UpdateNotification.tsx"},"region":{"startLine":16}}}],"partialFingerprints":{"codehealthFindingId/v1":"ba8f8554c5d8d4e9118f9721ed59039bcef2dcf1b864dd47565e14f7a95181fc"}},{"ruleId":"D2","level":"warning","message":{"text":"MergedToolBlock.MergedToolBlock (cognitive 25): MergedToolBlock.MergedToolBlock has cognitive complexity 25 (threshold 15). Drivers by points: ternaries 9 (11 pts), boolean chains 9, if/else 4 (5 pts) (nesting depth added 3). Of this number, 20 points are the body\u0027s own statements and 5 belong to 4 function literals inside it that branch. 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":"desktop/src/pages/chat/components/MergedToolBlock.tsx"},"region":{"startLine":122}}}],"partialFingerprints":{"codehealthFindingId/v1":"85d3b3388126d585101189dc9ad6dc8b5938e39ff03e4dc36df76bef27ec7e69"}},{"ruleId":"D2","level":"warning","message":{"text":"BrainHub.ReviewView (cognitive 25): BrainHub.ReviewView has cognitive complexity 25 (threshold 15). Drivers by points: ternaries 10 (12 pts), boolean chains 5, if/else 5, error handling 3 (nesting depth added 2). Of this number, 17 points are the body\u0027s own statements and 8 belong to 4 function literals inside it that branch. 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":"desktop/src/components/layout/BrainHub.tsx"},"region":{"startLine":840}}}],"partialFingerprints":{"codehealthFindingId/v1":"374043584391a76578d9910ffda8ba75ad91ce5d8b1671a6d152982f510472c2"}},{"ruleId":"D2","level":"warning","message":{"text":"parser._regex_fallback (cognitive 24): parser._regex_fallback has cognitive complexity 24 (threshold 15). Drivers by points: if/else 4 (9 pts), loops 4 (8 pts), ternaries 2 (4 pts), boolean chains 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":"backend/core/code_intel/parser.py"},"region":{"startLine":1742}}}],"partialFingerprints":{"codehealthFindingId/v1":"9ed4a24daa47f6c3a282827dbcbe0e325015905a53b394a7ac68ea9aefaa83b7"}},{"ruleId":"D2","level":"warning","message":{"text":"ContextDirectoryLoader._assemble_from_sources (cognitive 24): ContextDirectoryLoader._assemble_from_sources has cognitive complexity 24 (threshold 15). Drivers by points: if/else 7 (12 pts), error handling 3 (7 pts), boolean chains 2, loops 2, ternaries 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":"backend/core/context_directory_loader.py"},"region":{"startLine":869}}}],"partialFingerprints":{"codehealthFindingId/v1":"971867393d2eccedd62f6b223b54cbc130d76199dcdce9fa8fa83dc90c36d6cb"}},{"ruleId":"D2","level":"warning","message":{"text":"ddd_packager.gate_dangling_skill_refs (cognitive 24): ddd_packager.gate_dangling_skill_refs has cognitive complexity 24 (threshold 15). Drivers by points: if/else 5 (10 pts), loops 3 (6 pts), boolean chains 3, ternaries 2 (3 pts), error handling 1 (2 pts) (nesting depth added 10). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/core/ddd_packager.py"},"region":{"startLine":580}}}],"partialFingerprints":{"codehealthFindingId/v1":"860f1cab3b06fdf90b14c85c307251bc13c69ae52adf412e18982a8ee03bb182"}},{"ruleId":"D2","level":"warning","message":{"text":"memory_index._bm25_scores (cognitive 24): memory_index._bm25_scores has cognitive complexity 24 (threshold 15). Drivers by points: if/else 7 (13 pts), loops 5 (7 pts), ternaries 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":"backend/core/memory_index.py"},"region":{"startLine":267}}}],"partialFingerprints":{"codehealthFindingId/v1":"cee952b150f0e4fbce4da4ae114c7cffc3583c60329a7024e3240a148f9114d4"}},{"ruleId":"D2","level":"warning","message":{"text":"session_health_probe.session_health_probe (cognitive 24): session_health_probe.session_health_probe has cognitive complexity 24 (threshold 15). Drivers by points: boolean chains 7, if/else 5 (7 pts), error handling 5 (6 pts), ternaries 3, loops 1 (nesting depth added 3). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/core/session_health_probe.py"},"region":{"startLine":190}}}],"partialFingerprints":{"codehealthFindingId/v1":"f4ec0f8efe4eac47bf3a2b38a9ee4bf654e2e5caaf116ddea52f621d12360d05"}},{"ruleId":"D2","level":"warning","message":{"text":"StreamingOrchestrator._build_file_delete_events (cognitive 24): StreamingOrchestrator._build_file_delete_events has cognitive complexity 24 (threshold 15). Drivers by points: error handling 3 (8 pts), if/else 4 (8 pts), ternaries 3 (7 pts), loops 1 (nesting depth added 13). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/core/streaming_orchestrator.py"},"region":{"startLine":435}}}],"partialFingerprints":{"codehealthFindingId/v1":"17f7610c1fcc39849d31c75ad93d55f9f65d9f22a28832887120775587ef8f74"}},{"ruleId":"D2","level":"warning","message":{"text":"transcript_indexer.parse_transcript (cognitive 24): transcript_indexer.parse_transcript has cognitive complexity 24 (threshold 15). Drivers by points: if/else 6 (17 pts), loops 2 (4 pts), error handling 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":"backend/core/transcript_indexer.py"},"region":{"startLine":45}}}],"partialFingerprints":{"codehealthFindingId/v1":"93e19ba6a0f00a0467dc7fa72a1ea054b086c318b39278cf9661913ae49d5b3d"}},{"ruleId":"D2","level":"warning","message":{"text":"github_trending.fetch_github_trending (cognitive 24): github_trending.fetch_github_trending has cognitive complexity 24 (threshold 15). Drivers by points: if/else 7 (10 pts), ternaries 4 (8 pts), error handling 2 (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":"backend/jobs/adapters/github_trending.py"},"region":{"startLine":47}}}],"partialFingerprints":{"codehealthFindingId/v1":"2735a576b33944d3253dbeed135c80d206863e356323d847a64da612fe4eb8ac"}},{"ruleId":"D2","level":"warning","message":{"text":"weibo_trending._search_keyword (cognitive 24): weibo_trending._search_keyword has cognitive complexity 24 (threshold 15). Drivers by points: if/else 7 (21 pts), loops 2 (3 pts) (nesting depth added 15). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/jobs/adapters/weibo_trending.py"},"region":{"startLine":135}}}],"partialFingerprints":{"codehealthFindingId/v1":"d9b903db10eabc912c8d07c1c14f64254b2b92cc532294297059f38a3f969257"}},{"ruleId":"D2","level":"warning","message":{"text":"swarmai_monthly_report._collect_prior_month_metrics (cognitive 24): swarmai_monthly_report._collect_prior_month_metrics has cognitive complexity 24 (threshold 15). Drivers by points: if/else 9 (22 pts), loops 1, ternaries 1 (nesting depth added 13). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/jobs/handlers/swarmai_monthly_report.py"},"region":{"startLine":480}}}],"partialFingerprints":{"codehealthFindingId/v1":"725385d46472f1b1f8ce4e33e4f028c6252b5c951005e69d8934170d89cdf41b"}},{"ruleId":"D2","level":"warning","message":{"text":"self_tune.track_signal_usage (cognitive 24): self_tune.track_signal_usage has cognitive complexity 24 (threshold 15). Drivers by points: if/else 6 (13 pts), loops 5 (7 pts), ternaries 2, boolean chains 1, error handling 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":"backend/jobs/self_tune.py"},"region":{"startLine":176}}}],"partialFingerprints":{"codehealthFindingId/v1":"8b130c1f1f151a9c20c8221b798b9a4acb6300a5318f9a628981fccdae30169e"}},{"ruleId":"D2","level":"warning","message":{"text":"DocxXMLEditor.revert_insertion (cognitive 24): DocxXMLEditor.revert_insertion has cognitive complexity 24 (threshold 15). Drivers by points: loops 6 (16 pts), if/else 5 (8 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":"backend/skills/s_docx/scripts/document.py"},"region":{"startLine":264}}}],"partialFingerprints":{"codehealthFindingId/v1":"57baeabf24e93b53688762517340b3686027375fd7f4c6066cc5aae658b3c083"}},{"ruleId":"D2","level":"warning","message":{"text":"phonemes.load_phoneme_dicts (cognitive 24): phonemes.load_phoneme_dicts has cognitive complexity 24 (threshold 15). Drivers by points: if/else 11 (22 pts), boolean chains 1, 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":"backend/skills/s_pollinate/scripts/tts/phonemes.py"},"region":{"startLine":7}}}],"partialFingerprints":{"codehealthFindingId/v1":"6dbed4f21125fe58759f9f3cbfafdde72999d8d6d84c012f77dbd51669ff9ec8"}},{"ruleId":"D2","level":"warning","message":{"text":"todo_db._print_work_packet (cognitive 24): todo_db._print_work_packet has cognitive complexity 24 (threshold 15). Drivers by points: loops 6 (12 pts), if/else 11, ternaries 1 (nesting depth added 6). 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":"backend/skills/s_radar-todo/scripts/todo_db.py"},"region":{"startLine":149}}}],"partialFingerprints":{"codehealthFindingId/v1":"6d231e1662a4e5f9f2901dbd82712eafb7fb11f77c728218d853737532c25308"}},{"ruleId":"D2","level":"warning","message":{"text":"ai_ready_helpers.blind_spot_scan (cognitive 24): ai_ready_helpers.blind_spot_scan has cognitive complexity 24 (threshold 15). Drivers by points: if/else 6 (12 pts), boolean chains 6, loops 5 (6 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":"backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py"},"region":{"startLine":947}}}],"partialFingerprints":{"codehealthFindingId/v1":"0d9277bd7b9c849f749c19b85969a01d6d0e8b4de455b42acc97d4e3ce504c73"}},{"ruleId":"D2","level":"warning","message":{"text":"mcp_validation.validate_config_entry (cognitive 24): mcp_validation.validate_config_entry has cognitive complexity 24 (threshold 15). Drivers by points: if/else 10 (14 pts), boolean chains 8, loops 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":"backend/utils/mcp_validation.py"},"region":{"startLine":105}}}],"partialFingerprints":{"codehealthFindingId/v1":"897a39b74e30c652d10a1a8533d9f9a5a8353582a49ac5c7b716ffb79996097b"}},{"ruleId":"D2","level":"warning","message":{"text":"BottomBar.BottomBar (cognitive 24): BottomBar.BottomBar has cognitive complexity 24 (threshold 15). Drivers by points: if/else 9, boolean chains 8, ternaries 5 (7 pts) (nesting depth added 2). Of this number, 13 points are the body\u0027s own statements and 11 belong to 8 function literals inside it that branch. 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":"desktop/src/components/layout/BottomBar.tsx"},"region":{"startLine":89}}}],"partialFingerprints":{"codehealthFindingId/v1":"56c9e40a0f9a0ccbc58f9bd91f6c2a136ea7c59797e6abf2dbb40a74b9c790ee"}},{"ruleId":"D2","level":"warning","message":{"text":"LibraryOverlay.BrowseTab (cognitive 24): LibraryOverlay.BrowseTab has cognitive complexity 24 (threshold 15). Drivers by points: ternaries 8 (19 pts), boolean chains 5 (nesting depth added 11). Most of this is not in the body itself: 9 of the 24 points are its own statements and the rest belongs to 2 function literals inside it that branch (lines 244, 252). The decisions are inside those literals, which nothing outside this body can call, review or test on its own, so splitting the enclosing body is not the move available here. To reduce it, lift the literals\u0027 work into a named function or method at the enclosing scope and have each literal call it, then reduce whichever part then reads as the largest."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/layout/LibraryOverlay.tsx"},"region":{"startLine":198}}}],"partialFingerprints":{"codehealthFindingId/v1":"c8d7eed40d23ec44ba2826d7d5a37b15127b32702228514ddffd5c497ab3f546"}},{"ruleId":"D2","level":"warning","message":{"text":"SystemTab.SystemTab (cognitive 24): SystemTab.SystemTab has cognitive complexity 24 (threshold 15). Drivers by points: ternaries 5 (9 pts), boolean chains 6, error handling 4 (5 pts), if/else 3 (4 pts) (nesting depth added 6). Of this number, 12 points are the body\u0027s own statements and 12 belong to 2 function literals inside it that branch. To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/settings/SystemTab.tsx"},"region":{"startLine":26}}}],"partialFingerprints":{"codehealthFindingId/v1":"471af5c3ab9b9416fd768ea9511a04a7c05a18bb003ca4de325dba59261956e9"}},{"ruleId":"D2","level":"warning","message":{"text":"FileBrowser.FileBrowser (cognitive 24): FileBrowser.FileBrowser has cognitive complexity 24 (threshold 15). Drivers by points: ternaries 8 (15 pts), if/else 5, boolean chains 4 (nesting depth added 7). Of this number, 13 points are the body\u0027s own statements and 11 belong to 4 function literals inside it that branch. To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/workspace/FileBrowser.tsx"},"region":{"startLine":99}}}],"partialFingerprints":{"codehealthFindingId/v1":"18e82cc8ca06efef4780054115c941baadd3c8fd249b1545a7a5d879e7c854a7"}},{"ruleId":"D2","level":"warning","message":{"text":"ChannelGateway._should_reply (cognitive 23): ChannelGateway._should_reply has cognitive complexity 23 (threshold 15). Drivers by points: if/else 8 (12 pts), boolean chains 7, error handling 1 (3 pts), ternaries 1 (nesting depth added 6). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/channels/gateway.py"},"region":{"startLine":1164}}}],"partialFingerprints":{"codehealthFindingId/v1":"2c3efb864a18853015600db944f3985dddcaa06c53aa08256b632783d4546a56"}},{"ruleId":"D2","level":"warning","message":{"text":"module_map.detect_cross_module_changes (cognitive 23): module_map.detect_cross_module_changes has cognitive complexity 23 (threshold 15). Drivers by points: if/else 3 (10 pts), loops 6 (9 pts), error handling 2 (3 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":"backend/core/code_intel/module_map.py"},"region":{"startLine":195}}}],"partialFingerprints":{"codehealthFindingId/v1":"bf71b7d91689c99397d594b0f2398c365d79675d64b71033de6b34909c25e024"}},{"ruleId":"D2","level":"warning","message":{"text":"context_injector._extract_skill_invocations (cognitive 23): context_injector._extract_skill_invocations has cognitive complexity 23 (threshold 15). Drivers by points: if/else 6 (17 pts), loops 2 (3 pts), boolean chains 2, error handling 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":"backend/core/context_injector.py"},"region":{"startLine":397}}}],"partialFingerprints":{"codehealthFindingId/v1":"b58494eb023c91d90cbce66e58b6565488335d4928ed66e370ca23a3c992a92d"}},{"ruleId":"D2","level":"warning","message":{"text":"ddd_bindings.describe_project_ddd_line (cognitive 23): ddd_bindings.describe_project_ddd_line has cognitive complexity 23 (threshold 15). Drivers by points: if/else 12 (16 pts), error handling 2 (3 pts), ternaries 3, 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":"backend/core/ddd_bindings.py"},"region":{"startLine":545}}}],"partialFingerprints":{"codehealthFindingId/v1":"6662bcedeb289b601d47269d379ee33dd5d79305ae4892d9f8517dd4fbb1dc75"}},{"ruleId":"D2","level":"warning","message":{"text":"ddd_health._build_changelog_index (cognitive 23): ddd_health._build_changelog_index has cognitive complexity 23 (threshold 15). Drivers by points: if/else 7 (14 pts), error handling 3 (5 pts), boolean chains 3, 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":"backend/core/ddd_health.py"},"region":{"startLine":159}}}],"partialFingerprints":{"codehealthFindingId/v1":"f312f3fc4440f05922ea36052454623444fd877a1262f5aa3ee28d3fa939cea0"}},{"ruleId":"D2","level":"warning","message":{"text":"library_health.apply_action (cognitive 23): library_health.apply_action has cognitive complexity 23 (threshold 15). Drivers by points: if/else 6 (11 pts), loops 2 (5 pts), error handling 2 (4 pts), boolean chains 2, ternaries 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":"backend/core/library_health.py"},"region":{"startLine":191}}}],"partialFingerprints":{"codehealthFindingId/v1":"420f66c52bb2ec894f6fab850aaf7a80974c1501250dda4425b7503d000838d3"}},{"ruleId":"D2","level":"warning","message":{"text":"proactive_intelligence._extract_jobs_summary (cognitive 23): proactive_intelligence._extract_jobs_summary has cognitive complexity 23 (threshold 15). Drivers by points: if/else 6 (9 pts), error handling 4 (8 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":"backend/core/proactive_intelligence.py"},"region":{"startLine":1703}}}],"partialFingerprints":{"codehealthFindingId/v1":"df55f703d1fe681ac83c867bbd4f800ddd5836e2c8d4d45d375406f3180c1752"}},{"ruleId":"D2","level":"warning","message":{"text":"recall_multi._ddd_entry_hits (cognitive 23): recall_multi._ddd_entry_hits has cognitive complexity 23 (threshold 15). Drivers by points: if/else 7 (15 pts), loops 3 (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":"backend/core/recall_multi.py"},"region":{"startLine":98}}}],"partialFingerprints":{"codehealthFindingId/v1":"1bbd9e441f9bfda2da73b7b9da654d3cc4147228145d73b37ad453fe6bd76d45"}},{"ruleId":"D2","level":"warning","message":{"text":"SessionRouter._acquire_chat_slot (cognitive 23): SessionRouter._acquire_chat_slot has cognitive complexity 23 (threshold 15). Drivers by points: if/else 11 (18 pts), error handling 1 (2 pts), boolean chains 1, 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":"backend/core/session_router.py"},"region":{"startLine":2291}}}],"partialFingerprints":{"codehealthFindingId/v1":"672e836dff712cef3c52699c8c97187392ebccad6789f869f19ea20cf8505d06"}},{"ruleId":"D2","level":"warning","message":{"text":"session_router._convert_unsupported_blocks_to_path_hints (cognitive 23): session_router._convert_unsupported_blocks_to_path_hints has cognitive complexity 23 (threshold 15). Drivers by points: if/else 7 (15 pts), error handling 1 (3 pts), ternaries 1 (3 pts), boolean chains 1, 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":"backend/core/session_router.py"},"region":{"startLine":1556}}}],"partialFingerprints":{"codehealthFindingId/v1":"26ab0ad48c860a242159357725fee69763bf6922d951fb5d0e73261e914eecbf"}},{"ruleId":"D2","level":"warning","message":{"text":"swarm_workspace_manager._load_ddd_native_skill_templates (cognitive 23): swarm_workspace_manager._load_ddd_native_skill_templates has cognitive complexity 23 (threshold 15). Drivers by points: if/else 5 (13 pts), error handling 2 (6 pts), loops 2 (3 pts), boolean chains 1 (nesting depth added 13). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/core/swarm_workspace_manager.py"},"region":{"startLine":630}}}],"partialFingerprints":{"codehealthFindingId/v1":"0f6efeaa97b6795ee2f2f643c65306a5e92df7044be8a5315b55350aa79a6be6"}},{"ruleId":"D2","level":"warning","message":{"text":"ContextHealthHook._check_self_report_drift (cognitive 23): ContextHealthHook._check_self_report_drift has cognitive complexity 23 (threshold 15). Drivers by points: if/else 5 (13 pts), error handling 2 (5 pts), loops 2 (3 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":"backend/hooks/context_health_hook.py"},"region":{"startLine":3167}}}],"partialFingerprints":{"codehealthFindingId/v1":"2dd43b33942ed400b09ff06db2a46f4d9a5d376a71abe88e99695860bf6de8fd"}},{"ruleId":"D2","level":"warning","message":{"text":"DistillationTriggerHook._reconcile_open_threads_from_deliverables (cognitive 23): DistillationTriggerHook._reconcile_open_threads_from_deliverables has cognitive complexity 23 (threshold 15). Drivers by points: if/else 6 (12 pts), boolean chains 5, error handling 2 (3 pts), 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":"backend/hooks/distillation_hook.py"},"region":{"startLine":2053}}}],"partialFingerprints":{"codehealthFindingId/v1":"ac85a8a0767e5f7474b051d143a4fcbbd7d3bcbe020ffb55047a26bd17531612"}},{"ruleId":"D2","level":"warning","message":{"text":"ImprovementWritebackHook._extract_lessons (cognitive 23): ImprovementWritebackHook._extract_lessons has cognitive complexity 23 (threshold 15). Drivers by points: if/else 8 (18 pts), boolean chains 2, ternaries 1 (2 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":"backend/hooks/improvement_writeback_hook.py"},"region":{"startLine":212}}}],"partialFingerprints":{"codehealthFindingId/v1":"d895c76afa0503fe96f2b3bf0158fd19e5cd8f100dd533da53e7fca93a4470cd"}},{"ruleId":"D2","level":"warning","message":{"text":"trending.fetch_trending (cognitive 23): trending.fetch_trending has cognitive complexity 23 (threshold 15). Drivers by points: if/else 7 (15 pts), boolean chains 3, loops 2 (3 pts), error handling 1 (2 pts) (nesting depth added 10). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/jobs/adapters/trending.py"},"region":{"startLine":47}}}],"partialFingerprints":{"codehealthFindingId/v1":"19730b9a53bfded8ed96db1ebbb38a7b3852e6452bda33021348317adfda9872"}},{"ruleId":"D2","level":"warning","message":{"text":"artifact_cli._auto_validate_before_advance (cognitive 23): artifact_cli._auto_validate_before_advance has cognitive complexity 23 (threshold 15). Drivers by points: if/else 12 (16 pts), boolean chains 3, error handling 3, 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":"backend/scripts/artifact_cli.py"},"region":{"startLine":827}}}],"partialFingerprints":{"codehealthFindingId/v1":"144d195b5df4dcd886d6054a55a80b4d125ac3107df78f65f6fc6be7dc2bcd1c"}},{"ruleId":"D2","level":"warning","message":{"text":"RedliningValidator._get_git_word_diff (cognitive 23): RedliningValidator._get_git_word_diff has cognitive complexity 23 (threshold 15). Drivers by points: if/else 7 (16 pts), loops 2 (4 pts), boolean chains 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":"backend/skills/s_docx/ooxml/scripts/validation/redlining.py"},"region":{"startLine":139}}}],"partialFingerprints":{"codehealthFindingId/v1":"d9eb9e4d6a31707f7e146d7236ac752b469a58f0d192a865731ad0a605963921"}},{"ruleId":"D2","level":"warning","message":{"text":"RedliningValidator._get_git_word_diff (cognitive 23): RedliningValidator._get_git_word_diff has cognitive complexity 23 (threshold 15). Drivers by points: if/else 7 (16 pts), loops 2 (4 pts), boolean chains 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":"backend/skills/s_pptx/ooxml/scripts/validation/redlining.py"},"region":{"startLine":139}}}],"partialFingerprints":{"codehealthFindingId/v1":"98994d155e9365fa032af5c404fa144bc27211b29f9c407db4771e8cec7fa510"}},{"ruleId":"D2","level":"warning","message":{"text":"style-extract.aggregate_style (cognitive 23): style-extract.aggregate_style has cognitive complexity 23 (threshold 15). Drivers by points: if/else 5 (15 pts), loops 3 (5 pts), boolean chains 3 (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":"backend/skills/s_pptx/scripts/style-extract.py"},"region":{"startLine":201}}}],"partialFingerprints":{"codehealthFindingId/v1":"46e3165050ad08d5a3cc6df4e964bb638d8cc948bdae431a257a750ad1657746"}},{"ruleId":"D2","level":"warning","message":{"text":"ai_ready_helpers.score_equivalence (cognitive 23): ai_ready_helpers.score_equivalence has cognitive complexity 23 (threshold 15). Drivers by points: if/else 8 (14 pts), boolean chains 5, loops 3, ternaries 1 (nesting depth added 6). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py"},"region":{"startLine":1803}}}],"partialFingerprints":{"codehealthFindingId/v1":"a008ab64c1089f5c1a3bf2a3e8fddff8d578c9ffb478e82e0da50677b31b8bd3"}},{"ruleId":"D2","level":"warning","message":{"text":"ai_ready_helpers.evaluate_verification_response (cognitive 23): ai_ready_helpers.evaluate_verification_response has cognitive complexity 23 (threshold 15). Drivers by points: if/else 8 (17 pts), loops 2 (3 pts), boolean chains 2, ternaries 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":"backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py"},"region":{"startLine":3422}}}],"partialFingerprints":{"codehealthFindingId/v1":"6f5f5b01b00c23b6b380a26cd67f9efb55395d4783a94401b66f68fa587b6c23"}},{"ruleId":"D2","level":"warning","message":{"text":"ai_ready_helpers.score_equivalence (cognitive 23): ai_ready_helpers.score_equivalence has cognitive complexity 23 (threshold 15). Drivers by points: if/else 8 (14 pts), boolean chains 5, loops 3, ternaries 1 (nesting depth added 6). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py"},"region":{"startLine":1467}}}],"partialFingerprints":{"codehealthFindingId/v1":"b11d05f3e86770c1cf0a903ae6ea7485a733c3349ab33ea8bbeee52b17c0a098"}},{"ruleId":"D2","level":"warning","message":{"text":"diff_parser.format_human_summary (cognitive 23): diff_parser.format_human_summary has cognitive complexity 23 (threshold 15). Drivers by points: if/else 9 (16 pts), boolean chains 3, ternaries 2 (3 pts), 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":"backend/utils/diff_parser.py"},"region":{"startLine":86}}}],"partialFingerprints":{"codehealthFindingId/v1":"ec2d088383dc64756f6c79515e4adb86a27e25d0c8a1fca89fe20bdb7991030f"}},{"ruleId":"D2","level":"warning","message":{"text":"lint_doc_frontmatter.main (cognitive 23): lint_doc_frontmatter.main has cognitive complexity 23 (threshold 15). Drivers by points: if/else 10 (16 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":"scripts/lint_doc_frontmatter.py"},"region":{"startLine":134}}}],"partialFingerprints":{"codehealthFindingId/v1":"6ea9035ce55e61eb1b9eabd1706672ae66632eb8e9dbf109d950bc3182c617d6"}},{"ruleId":"D2","level":"warning","message":{"text":"uiCommands.dispatchUiCommand (cognitive 23): uiCommands.dispatchUiCommand has cognitive complexity 23 (threshold 15). Drivers by points: if/else 7 (10 pts), ternaries 4 (7 pts), boolean chains 6 (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":"desktop/src/utils/uiCommands.ts"},"region":{"startLine":99}}}],"partialFingerprints":{"codehealthFindingId/v1":"5f26023fb6138eb5789f7f52729277f5b7705777c11a40cec3ecb85cf1575a0f"}},{"ruleId":"D2","level":"warning","message":{"text":"BackupTab.BackupTab (cognitive 23): BackupTab.BackupTab has cognitive complexity 23 (threshold 15). Drivers by points: boolean chains 10, ternaries 5 (6 pts), error handling 4, if/else 3 (nesting depth added 1). Of this number, 13 points are the body\u0027s own statements and 10 belong to 6 function literals inside it that branch. To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/settings/BackupTab.tsx"},"region":{"startLine":15}}}],"partialFingerprints":{"codehealthFindingId/v1":"712d537875907f1cf70a7927dba56ae515343ec94ec04a0d685cb4fb8a5ac26b"}},{"ruleId":"D2","level":"warning","message":{"text":"SlackChannelAdapter._mcp_post_message (cognitive 22): SlackChannelAdapter._mcp_post_message has cognitive complexity 22 (threshold 15). Drivers by points: if/else 6 (14 pts), error handling 1 (4 pts), boolean chains 2, loops 1 (2 pts) (nesting depth added 12). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/channels/adapters/slack.py"},"region":{"startLine":1348}}}],"partialFingerprints":{"codehealthFindingId/v1":"5f04efe303d1d5e613bc5679a44f485626587b2abd93cd00e9dd6fd7f029a062"}},{"ruleId":"D2","level":"warning","message":{"text":"graph_analysis._build_file_domain_map (cognitive 22): graph_analysis._build_file_domain_map has cognitive complexity 22 (threshold 15). Drivers by points: if/else 4 (10 pts), boolean chains 6, loops 4 (6 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":"backend/core/code_intel/graph_analysis.py"},"region":{"startLine":93}}}],"partialFingerprints":{"codehealthFindingId/v1":"65dde50cc992d0accb97ca926e4329d9a37fec98c35f010b294142e4d247d9db"}},{"ruleId":"D2","level":"warning","message":{"text":"parser._resolve_binding_name_nodes (cognitive 22): parser._resolve_binding_name_nodes has cognitive complexity 22 (threshold 15). Drivers by points: if/else 7 (15 pts), ternaries 2 (4 pts), loops 1 (2 pts), boolean chains 1 (nesting depth added 11). 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":"backend/core/code_intel/parser.py"},"region":{"startLine":359}}}],"partialFingerprints":{"codehealthFindingId/v1":"f8170f777fc1f51f833303d8bbd6f272b8db8637e88b3b45d07a15d9853e76ae"}},{"ruleId":"D2","level":"warning","message":{"text":"ddd_cultivation.filter_lessons_for_ddd (cognitive 22): ddd_cultivation.filter_lessons_for_ddd has cognitive complexity 22 (threshold 15). Drivers by points: if/else 7 (16 pts), boolean chains 3, ternaries 1 (2 pts), loops 1 (nesting depth added 10). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/core/ddd_cultivation.py"},"region":{"startLine":723}}}],"partialFingerprints":{"codehealthFindingId/v1":"33bec1f50125b156a3f873d660f07a5cc60f8d9d1f2c5dd586298d70a596a9ea"}},{"ruleId":"D2","level":"warning","message":{"text":"LifecycleManager._sample_process_memory (cognitive 22): LifecycleManager._sample_process_memory has cognitive complexity 22 (threshold 15). Drivers by points: if/else 9 (16 pts), boolean chains 4, error handling 1, 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":"backend/core/lifecycle_manager.py"},"region":{"startLine":335}}}],"partialFingerprints":{"codehealthFindingId/v1":"b012287a41dca7357e86aa481f440b4db1aa9d0f0f901658875a22a513b2635a"}},{"ruleId":"D2","level":"warning","message":{"text":"RecallEngine.search (cognitive 22): RecallEngine.search has cognitive complexity 22 (threshold 15). Drivers by points: if/else 4 (7 pts), ternaries 2 (7 pts), loops 3 (5 pts), error handling 1 (2 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":"backend/core/recall_engine.py"},"region":{"startLine":57}}}],"partialFingerprints":{"codehealthFindingId/v1":"9bac58852f5f3bfc9e874eec25db5b3cc077b51803cf9144444d0768fbbed984"}},{"ruleId":"D2","level":"warning","message":{"text":"SwarmWorkspaceManager.verify_integrity (cognitive 22): SwarmWorkspaceManager.verify_integrity has cognitive complexity 22 (threshold 15). Drivers by points: if/else 7 (15 pts), loops 3 (4 pts), error handling 1 (2 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":"backend/core/swarm_workspace_manager.py"},"region":{"startLine":2207}}}],"partialFingerprints":{"codehealthFindingId/v1":"3a6eae5c4cd0f23bcb067aed65e4e29232bc781823ef5f2bbbf1d8d68802f6df"}},{"ruleId":"D2","level":"warning","message":{"text":"ContextHealthHook._auto_update_doc_frontmatter (cognitive 22): ContextHealthHook._auto_update_doc_frontmatter has cognitive complexity 22 (threshold 15). Drivers by points: if/else 11 (18 pts), error handling 2 (3 pts), 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":"backend/hooks/context_health_hook.py"},"region":{"startLine":492}}}],"partialFingerprints":{"codehealthFindingId/v1":"2ffd0aabc8e011c5e530078b7f6f35b94a27b11b0d1ca93f5c33366abd48980b"}},{"ruleId":"D2","level":"warning","message":{"text":"ContextHealthHook._sync_transcript_index (cognitive 22): ContextHealthHook._sync_transcript_index has cognitive complexity 22 (threshold 15). Drivers by points: if/else 11 (18 pts), error handling 2 (4 pts) (nesting depth added 9). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/hooks/context_health_hook.py"},"region":{"startLine":2393}}}],"partialFingerprints":{"codehealthFindingId/v1":"7803cd560cbbe80ecfb81643e57ba72ffdf5677fe44cd5de9d69e5d8aca53a11"}},{"ruleId":"D2","level":"warning","message":{"text":"data_point_folding._fold_one_family (cognitive 22): data_point_folding._fold_one_family has cognitive complexity 22 (threshold 15). Drivers by points: if/else 11 (15 pts), loops 3, boolean chains 2, error handling 1, ternaries 1 (nesting depth added 4). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/hooks/data_point_folding.py"},"region":{"startLine":201}}}],"partialFingerprints":{"codehealthFindingId/v1":"266047cc181843bda25f7051c64e0336906f30ab5e24ac7d1861e62fa3f6a13a"}},{"ruleId":"D2","level":"warning","message":{"text":"DistillationTriggerHook._verify_claim_against_git (cognitive 22): DistillationTriggerHook._verify_claim_against_git has cognitive complexity 22 (threshold 15). Drivers by points: if/else 6 (9 pts), error handling 3 (6 pts), boolean chains 4, loops 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":"backend/hooks/distillation_hook.py"},"region":{"startLine":1493}}}],"partialFingerprints":{"codehealthFindingId/v1":"cee76d946bd87a840a77296c24389f82b77090ad04b68801ff017121b6267493"}},{"ruleId":"D2","level":"warning","message":{"text":"KnowledgeBackflowHook._execute_inner (cognitive 22): KnowledgeBackflowHook._execute_inner has cognitive complexity 22 (threshold 15). Drivers by points: if/else 10 (19 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":"backend/hooks/knowledge_backflow_hook.py"},"region":{"startLine":253}}}],"partialFingerprints":{"codehealthFindingId/v1":"42a64be69aaa702d9b33906f1cdb7786f2c7ba5e8b1251155d9feea9030c52a1"}},{"ruleId":"D2","level":"warning","message":{"text":"clean_foreign_run_stubs.find_foreign_stubs (cognitive 22): clean_foreign_run_stubs.find_foreign_stubs has cognitive complexity 22 (threshold 15). Drivers by points: if/else 4 (11 pts), loops 4 (6 pts), boolean chains 3, error handling 1 (2 pts) (nesting depth added 10). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/scripts/clean_foreign_run_stubs.py"},"region":{"startLine":59}}}],"partialFingerprints":{"codehealthFindingId/v1":"e8fef6c731687daef1290ec470c6128261f5a6851ff445f17982556331b46006"}},{"ruleId":"D2","level":"warning","message":{"text":"pipeline_validator.check_artifact_freshness (cognitive 22): pipeline_validator.check_artifact_freshness has cognitive complexity 22 (threshold 15). Drivers by points: if/else 10 (15 pts), error handling 2 (5 pts), loops 1 (2 pts) (nesting depth added 9). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/scripts/pipeline_validator.py"},"region":{"startLine":2511}}}],"partialFingerprints":{"codehealthFindingId/v1":"0b65707c1548dd5d3326ee902c39c9fceb482be8e5e0f35ddd6f5d3aac781002"}},{"ruleId":"D2","level":"warning","message":{"text":"pipeline_validator.main (cognitive 22): pipeline_validator.main has cognitive complexity 22 (threshold 15). Drivers by points: if/else 6 (12 pts), ternaries 3 (6 pts), error handling 1 (2 pts), loops 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":"backend/scripts/pipeline_validator.py"},"region":{"startLine":3642}}}],"partialFingerprints":{"codehealthFindingId/v1":"0693044683504101bf720d527c8143d1289a748b6d3ee64eed7e8e0679f05c1e"}},{"ruleId":"D2","level":"warning","message":{"text":"update_convergence.append_to_convergence (cognitive 22): update_convergence.append_to_convergence has cognitive complexity 22 (threshold 15). Drivers by points: if/else 8 (16 pts), loops 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":"backend/scripts/update_convergence.py"},"region":{"startLine":177}}}],"partialFingerprints":{"codehealthFindingId/v1":"8e28d72ed83c67f505b32be0f76556e1aa4894dbcef6d7e3d8955635c1f4ac04"}},{"ruleId":"D2","level":"warning","message":{"text":"BaseSchemaValidator.validate_against_xsd (cognitive 22): BaseSchemaValidator.validate_against_xsd has cognitive complexity 22 (threshold 15). Drivers by points: if/else 7 (11 pts), loops 3 (5 pts), boolean chains 3, 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":"backend/skills/s_docx/ooxml/scripts/validation/base.py"},"region":{"startLine":688}}}],"partialFingerprints":{"codehealthFindingId/v1":"6911aa67d4a60e0336685afbee97ba43a87506018e0471ea324f67be9d2df7f0"}},{"ruleId":"D2","level":"warning","message":{"text":"cross_format_check.check_message_alignment (cognitive 22): cross_format_check.check_message_alignment has cognitive complexity 22 (threshold 15). Drivers by points: if/else 12 (18 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":"backend/skills/s_pollinate/scripts/cross_format_check.py"},"region":{"startLine":79}}}],"partialFingerprints":{"codehealthFindingId/v1":"c62d47c034ed9a0dbdc312c977d7c2c5625546b2c39c21ea64c0375ee549dd5b"}},{"ruleId":"D2","level":"warning","message":{"text":"cross_format_check.check_data_integrity (cognitive 22): cross_format_check.check_data_integrity has cognitive complexity 22 (threshold 15). Drivers by points: if/else 7 (13 pts), loops 5 (9 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":"backend/skills/s_pollinate/scripts/cross_format_check.py"},"region":{"startLine":136}}}],"partialFingerprints":{"codehealthFindingId/v1":"d17725bca0eee191e7f85f51b18b750ca7eb88e12889e7060d3e8431a9d91725"}},{"ruleId":"D2","level":"warning","message":{"text":"deck_notes_injector.main (cognitive 22): deck_notes_injector.main has cognitive complexity 22 (threshold 15). Drivers by points: if/else 9 (12 pts), loops 2 (6 pts), ternaries 2 (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":"backend/skills/s_pollinate/scripts/deck_notes_injector.py"},"region":{"startLine":264}}}],"partialFingerprints":{"codehealthFindingId/v1":"985d3bae44a66dad5cefbf4e2afc2a79da84777c156092f0bf5c22c5b9d9064d"}},{"ruleId":"D2","level":"warning","message":{"text":"format_recommend.main (cognitive 22): format_recommend.main has cognitive complexity 22 (threshold 15). Drivers by points: if/else 10 (15 pts), loops 2 (5 pts), ternaries 1 (2 pts) (nesting depth added 9). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/skills/s_pollinate/scripts/format_recommend.py"},"region":{"startLine":502}}}],"partialFingerprints":{"codehealthFindingId/v1":"587c5d5854892040a74b54cea3ce3433bf0af6651b813ada244bebc1873f6bab"}},{"ruleId":"D2","level":"warning","message":{"text":"BaseSchemaValidator.validate_against_xsd (cognitive 22): BaseSchemaValidator.validate_against_xsd has cognitive complexity 22 (threshold 15). Drivers by points: if/else 7 (11 pts), loops 3 (5 pts), boolean chains 3, 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":"backend/skills/s_pptx/ooxml/scripts/validation/base.py"},"region":{"startLine":691}}}],"partialFingerprints":{"codehealthFindingId/v1":"8876037d514548c9e211d04d22fe7466f333617ead04474e1f195d10a7964a11"}},{"ruleId":"D2","level":"warning","message":{"text":"ai_ready_helpers._parse_git_log (cognitive 22): ai_ready_helpers._parse_git_log has cognitive complexity 22 (threshold 15). Drivers by points: if/else 7 (19 pts), boolean chains 2, loops 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":"backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py"},"region":{"startLine":1981}}}],"partialFingerprints":{"codehealthFindingId/v1":"da7cd8f912828b0c868c59d8740ed295ede847ac66ee1790f371d7e1305ff4fc"}},{"ruleId":"D2","level":"warning","message":{"text":"ai_ready_helpers.prioritized_file_list (cognitive 22): ai_ready_helpers.prioritized_file_list has cognitive complexity 22 (threshold 15). Drivers by points: if/else 11 (14 pts), boolean chains 3, error handling 2, loops 1 (2 pts), ternaries 1 (nesting depth added 4). To reduce it, split the body: most of this score is breadth rather than depth \u2014 checks laid out side by side rather than stacked \u2014 so group the statements between the checks into named steps and move each step into its own function. Some of it IS depth: where a check sits inside another whose only job is to reach it, merge the two into one condition."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py"},"region":{"startLine":3173}}}],"partialFingerprints":{"codehealthFindingId/v1":"5aeed17f75bd7420b186178e8414c0ce9718105ad684dd6b78a29ffb1751b250"}},{"ruleId":"D2","level":"warning","message":{"text":"md_freeze.split_blocks (cognitive 22): md_freeze.split_blocks has cognitive complexity 22 (threshold 15). Drivers by points: if/else 7 (15 pts), ternaries 1 (5 pts), boolean chains 1, loops 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":"backend/skills/s_translate/scripts/md_freeze.py"},"region":{"startLine":96}}}],"partialFingerprints":{"codehealthFindingId/v1":"3372910cde8760d530b7dda50c825fa2c450dc350379de150d3c2576369c6cc6"}},{"ruleId":"D2","level":"warning","message":{"text":"ai_ready_helpers._parse_git_log (cognitive 22): ai_ready_helpers._parse_git_log has cognitive complexity 22 (threshold 15). Drivers by points: if/else 7 (19 pts), boolean chains 2, loops 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":"backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py"},"region":{"startLine":1645}}}],"partialFingerprints":{"codehealthFindingId/v1":"54ed10728843059aedec49030e9842718f3fdce4c267ab7c147f26d5ef7a8ecc"}},{"ruleId":"D2","level":"warning","message":{"text":"ai_ready_helpers.prioritized_file_list (cognitive 22): ai_ready_helpers.prioritized_file_list has cognitive complexity 22 (threshold 15). Drivers by points: if/else 11 (14 pts), boolean chains 3, error handling 2, loops 1 (2 pts), ternaries 1 (nesting depth added 4). To reduce it, split the body: most of this score is breadth rather than depth \u2014 checks laid out side by side rather than stacked \u2014 so group the statements between the checks into named steps and move each step into its own function. Some of it IS depth: where a check sits inside another whose only job is to reach it, merge the two into one condition."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py"},"region":{"startLine":2826}}}],"partialFingerprints":{"codehealthFindingId/v1":"e1e3da6de28a2a0ef3efd841f21b3a86c29b79389075c4c1895f80f58d9f1a90"}},{"ruleId":"D2","level":"warning","message":{"text":"swarmai::get_fallback_path (cognitive 22): swarmai::get_fallback_path has cognitive complexity 22 (threshold 15). Drivers by points: if/else 6 (14 pts), loops 3 (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":"desktop/src-tauri/src/lib.rs"},"region":{"startLine":124}}}],"partialFingerprints":{"codehealthFindingId/v1":"38872a4624c2d74e4dd44f7df849f1324d6fab86a6132107c694efc70842299a"}},{"ruleId":"D2","level":"warning","message":{"text":"html2pptx.validateTextBoxPosition (cognitive 22): html2pptx.validateTextBoxPosition has cognitive complexity 22 (threshold 15). Drivers by points: if/else 5 (17 pts), boolean chains 4, loops 1 (nesting depth added 12). Most of this is not in the body itself: 8 of the 22 points are its own statements and the rest belongs to one function literal inside it that branches (line 101). The decisions are inside the literal, which nothing outside this body can call, review or test on its own, so splitting the enclosing body is not the move available here. To reduce it, lift the literal\u0027s work into a named function or method at the enclosing scope and have the literal call it, then reduce whichever part then reads as the largest."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/skills/s_pptx/scripts/html2pptx.js"},"region":{"startLine":88}}}],"partialFingerprints":{"codehealthFindingId/v1":"ca78f439d703d8620fe0ca8ec187f0c9404a4b9f2f392d6b22ebaeb010344e6b"}},{"ruleId":"D2","level":"warning","message":{"text":"HistoryOverlay.HistoryContent (cognitive 22): HistoryOverlay.HistoryContent has cognitive complexity 22 (threshold 15). Drivers by points: if/else 10 (12 pts), ternaries 4 (7 pts), error handling 2, boolean chains 1 (nesting depth added 5). Most of this is not in the body itself: 6 of the 22 points are its own statements and the rest belongs to 7 function literals inside it that branch (lines 91, 117, 138, \u2026). The decisions are inside those literals, which nothing outside this body can call, review or test on its own, so splitting the enclosing body is not the move available here. To reduce it, lift the literals\u0027 work into a named function or method at the enclosing scope and have each literal call it, then reduce whichever part then reads as the largest."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/layout/HistoryOverlay.tsx"},"region":{"startLine":59}}}],"partialFingerprints":{"codehealthFindingId/v1":"47138b29b4222463112d82816bedd787a6720eacf8d345c62bff0dc445325297"}},{"ruleId":"D2","level":"warning","message":{"text":"CommunityOverlay.SourcesTab (cognitive 22): CommunityOverlay.SourcesTab has cognitive complexity 22 (threshold 15). Drivers by points: ternaries 10 (15 pts), boolean chains 5, error handling 1, if/else 1 (nesting depth added 5). Most of this is not in the body itself: 3 of the 22 points are its own statements and the rest belongs to 4 function literals inside it that branch (lines 423, 386, 391, \u2026). The decisions are inside those literals, which nothing outside this body can call, review or test on its own, so splitting the enclosing body is not the move available here. To reduce it, lift the literals\u0027 work into a named function or method at the enclosing scope and have each literal call it, then reduce whichever part then reads as the largest."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/layout/CommunityOverlay.tsx"},"region":{"startLine":374}}}],"partialFingerprints":{"codehealthFindingId/v1":"bdf05bcc8ad2af8c615c4efa10b401d7afbedf8b7b1974d1e1dd22be073b386b"}},{"ruleId":"D2","level":"warning","message":{"text":"AboutTab.AboutTab (cognitive 22): AboutTab.AboutTab has cognitive complexity 22 (threshold 15). Drivers by points: boolean chains 10, if/else 6, ternaries 2 (4 pts), error handling 2 (nesting depth added 2). Most of this is not in the body itself: 9 of the 22 points are its own statements and the rest belongs to 4 function literals inside it that branch (lines 47, 64, 33, \u2026). The decisions are inside those literals, which nothing outside this body can call, review or test on its own, so splitting the enclosing body is not the move available here. To reduce it, lift the literals\u0027 work into a named function or method at the enclosing scope and have each literal call it, then reduce whichever part then reads as the largest."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/settings/AboutTab.tsx"},"region":{"startLine":26}}}],"partialFingerprints":{"codehealthFindingId/v1":"bd56f550f34e2fddcd929445a5fc28cb66ac5733e1a831885047c43434b41f78"}},{"ruleId":"D2","level":"warning","message":{"text":"SlackChannelAdapter._normalize_event (cognitive 21): SlackChannelAdapter._normalize_event has cognitive complexity 21 (threshold 15). Drivers by points: if/else 9 (14 pts), boolean chains 6, 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":"backend/channels/adapters/slack.py"},"region":{"startLine":586}}}],"partialFingerprints":{"codehealthFindingId/v1":"36ac705712167f1aa2a3c40423bc5eae556f24d239f3b2407dfcb619bfd102ae"}},{"ruleId":"D2","level":"warning","message":{"text":"ChannelGateway._retry_loop (cognitive 21): ChannelGateway._retry_loop has cognitive complexity 21 (threshold 15). Drivers by points: if/else 7 (16 pts), error handling 2 (4 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":"backend/channels/gateway.py"},"region":{"startLine":1019}}}],"partialFingerprints":{"codehealthFindingId/v1":"a6bfc43bd2e971320a442be9a851936f66a7ec74db00562db4376c5484ae6632"}},{"ruleId":"D2","level":"warning","message":{"text":"HumanResponseFormatter._split_on_boundaries (cognitive 21): HumanResponseFormatter._split_on_boundaries has cognitive complexity 21 (threshold 15). Drivers by points: if/else 10 (15 pts), loops 4, boolean chains 2 (nesting depth added 5). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/channels/response_formatter.py"},"region":{"startLine":54}}}],"partialFingerprints":{"codehealthFindingId/v1":"1916c8d0d3bdd1e303b7e1b11a2e4beda724217fa0471eba7ac3f2af5fef106f"}},{"ruleId":"D2","level":"warning","message":{"text":"streaming.cleanup_stream (cognitive 21): streaming.cleanup_stream has cognitive complexity 21 (threshold 15). Drivers by points: if/else 9 (12 pts), error handling 3 (7 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":"backend/channels/streaming.py"},"region":{"startLine":407}}}],"partialFingerprints":{"codehealthFindingId/v1":"e9f88167450440d475c6a07c7d298b590cf9f46b1712b49dd7c33a539042f3fd"}},{"ruleId":"D2","level":"warning","message":{"text":"attention_authority._collect_community_digests (cognitive 21): attention_authority._collect_community_digests has cognitive complexity 21 (threshold 15). Drivers by points: if/else 7 (13 pts), error handling 3 (5 pts), loops 2, boolean chains 1 (nesting depth added 8). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/core/attention_authority.py"},"region":{"startLine":443}}}],"partialFingerprints":{"codehealthFindingId/v1":"d373e5a0418725010c3e8c6ac3566ac2cadbfd8089296adf53f3c58644adc3ca"}},{"ruleId":"D2","level":"warning","message":{"text":"freshness.detect_spec_details_staleness (cognitive 21): freshness.detect_spec_details_staleness has cognitive complexity 21 (threshold 15). Drivers by points: if/else 7 (11 pts), boolean chains 5, error handling 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":"backend/core/code_intel/freshness.py"},"region":{"startLine":224}}}],"partialFingerprints":{"codehealthFindingId/v1":"6b3c0b7932635aa8c804d9d73b9e49478b71b3f4b0475064db3d26d72197b6ba"}},{"ruleId":"D2","level":"warning","message":{"text":"module_map.build_module_map (cognitive 21): module_map.build_module_map has cognitive complexity 21 (threshold 15). Drivers by points: loops 5 (9 pts), if/else 3 (8 pts), error handling 2 (4 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":"backend/core/code_intel/module_map.py"},"region":{"startLine":131}}}],"partialFingerprints":{"codehealthFindingId/v1":"d34c5414c784b6a32471a2085a3fb21dcad6fbc63b4933460940c37140a43ec8"}},{"ruleId":"D2","level":"warning","message":{"text":"context_recall._truncate_at_sentence (cognitive 21): context_recall._truncate_at_sentence has cognitive complexity 21 (threshold 15). Drivers by points: if/else 9 (14 pts), loops 3 (5 pts), ternaries 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":"backend/core/context_recall.py"},"region":{"startLine":66}}}],"partialFingerprints":{"codehealthFindingId/v1":"a785e77207984eac5edc2563c45cc25ce38b54d41ec54b219d5d0491ab5dcd77"}},{"ruleId":"D2","level":"warning","message":{"text":"ddd_entry_lifecycle.classify_entry_type (cognitive 21): ddd_entry_lifecycle.classify_entry_type 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":"backend/core/ddd_entry_lifecycle.py"},"region":{"startLine":465}}}],"partialFingerprints":{"codehealthFindingId/v1":"246b2e045a1d4c64512db3d966fd0a282dd46c8a3b59019b4caae4a720abf20e"}},{"ruleId":"D2","level":"warning","message":{"text":"ddd_entry_lifecycle.archive_raw_lines (cognitive 21): ddd_entry_lifecycle.archive_raw_lines has cognitive complexity 21 (threshold 15). Drivers by points: if/else 10 (17 pts), boolean chains 2, loops 1 (2 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":"backend/core/ddd_entry_lifecycle.py"},"region":{"startLine":1070}}}],"partialFingerprints":{"codehealthFindingId/v1":"4f8500b3af71741ea47483b651bfeb8fdae77b99bb7a8204b2f69ba2a5c7c885"}},{"ruleId":"D2","level":"warning","message":{"text":"ddd_maturity.parse_maturity (cognitive 21): ddd_maturity.parse_maturity has cognitive complexity 21 (threshold 15). Drivers by points: if/else 8 (16 pts), boolean chains 4, 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":"backend/core/ddd_maturity.py"},"region":{"startLine":119}}}],"partialFingerprints":{"codehealthFindingId/v1":"cdd06f38779345735ad51afbbdced5da9c2f031704efc72cdc0e208ac32f364b"}},{"ruleId":"D2","level":"warning","message":{"text":"engine_metrics._collect_session_stats (cognitive 21): engine_metrics._collect_session_stats has cognitive complexity 21 (threshold 15). Drivers by points: if/else 6 (13 pts), error handling 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":"backend/core/engine_metrics.py"},"region":{"startLine":537}}}],"partialFingerprints":{"codehealthFindingId/v1":"9f6176158c2ad609346be7b6cfd4d77e0728c6977685319dfa00df6499d50bb3"}},{"ruleId":"D2","level":"warning","message":{"text":"EvolutionOptimizer._is_quality_correction (cognitive 21): EvolutionOptimizer._is_quality_correction has cognitive complexity 21 (threshold 15). Drivers by points: if/else 11 (16 pts), ternaries 1 (3 pts), boolean chains 2 (nesting depth added 7). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/core/evolution_optimizer.py"},"region":{"startLine":687}}}],"partialFingerprints":{"codehealthFindingId/v1":"e59dca960e681f91eb01c1bdcd0732b5b498611c57d24a5b131b039459a43009"}},{"ruleId":"D2","level":"warning","message":{"text":"LifecycleManager._proactive_rss_restart (cognitive 21): LifecycleManager._proactive_rss_restart has cognitive complexity 21 (threshold 15). Drivers by points: if/else 7 (13 pts), error handling 3 (5 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":"backend/core/lifecycle_manager.py"},"region":{"startLine":433}}}],"partialFingerprints":{"codehealthFindingId/v1":"8236f06d43bd234826a14e32e9bb102032e6c37b149c5654930a1234853418b0"}},{"ruleId":"D2","level":"warning","message":{"text":"memory_extractor._format_conversation (cognitive 21): memory_extractor._format_conversation has cognitive complexity 21 (threshold 15). Drivers by points: if/else 5 (14 pts), loops 2 (4 pts), ternaries 1 (2 pts), boolean chains 1 (nesting depth added 12). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/core/memory_extractor.py"},"region":{"startLine":95}}}],"partialFingerprints":{"codehealthFindingId/v1":"52b7c4f041e5b84ef9f5ef39d0e3289fab10eeca2fad678c0eadffd0966b5ccc"}},{"ruleId":"D2","level":"warning","message":{"text":"proactive_intelligence._extract_recent_deliverables (cognitive 21): proactive_intelligence._extract_recent_deliverables has cognitive complexity 21 (threshold 15). Drivers by points: if/else 5 (11 pts), boolean chains 5, loops 2 (3 pts), error handling 1 (2 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":"backend/core/proactive_intelligence.py"},"region":{"startLine":259}}}],"partialFingerprints":{"codehealthFindingId/v1":"5eec209ab2e667109d1a0f96db90fff11ed06ed38e677b64e91fe885bfe6f5fc"}},{"ruleId":"D2","level":"warning","message":{"text":"runtime_hooks._read_subagent_prompt_head (cognitive 21): runtime_hooks._read_subagent_prompt_head has cognitive complexity 21 (threshold 15). Drivers by points: if/else 7 (14 pts), error handling 2 (3 pts), ternaries 1 (2 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":"backend/core/runtime_hooks.py"},"region":{"startLine":943}}}],"partialFingerprints":{"codehealthFindingId/v1":"c1f8aff11e24deb4c4ce088460100c31b65bd0911026a72ee3c92ee5398b2e67"}},{"ruleId":"D2","level":"warning","message":{"text":"SessionMiner.mine_all (cognitive 21): SessionMiner.mine_all has cognitive complexity 21 (threshold 15). Drivers by points: if/else 4 (9 pts), loops 5 (9 pts), error handling 1 (2 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":"backend/core/session_miner.py"},"region":{"startLine":472}}}],"partialFingerprints":{"codehealthFindingId/v1":"60c1fe7d42870a41a0646ddbdb773ea7b87d1b7e4474aaef22ceb7a022f2b75e"}},{"ruleId":"D2","level":"warning","message":{"text":"SessionRouter.drain_pending (cognitive 21): SessionRouter.drain_pending has cognitive complexity 21 (threshold 15). Drivers by points: if/else 7 (8 pts), ternaries 2 (5 pts), boolean chains 4, error handling 2 (3 pts), loops 1 (nesting depth added 5). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/core/session_router.py"},"region":{"startLine":2678}}}],"partialFingerprints":{"codehealthFindingId/v1":"65554f260e804e9f20e86c17274be14230ca44f06b862d3e6f22494137559e9f"}},{"ruleId":"D2","level":"warning","message":{"text":"SessionUnit._spawn (cognitive 21): SessionUnit._spawn has cognitive complexity 21 (threshold 15). Drivers by points: if/else 9, boolean chains 7, ternaries 3, error handling 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":"backend/core/session_unit.py"},"region":{"startLine":3278}}}],"partialFingerprints":{"codehealthFindingId/v1":"52a6ea7564c4e79e78c43f7932035febf0c550aa6dd9be72290166753b90122e"}},{"ruleId":"D2","level":"warning","message":{"text":"skill_manager.parse_skill_md (cognitive 21): skill_manager.parse_skill_md has cognitive complexity 21 (threshold 15). Drivers by points: ternaries 11, if/else 8 (9 pts), boolean chains 1 (nesting depth added 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":"backend/core/skill_manager.py"},"region":{"startLine":215}}}],"partialFingerprints":{"codehealthFindingId/v1":"892e99fdf6fc5d00ede5f4f09b26744834a61c71380340d74d47ad593194c996"}},{"ruleId":"D2","level":"warning","message":{"text":"SummarizationPipeline._extract_open_questions (cognitive 21): SummarizationPipeline._extract_open_questions has cognitive complexity 21 (threshold 15). Drivers by points: if/else 5 (17 pts), loops 2 (3 pts), boolean chains 1 (nesting depth added 13). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/core/summarization.py"},"region":{"startLine":495}}}],"partialFingerprints":{"codehealthFindingId/v1":"3db3db1d8efd17b1b63689315aab828171124aaadcc3d9f4059ec3fef87fc27a"}},{"ruleId":"D2","level":"warning","message":{"text":"SummarizationPipeline._format_conversation_for_llm (cognitive 21): SummarizationPipeline._format_conversation_for_llm has cognitive complexity 21 (threshold 15). Drivers by points: if/else 5 (14 pts), loops 2 (4 pts), ternaries 1 (2 pts), boolean chains 1 (nesting depth added 12). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/core/summarization.py"},"region":{"startLine":683}}}],"partialFingerprints":{"codehealthFindingId/v1":"c9969b71e0cc21d97904ec316e45719d5cd587375f81cd1b68f6bf4e2607a6bc"}},{"ruleId":"D2","level":"warning","message":{"text":"UserObserver.observe_session (cognitive 21): UserObserver.observe_session has cognitive complexity 21 (threshold 15). Drivers by points: if/else 8 (15 pts), loops 4 (6 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":"backend/core/user_observer.py"},"region":{"startLine":88}}}],"partialFingerprints":{"codehealthFindingId/v1":"5b7e808dc69cdb0cc2d1456bcc6887780d5e7d39c3c967dccf82f150373f463e"}},{"ruleId":"D2","level":"warning","message":{"text":"DistillationTriggerHook._update_effectiveness_scoring (cognitive 21): DistillationTriggerHook._update_effectiveness_scoring has cognitive complexity 21 (threshold 15). Drivers by points: if/else 5 (11 pts), boolean chains 5, loops 2 (3 pts), error handling 1 (2 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":"backend/hooks/distillation_hook.py"},"region":{"startLine":371}}}],"partialFingerprints":{"codehealthFindingId/v1":"b0f5466646278fcbd35dd2a1d9beb5e859211158b37f509eaf40dae29d74ef25"}},{"ruleId":"D2","level":"warning","message":{"text":"DistillationTriggerHook._extract_decisions (cognitive 21): DistillationTriggerHook._extract_decisions has cognitive complexity 21 (threshold 15). Drivers by points: if/else 5 (12 pts), boolean chains 8, 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":"backend/hooks/distillation_hook.py"},"region":{"startLine":1126}}}],"partialFingerprints":{"codehealthFindingId/v1":"bcab76c87a29cb6389b55421f3e9585befdb036e0dc4253cd2691d32e5f2ff84"}},{"ruleId":"D2","level":"warning","message":{"text":"DistillationTriggerHook._archive_stale_rc_entries (cognitive 21): DistillationTriggerHook._archive_stale_rc_entries has cognitive complexity 21 (threshold 15). Drivers by points: if/else 9 (14 pts), error handling 3 (5 pts), boolean chains 1, 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":"backend/hooks/distillation_hook.py"},"region":{"startLine":2259}}}],"partialFingerprints":{"codehealthFindingId/v1":"e672b9619a9905840f00e2f02d0ac05fb9130b82c069a66264cbbc2904d5438b"}},{"ruleId":"D2","level":"warning","message":{"text":"github_releases.fetch_github_releases (cognitive 21): github_releases.fetch_github_releases has cognitive complexity 21 (threshold 15). Drivers by points: if/else 6 (15 pts), loops 2 (3 pts), error handling 1 (2 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":"backend/jobs/adapters/github_releases.py"},"region":{"startLine":48}}}],"partialFingerprints":{"codehealthFindingId/v1":"ab42b9c2a882207f64c5f7df49e0d51fbe69149541064bdd641d4c646582c6f4"}},{"ruleId":"D2","level":"warning","message":{"text":"self_tune.extract_projects (cognitive 21): self_tune.extract_projects has cognitive complexity 21 (threshold 15). Drivers by points: if/else 6 (18 pts), loops 1 (2 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":"backend/jobs/self_tune.py"},"region":{"startLine":61}}}],"partialFingerprints":{"codehealthFindingId/v1":"c9ef4d56d5be133365a6af129e7896ddf1dbfceab93f7e44d09b5ae6b0f9e680"}},{"ruleId":"D2","level":"warning","message":{"text":"settings._list_bedrock_inference_profiles (cognitive 21): settings._list_bedrock_inference_profiles has cognitive complexity 21 (threshold 15). Drivers by points: if/else 5 (15 pts), boolean chains 3, loops 2 (3 pts) (nesting depth added 11). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/routers/settings.py"},"region":{"startLine":153}}}],"partialFingerprints":{"codehealthFindingId/v1":"ff42605ec17663fc757facaeccab246c1768b833d75864ac5920ff2eeb126ba7"}},{"ruleId":"D2","level":"warning","message":{"text":"artifact_cli.cmd_ddd_noise (cognitive 21): artifact_cli.cmd_ddd_noise has cognitive complexity 21 (threshold 15). Drivers by points: if/else 7 (12 pts), ternaries 3 (5 pts), loops 2 (4 pts) (nesting depth added 9). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/scripts/artifact_cli.py"},"region":{"startLine":5754}}}],"partialFingerprints":{"codehealthFindingId/v1":"b4f340592aea2f654ac737bd22b5ae1f623cda6dd5e2c49a9a954b34a269f511"}},{"ruleId":"D2","level":"warning","message":{"text":"completion_gate.completion_surface_verdict (cognitive 21): completion_gate.completion_surface_verdict has cognitive complexity 21 (threshold 15). Drivers by points: if/else 9 (11 pts), boolean chains 6, loops 2 (4 pts) (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":"backend/scripts/completion_gate.py"},"region":{"startLine":59}}}],"partialFingerprints":{"codehealthFindingId/v1":"5e6d2d35d989d7e1b0e43299c35238657b724912c5097ac299a4182b0f2dd1c3"}},{"ruleId":"D2","level":"warning","message":{"text":"golden_case_validator.main (cognitive 21): golden_case_validator.main has cognitive complexity 21 (threshold 15). Drivers by points: ternaries 6 (10 pts), if/else 4 (6 pts), loops 2 (3 pts), error handling 1 (2 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":"backend/scripts/golden_case_validator.py"},"region":{"startLine":371}}}],"partialFingerprints":{"codehealthFindingId/v1":"82924a749d3fa429a1b575322d671be2aa6c8f9a7e2711efa5ec29aa1dd092fc"}},{"ruleId":"D2","level":"warning","message":{"text":"pipeline_analytics.analyze_abandon_patterns (cognitive 21): pipeline_analytics.analyze_abandon_patterns has cognitive complexity 21 (threshold 15). Drivers by points: if/else 7 (13 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":"backend/scripts/pipeline_analytics.py"},"region":{"startLine":421}}}],"partialFingerprints":{"codehealthFindingId/v1":"f00a650b848fda81a027a0fa84007461f2e5a4568bf9497c070a9c352a1397ed"}},{"ruleId":"D2","level":"warning","message":{"text":"pipeline_validator._check_understanding_gate (cognitive 21): pipeline_validator._check_understanding_gate has cognitive complexity 21 (threshold 15). Drivers by points: if/else 6 (11 pts), boolean chains 6, ternaries 2 (4 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":"backend/scripts/pipeline_validator.py"},"region":{"startLine":1052}}}],"partialFingerprints":{"codehealthFindingId/v1":"3c261a0c1fe89675ce06cfbfff9280fab386eacdbc4754d7a2df84b168cd04fa"}},{"ruleId":"D2","level":"warning","message":{"text":"scenario_runner.parse_trajectory (cognitive 21): scenario_runner.parse_trajectory has cognitive complexity 21 (threshold 15). Drivers by points: if/else 5 (11 pts), error handling 2 (6 pts), loops 2 (3 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":"backend/scripts/scenario_runner.py"},"region":{"startLine":72}}}],"partialFingerprints":{"codehealthFindingId/v1":"5d6c0f9ac139208eda16e0e0dfb06374cdc94318748476b5af770beb45487b20"}},{"ruleId":"D2","level":"warning","message":{"text":"design_system._generate_intelligent_overrides (cognitive 21): design_system._generate_intelligent_overrides has cognitive complexity 21 (threshold 15). Drivers by points: if/else 12 (19 pts), boolean chains 1, 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":"backend/skills/s_frontend-design/scripts/design_system.py"},"region":{"startLine":995}}}],"partialFingerprints":{"codehealthFindingId/v1":"09562525ced84bcc20b03516f4bc3cc3dbe1040b46980d3739d3a4770d51cc96"}},{"ruleId":"D2","level":"warning","message":{"text":"todo_db._build_linked_context (cognitive 21): todo_db._build_linked_context has cognitive complexity 21 (threshold 15). Drivers by points: boolean chains 10, if/else 10, ternaries 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":"backend/skills/s_radar-todo/scripts/todo_db.py"},"region":{"startLine":78}}}],"partialFingerprints":{"codehealthFindingId/v1":"fa342c94906b31b5bab9e11f8c5d3b021e7b2475370f3dfca0d78da58c06faa9"}},{"ruleId":"D2","level":"warning","message":{"text":"ai_ready_helpers._collect_doc_file_anchors (cognitive 21): ai_ready_helpers._collect_doc_file_anchors has cognitive complexity 21 (threshold 15). Drivers by points: if/else 4 (8 pts), loops 5 (7 pts), boolean chains 6 (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":"backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py"},"region":{"startLine":391}}}],"partialFingerprints":{"codehealthFindingId/v1":"728bcf05742033e3dd2e1277b540efcc1a80b66ef78bdaf8b79ea04ce124a9db"}},{"ruleId":"D2","level":"warning","message":{"text":"ai_ready_helpers._iter_domain_assertions (cognitive 21): ai_ready_helpers._iter_domain_assertions has cognitive complexity 21 (threshold 15). Drivers by points: loops 7 (13 pts), boolean chains 4, if/else 2 (4 pts) (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":"backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py"},"region":{"startLine":1352}}}],"partialFingerprints":{"codehealthFindingId/v1":"bed8908ec108c2e27610b65387fc8e011cdd9e1bb4ed666a1622d3e58e3f3d91"}},{"ruleId":"D2","level":"warning","message":{"text":"ai_ready_helpers._collect_doc_file_anchors (cognitive 21): ai_ready_helpers._collect_doc_file_anchors has cognitive complexity 21 (threshold 15). Drivers by points: if/else 4 (8 pts), loops 5 (7 pts), boolean chains 6 (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":"backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py"},"region":{"startLine":391}}}],"partialFingerprints":{"codehealthFindingId/v1":"18bc2e2e495348d74b7d412aa7ca4aaebc81ec10fb627af9aa9521e02cc8703c"}},{"ruleId":"D2","level":"warning","message":{"text":"ai_ready_helpers._iter_domain_assertions (cognitive 21): ai_ready_helpers._iter_domain_assertions has cognitive complexity 21 (threshold 15). Drivers by points: loops 7 (13 pts), boolean chains 4, if/else 2 (4 pts) (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":"backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py"},"region":{"startLine":1069}}}],"partialFingerprints":{"codehealthFindingId/v1":"2eea2c9628958a9f05feb72df604957e57c21b42b61ee1fd0c55892afbc292c2"}},{"ruleId":"D2","level":"warning","message":{"text":"lint_skills.lint_body (cognitive 21): lint_skills.lint_body has cognitive complexity 21 (threshold 15). Drivers by points: if/else 4 (11 pts), loops 5 (8 pts), boolean chains 1, error handling 1 (nesting depth added 10). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"scripts/lint_skills.py"},"region":{"startLine":343}}}],"partialFingerprints":{"codehealthFindingId/v1":"a4fd2ad75dcaf3792c36ea7d243d6566cf1a7ee1c249bc91d81698c6d081e01a"}},{"ruleId":"D2","level":"warning","message":{"text":"useReviewMode.useReviewMode (cognitive 21): useReviewMode.useReviewMode has cognitive complexity 21 (threshold 15). Drivers by points: ternaries 7 (10 pts), if/else 7 (8 pts), boolean chains 3 (nesting depth added 4). Most of this is not in the body itself: 0 of the 21 points are its own statements and the rest belongs to 8 function literals inside it that branch (lines 170, 83, 163, \u2026). The decisions are inside those literals, which nothing outside this body can call, review or test on its own, so splitting the enclosing body is not the move available here. To reduce it, lift the literals\u0027 work into a named function or method at the enclosing scope and have each literal call it, then reduce whichever part then reads as the largest."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/hooks/useReviewMode.ts"},"region":{"startLine":75}}}],"partialFingerprints":{"codehealthFindingId/v1":"6d72268f9194576bdb8c5e3eaaa09276189cd6babc56ddcb3c7f7e7529b3de2f"}},{"ruleId":"D2","level":"warning","message":{"text":"FileEditorCore.DiffView (cognitive 21): FileEditorCore.DiffView has cognitive complexity 21 (threshold 15). Drivers by points: boolean chains 10, ternaries 7 (8 pts), if/else 3 (nesting depth added 1). Most of this is not in the body itself: 4 of the 21 points are its own statements and the rest belongs to 3 function literals inside it that branch (lines 415, 399, 480). The decisions are inside those literals, which nothing outside this body can call, review or test on its own, so splitting the enclosing body is not the move available here. To reduce it, lift the literals\u0027 work into a named function or method at the enclosing scope and have each literal call it, then reduce whichever part then reads as the largest."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/common/FileEditorCore.tsx"},"region":{"startLine":380}}}],"partialFingerprints":{"codehealthFindingId/v1":"79697d0047ef9c8d6eb83078b3e5ad7971dda17c4bcfc52020a0b7a540c18f9a"}},{"ruleId":"D2","level":"warning","message":{"text":"useAudioPlayer.useAudioPlayer (cognitive 21): useAudioPlayer.useAudioPlayer has cognitive complexity 21 (threshold 15). Drivers by points: if/else 9, error handling 3 (6 pts), boolean chains 5, loops 1 (nesting depth added 3). Most of this is not in the body itself: 0 of the 21 points are its own statements and the rest belongs to 7 function literals inside it that branch (lines 91, 173, 43, \u2026). The decisions are inside those literals, which nothing outside this body can call, review or test on its own, so splitting the enclosing body is not the move available here. To reduce it, lift the literals\u0027 work into a named function or method at the enclosing scope and have each literal call it, then reduce whichever part then reads as the largest."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/hooks/useAudioPlayer.ts"},"region":{"startLine":31}}}],"partialFingerprints":{"codehealthFindingId/v1":"59f0691942c75fd15511b5f1245aec2ea83a33c46987f357a33e6c256434523d"}},{"ruleId":"D2","level":"warning","message":{"text":"attention_authority._collect_governance (cognitive 20): attention_authority._collect_governance has cognitive complexity 20 (threshold 15). Drivers by points: boolean chains 7, if/else 4 (7 pts), ternaries 2 (4 pts), error handling 1, 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":"backend/core/attention_authority.py"},"region":{"startLine":195}}}],"partialFingerprints":{"codehealthFindingId/v1":"6d57eeb151a56e9c9f84787084004931cd5c23fdc46d5364e64f5a5ef230eafd"}},{"ruleId":"D2","level":"warning","message":{"text":"BackupManager._restore_impl (cognitive 20): BackupManager._restore_impl has cognitive complexity 20 (threshold 15). Drivers by points: if/else 8 (11 pts), error handling 4 (5 pts), loops 2 (3 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":"backend/core/backup_manager.py"},"region":{"startLine":471}}}],"partialFingerprints":{"codehealthFindingId/v1":"5a710c746abec199c77457ac3eadc9ce2c56ccdb37bfb2b772f4ab90f5d54d8f"}},{"ruleId":"D2","level":"warning","message":{"text":"canvas_surface.is_canvas_surfaceable (cognitive 20): canvas_surface.is_canvas_surfaceable has cognitive complexity 20 (threshold 15). Drivers by points: if/else 12 (13 pts), boolean chains 4, error handling 2, ternaries 1 (nesting depth added 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":"backend/core/canvas_surface.py"},"region":{"startLine":90}}}],"partialFingerprints":{"codehealthFindingId/v1":"1cbaee292f65c028736f17523514fe1fbcacb45b575e4e7c18e4bdb3cba5014d"}},{"ruleId":"D2","level":"warning","message":{"text":"dead_code.find_dead_code (cognitive 20): dead_code.find_dead_code has cognitive complexity 20 (threshold 15). Drivers by points: if/else 5 (10 pts), error handling 2 (4 pts), loops 2 (3 pts), ternaries 1 (2 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":"backend/core/code_intel/dead_code.py"},"region":{"startLine":156}}}],"partialFingerprints":{"codehealthFindingId/v1":"11dd69b79d3f2b601490982d54eee74367a54baa54be44ebe1937396cf68ec59"}},{"ruleId":"D2","level":"warning","message":{"text":"GraphStore._migrate_schema (cognitive 20): GraphStore._migrate_schema has cognitive complexity 20 (threshold 15). Drivers by points: if/else 5 (7 pts), error handling 3 (5 pts), boolean chains 4, loops 1 (3 pts), ternaries 1 (nesting depth added 6). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/core/code_intel/graph_store.py"},"region":{"startLine":322}}}],"partialFingerprints":{"codehealthFindingId/v1":"41f043e8dd570da6c122e1b8c9e8a691e886d92c77a09a1140ee6590ca8e2546"}},{"ruleId":"D2","level":"warning","message":{"text":"GraphStore.store_file_nodes_edges (cognitive 20): GraphStore.store_file_nodes_edges has cognitive complexity 20 (threshold 15). Drivers by points: if/else 5 (7 pts), loops 5 (6 pts), ternaries 3 (6 pts), error handling 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":"backend/core/code_intel/graph_store.py"},"region":{"startLine":595}}}],"partialFingerprints":{"codehealthFindingId/v1":"1aa0634fa9ed0696bc75c9c4cc153180620a5d14ce98cae761c633d56cb1a732"}},{"ruleId":"D2","level":"warning","message":{"text":"ddd_cultivation.apply_retire_proposal (cognitive 20): ddd_cultivation.apply_retire_proposal has cognitive complexity 20 (threshold 15). Drivers by points: if/else 9 (13 pts), error handling 3 (4 pts), boolean chains 3 (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":"backend/core/ddd_cultivation.py"},"region":{"startLine":1678}}}],"partialFingerprints":{"codehealthFindingId/v1":"c48557d7b708c8c42f1537355cdc08d68cb2797fe822b95c9dad66f3d566548e"}},{"ruleId":"D2","level":"warning","message":{"text":"ddd_cultivation.write_proposal (cognitive 20): ddd_cultivation.write_proposal has cognitive complexity 20 (threshold 15). Drivers by points: if/else 4 (9 pts), error handling 3 (6 pts), boolean chains 2, loops 1 (2 pts), ternaries 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":"backend/core/ddd_cultivation.py"},"region":{"startLine":2307}}}],"partialFingerprints":{"codehealthFindingId/v1":"9ca2e6f2a19f27e6cca6bcfde9373ec476f2be3ae36cfc7f31f478e6b13355f5"}},{"ruleId":"D2","level":"warning","message":{"text":"ddd_entry_lifecycle.reclaim_duplicate_entries (cognitive 20): ddd_entry_lifecycle.reclaim_duplicate_entries has cognitive complexity 20 (threshold 15). Drivers by points: if/else 10 (15 pts), loops 3, boolean chains 2 (nesting depth added 5). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/core/ddd_entry_lifecycle.py"},"region":{"startLine":1509}}}],"partialFingerprints":{"codehealthFindingId/v1":"862e300c7d0ea290c1cb21ea415da02e02fe51a9ab92632b898a45ea04fd81df"}},{"ruleId":"D2","level":"warning","message":{"text":"ddd_skill_registry.build_manifest (cognitive 20): ddd_skill_registry.build_manifest has cognitive complexity 20 (threshold 15). Drivers by points: if/else 5 (10 pts), loops 3 (6 pts), error handling 2 (3 pts), boolean chains 1 (nesting depth added 9). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/core/ddd_skill_registry.py"},"region":{"startLine":177}}}],"partialFingerprints":{"codehealthFindingId/v1":"d58ca1f771774bf62f3e5cfd039b78a8a8610191cfb3d05a921dabe0e33317bc"}},{"ruleId":"D2","level":"warning","message":{"text":"engine_metrics.collect_memory_effectiveness (cognitive 20): engine_metrics.collect_memory_effectiveness has cognitive complexity 20 (threshold 15). Drivers by points: if/else 8 (16 pts), boolean chains 2, error handling 1, 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":"backend/core/engine_metrics.py"},"region":{"startLine":42}}}],"partialFingerprints":{"codehealthFindingId/v1":"b9b13e1c60ab125d1c9ea96914a68ef649747838dc6405c8eac2d1c769954eea"}},{"ruleId":"D2","level":"warning","message":{"text":"EvalService.decide_governance (cognitive 20): EvalService.decide_governance has cognitive complexity 20 (threshold 15). Drivers by points: if/else 9 (15 pts), error handling 1 (4 pts), ternaries 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":"backend/core/eval_service.py"},"region":{"startLine":1669}}}],"partialFingerprints":{"codehealthFindingId/v1":"8227ee7e162767b5e7b285e696adc78eb60ee2369c997fccc97f64ced5cb8ba8"}},{"ruleId":"D2","level":"warning","message":{"text":"closed_loop.audit_recurrence (cognitive 20): closed_loop.audit_recurrence has cognitive complexity 20 (threshold 15). Drivers by points: boolean chains 11, if/else 7 (8 pts), loops 1 (nesting depth added 1). To reduce it, name the conditions: bind each compound test to a well-named local or a small predicate function, so the body reads as a sequence of named decisions rather than a chain of operators."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/core/evolution/closed_loop.py"},"region":{"startLine":37}}}],"partialFingerprints":{"codehealthFindingId/v1":"43c6d6cd7612ed137399c9646195767d030d878fcd70345926ed6ef4e0cc03db"}},{"ruleId":"D2","level":"warning","message":{"text":"governance_router.classify_new_corrections (cognitive 20): governance_router.classify_new_corrections has cognitive complexity 20 (threshold 15). Drivers by points: if/else 8 (12 pts), error handling 3 (4 pts), boolean chains 2, 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":"backend/core/evolution/governance_router.py"},"region":{"startLine":167}}}],"partialFingerprints":{"codehealthFindingId/v1":"e5eaa81cdad6a30eeab46e179bc30e852f2ef7e7481bdc84d4d9650fcda91bda"}},{"ruleId":"D2","level":"warning","message":{"text":"LifecycleManager._streaming_rss_check (cognitive 20): LifecycleManager._streaming_rss_check has cognitive complexity 20 (threshold 15). Drivers by points: if/else 8 (15 pts), boolean chains 2, loops 2, error handling 1 (nesting depth added 7). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/core/lifecycle_manager.py"},"region":{"startLine":529}}}],"partialFingerprints":{"codehealthFindingId/v1":"34070852bd76067c1897b9ef84ff8aabe2fbc67302135f047bf6f981c22260ee"}},{"ruleId":"D2","level":"warning","message":{"text":"LifecycleManager._scan_unprocessed_sessions (cognitive 20): LifecycleManager._scan_unprocessed_sessions has cognitive complexity 20 (threshold 15). Drivers by points: if/else 8 (13 pts), boolean chains 4, error handling 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":"backend/core/lifecycle_manager.py"},"region":{"startLine":1642}}}],"partialFingerprints":{"codehealthFindingId/v1":"1bebf0264ff94bad3af4add272df8112ff35e5eddc7d37053b3eb67139b96d07"}},{"ruleId":"D2","level":"warning","message":{"text":"MemoryGuard.scan (cognitive 20): MemoryGuard.scan has cognitive complexity 20 (threshold 15). Drivers by points: loops 9 (14 pts), ternaries 1 (3 pts), if/else 2, boolean chains 1 (nesting depth added 7). To reduce it, break up the iteration: give each loop body a named function, and split a multi-phase loop into one function per phase so no single body carries the whole pipeline."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/core/memory_guard.py"},"region":{"startLine":109}}}],"partialFingerprints":{"codehealthFindingId/v1":"b2c54aadb35d08a2c3d7119dc2428af5883b0c024f5787cc6627e5c250e72343"}},{"ruleId":"D2","level":"warning","message":{"text":"SessionUnit._force_kill (cognitive 20): SessionUnit._force_kill has cognitive complexity 20 (threshold 15). Drivers by points: error handling 6 (14 pts), if/else 5 (6 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":"backend/core/session_unit.py"},"region":{"startLine":4378}}}],"partialFingerprints":{"codehealthFindingId/v1":"061f4fd22a73d1733b9fa04780588059ee49d884efdf0652220474f8005c52b8"}},{"ruleId":"D2","level":"warning","message":{"text":"bedrock.converse_with_retry (cognitive 20): bedrock.converse_with_retry has cognitive complexity 20 (threshold 15). Drivers by points: if/else 3 (8 pts), error handling 2 (5 pts), loops 2 (3 pts), boolean chains 2, 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":"backend/jobs/bedrock.py"},"region":{"startLine":384}}}],"partialFingerprints":{"codehealthFindingId/v1":"80b6a04406c2e5cdd5ae1c6d7648c73156471260cfa0027da0990c524242dd41"}},{"ruleId":"D2","level":"warning","message":{"text":"executor._handle_maintenance (cognitive 20): executor._handle_maintenance has cognitive complexity 20 (threshold 15). Drivers by points: if/else 12 (16 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."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/jobs/executor.py"},"region":{"startLine":1075}}}],"partialFingerprints":{"codehealthFindingId/v1":"8d48e834339bce8c1cca9044a9b508e421af961c3665e8c29fd7cda25ad69add"}},{"ruleId":"D2","level":"warning","message":{"text":"session_quality.run_session_quality (cognitive 20): session_quality.run_session_quality has cognitive complexity 20 (threshold 15). Drivers by points: if/else 8 (15 pts), boolean chains 2, ternaries 2, 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":"backend/jobs/handlers/session_quality.py"},"region":{"startLine":88}}}],"partialFingerprints":{"codehealthFindingId/v1":"03e1095ebaedc1cfff5a1839b6d98bb1e557628e7cfb5323acbd5be87e2217ee"}},{"ruleId":"D2","level":"warning","message":{"text":"chat._merge_consecutive_assistant_messages (cognitive 20): chat._merge_consecutive_assistant_messages has cognitive complexity 20 (threshold 15). Drivers by points: if/else 7 (16 pts), boolean chains 3, 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":"backend/routers/chat.py"},"region":{"startLine":1078}}}],"partialFingerprints":{"codehealthFindingId/v1":"bf04fbe5218a98a101c30441073a27db20beb59f54ad73a96a338c62788844e4"}},{"ruleId":"D2","level":"warning","message":{"text":"ddd_brain._section_members (cognitive 20): ddd_brain._section_members has cognitive complexity 20 (threshold 15). Drivers by points: if/else 7 (10 pts), ternaries 3 (6 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":"backend/routers/ddd_brain.py"},"region":{"startLine":480}}}],"partialFingerprints":{"codehealthFindingId/v1":"5e6c07c520288eb23f46b9b14e5f670f87fd33e248de2e5eb2a5a7a6a513b553"}},{"ruleId":"D2","level":"warning","message":{"text":"workspace_api._get_git_status (cognitive 20): workspace_api._get_git_status has cognitive complexity 20 (threshold 15). Drivers by points: if/else 7 (12 pts), boolean chains 6, error handling 1, 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":"backend/routers/workspace_api.py"},"region":{"startLine":261}}}],"partialFingerprints":{"codehealthFindingId/v1":"544ea440ee184e2bac05b5259cf0769def28f0463f3568f802b1ffb7f0c759f7"}},{"ruleId":"D2","level":"warning","message":{"text":"artifact_cli.cleanup_orphans (cognitive 20): artifact_cli.cleanup_orphans has cognitive complexity 20 (threshold 15). Drivers by points: if/else 6 (14 pts), error handling 1 (3 pts), loops 2 (3 pts) (nesting depth added 11). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/scripts/artifact_cli.py"},"region":{"startLine":1324}}}],"partialFingerprints":{"codehealthFindingId/v1":"a8a1d752f53b6b00012b8e4568588236d4113c893b62bbfb0908b955eeadc7b1"}},{"ruleId":"D2","level":"warning","message":{"text":"artifact_cli.cmd_run_get (cognitive 20): artifact_cli.cmd_run_get has cognitive complexity 20 (threshold 15). Drivers by points: if/else 5 (9 pts), error handling 2 (7 pts), loops 2 (4 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":"backend/scripts/artifact_cli.py"},"region":{"startLine":3420}}}],"partialFingerprints":{"codehealthFindingId/v1":"1b0418dcaf8cc6ad2c9223744defed76cf1b4309b142a2bc3e61a7d195589e68"}},{"ruleId":"D2","level":"warning","message":{"text":"check_migration_class.validate_enumeration_cmd (cognitive 20): check_migration_class.validate_enumeration_cmd has cognitive complexity 20 (threshold 15). Drivers by points: if/else 11 (15 pts), ternaries 1 (3 pts), boolean chains 1, loops 1 (nesting depth added 6). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/scripts/check_migration_class.py"},"region":{"startLine":78}}}],"partialFingerprints":{"codehealthFindingId/v1":"a7a2e101bab1e59b4252ea34a6e1998e40faa30a5289da91f10d885d4cf726dc"}},{"ruleId":"D2","level":"warning","message":{"text":"eval_runner.eval_trajectory_capture (cognitive 20): eval_runner.eval_trajectory_capture has cognitive complexity 20 (threshold 15). Drivers by points: if/else 7 (9 pts), boolean chains 6, error handling 3 (4 pts), 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."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/scripts/eval_runner.py"},"region":{"startLine":1388}}}],"partialFingerprints":{"codehealthFindingId/v1":"d0940f5fc3943bd4d4957eb280b4d7ac84de37e1c21d2b3de3d63a604fad20ae"}},{"ruleId":"D2","level":"warning","message":{"text":"judge_telemetry_report.render (cognitive 20): judge_telemetry_report.render has cognitive complexity 20 (threshold 15). Drivers by points: if/else 10 (12 pts), loops 3 (5 pts), boolean chains 2, ternaries 1 (nesting depth added 4). To reduce it, split the body: most of this score is breadth rather than depth \u2014 checks laid out side by side rather than stacked \u2014 so group the statements between the checks into named steps and move each step into its own function. Some of it IS depth: where a check sits inside another whose only job is to reach it, merge the two into one condition, 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":"backend/scripts/judge_telemetry_report.py"},"region":{"startLine":101}}}],"partialFingerprints":{"codehealthFindingId/v1":"bf62cf2e181d71fa7137bd5284bca463750298320f532bc408d32e564da38157"}},{"ruleId":"D2","level":"warning","message":{"text":"pipeline_analytics._is_replaced_duplicate (cognitive 20): pipeline_analytics._is_replaced_duplicate has cognitive complexity 20 (threshold 15). Drivers by points: if/else 8 (14 pts), boolean chains 5, loops 1 (nesting depth added 6). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/scripts/pipeline_analytics.py"},"region":{"startLine":296}}}],"partialFingerprints":{"codehealthFindingId/v1":"877bf2483a8e28a2054d74c81a881b331c3c9c2aa4b64f31eb43cbfea1bde18d"}},{"ruleId":"D2","level":"warning","message":{"text":"pipeline_analytics.analyze_estimation_accuracy (cognitive 20): pipeline_analytics.analyze_estimation_accuracy has cognitive complexity 20 (threshold 15). Drivers by points: loops 7 (8 pts), if/else 4 (7 pts), boolean chains 3, ternaries 1 (2 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":"backend/scripts/pipeline_analytics.py"},"region":{"startLine":629}}}],"partialFingerprints":{"codehealthFindingId/v1":"736b0c3a7905573ce166dc7316fd4cdb5ab4a0590f54bfb7a721556954478c46"}},{"ruleId":"D2","level":"warning","message":{"text":"pipeline_validator.check_ddd_staleness (cognitive 20): pipeline_validator.check_ddd_staleness has cognitive complexity 20 (threshold 15). Drivers by points: if/else 7 (13 pts), loops 2 (3 pts), boolean chains 2, error handling 1 (2 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":"backend/scripts/pipeline_validator.py"},"region":{"startLine":1895}}}],"partialFingerprints":{"codehealthFindingId/v1":"d80981d92b3c1a2e39bb5fca84deb452430366d108e3bafa5bca71002908cf9d"}},{"ruleId":"D2","level":"warning","message":{"text":"scan._load_routing (cognitive 20): scan._load_routing has cognitive complexity 20 (threshold 15). Drivers by points: if/else 4 (7 pts), loops 4 (6 pts), ternaries 2 (6 pts), error handling 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":"backend/skills/s_context-hygiene/scripts/scan.py"},"region":{"startLine":69}}}],"partialFingerprints":{"codehealthFindingId/v1":"6473f800848c45ec2b1bae61eaf78b487cef8c93291ddf49aa21306590d51b14"}},{"ruleId":"D2","level":"warning","message":{"text":"DOCXSchemaValidator.validate_deletions (cognitive 20): DOCXSchemaValidator.validate_deletions has cognitive complexity 20 (threshold 15). Drivers by points: if/else 5 (9 pts), loops 3 (5 pts), ternaries 1 (4 pts), error handling 1 (2 pts) (nesting depth added 10). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/skills/s_docx/ooxml/scripts/validation/docx.py"},"region":{"startLine":124}}}],"partialFingerprints":{"codehealthFindingId/v1":"2786cc00bacaecc1661ded4faac5cae7877fd007e2a850e373565fe3640eb5b1"}},{"ruleId":"D2","level":"warning","message":{"text":"DocxXMLEditor._inject_attributes_to_nodes (cognitive 20): DocxXMLEditor._inject_attributes_to_nodes has cognitive complexity 20 (threshold 15). Drivers by points: loops 8 (16 pts), if/else 2 (4 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":"backend/skills/s_docx/scripts/document.py"},"region":{"startLine":116}}}],"partialFingerprints":{"codehealthFindingId/v1":"05f30a59a92a9d43eaec53be9eff8e3ec9b2569a86f4ef184c5152ef035a7c82"}},{"ruleId":"D2","level":"warning","message":{"text":"SelfLoopsHealthEngine._check_knowledge (cognitive 20): SelfLoopsHealthEngine._check_knowledge has cognitive complexity 20 (threshold 15). Drivers by points: ternaries 7, if/else 4 (6 pts), boolean chains 3, error handling 1 (2 pts), loops 1 (2 pts) (nesting depth added 4). 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":"backend/skills/s_loops-health/scripts/loops_health_check.py"},"region":{"startLine":378}}}],"partialFingerprints":{"codehealthFindingId/v1":"d8edb850dcd05590359003e10585c2a23b35ada57d2dee7a167f002087631f87"}},{"ruleId":"D2","level":"warning","message":{"text":"SelfLoopsHealthEngine._fix_ot_resolved (cognitive 20): SelfLoopsHealthEngine._fix_ot_resolved has cognitive complexity 20 (threshold 15). Drivers by points: if/else 11 (16 pts), error handling 2 (3 pts), loops 1 (nesting depth added 6). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/skills/s_loops-health/scripts/loops_health_check.py"},"region":{"startLine":825}}}],"partialFingerprints":{"codehealthFindingId/v1":"6388f9929fae643a75510dd6108da94f3112ddbd87f4e22a56567eb4019f3998"}},{"ruleId":"D2","level":"warning","message":{"text":"DOCXSchemaValidator.validate_deletions (cognitive 20): DOCXSchemaValidator.validate_deletions has cognitive complexity 20 (threshold 15). Drivers by points: if/else 5 (9 pts), loops 3 (5 pts), ternaries 1 (4 pts), error handling 1 (2 pts) (nesting depth added 10). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/skills/s_pptx/ooxml/scripts/validation/docx.py"},"region":{"startLine":124}}}],"partialFingerprints":{"codehealthFindingId/v1":"20c11c6b5286d478dee2be7d1a7cd499bc6f8812c8ddd833eb215a62cb69f5bc"}},{"ruleId":"D2","level":"warning","message":{"text":"ai_ready_helpers.check_anchor_accounting (cognitive 20): ai_ready_helpers.check_anchor_accounting has cognitive complexity 20 (threshold 15). Drivers by points: if/else 7 (11 pts), boolean chains 5, loops 3, error handling 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":"backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py"},"region":{"startLine":773}}}],"partialFingerprints":{"codehealthFindingId/v1":"cc5c2024a7224023ed8b50e80a8b172cb2a64322b5ddaf1b55100a8cb78af99d"}},{"ruleId":"D2","level":"warning","message":{"text":"ai_ready_helpers.eval_spec_details (cognitive 20): ai_ready_helpers.eval_spec_details has cognitive complexity 20 (threshold 15). Drivers by points: boolean chains 7, if/else 4 (6 pts), ternaries 4, loops 2 (3 pts) (nesting depth added 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":"backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py"},"region":{"startLine":1374}}}],"partialFingerprints":{"codehealthFindingId/v1":"e6d8bf2da8a97b8a925485e6d9538a94b96e52c7877fa268d6fd86244202501b"}},{"ruleId":"D2","level":"warning","message":{"text":"ai_ready_helpers.check_anchor_accounting (cognitive 20): ai_ready_helpers.check_anchor_accounting has cognitive complexity 20 (threshold 15). Drivers by points: if/else 7 (11 pts), boolean chains 5, loops 3, error handling 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":"backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py"},"region":{"startLine":687}}}],"partialFingerprints":{"codehealthFindingId/v1":"6d3c906d80fa61a7c28987b1c6b971d0e2d08a88d98fde4f00b7fd444d7fa181"}},{"ruleId":"D2","level":"warning","message":{"text":"ai_ready_helpers.eval_spec_details (cognitive 20): ai_ready_helpers.eval_spec_details has cognitive complexity 20 (threshold 15). Drivers by points: boolean chains 7, if/else 4 (6 pts), ternaries 4, loops 2 (3 pts) (nesting depth added 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":"backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py"},"region":{"startLine":1091}}}],"partialFingerprints":{"codehealthFindingId/v1":"600b8f045ccc01c4cfe0a3110dc0a48c62eeeeb0e511020a2e70495edbe396d2"}},{"ruleId":"D2","level":"warning","message":{"text":"lint_doc_frontmatter.check_file (cognitive 20): lint_doc_frontmatter.check_file has cognitive complexity 20 (threshold 15). Drivers by points: if/else 9 (15 pts), boolean chains 3, loops 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":"scripts/lint_doc_frontmatter.py"},"region":{"startLine":47}}}],"partialFingerprints":{"codehealthFindingId/v1":"fb56d3855a99c3c4a92833b2a6d12d4f5293e6a6d4b09ab0ec59f2eb834c8de5"}},{"ruleId":"D2","level":"warning","message":{"text":"DeckStage._onKey (cognitive 20): DeckStage._onKey has cognitive complexity 20 (threshold 15). Drivers by points: if/else 11 (12 pts), boolean chains 6, ternaries 1 (2 pts) (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":"backend/skills/s_pollinate/templates/html-deck/shared/deck-stage.js"},"region":{"startLine":559}}}],"partialFingerprints":{"codehealthFindingId/v1":"45b47d6426e14f03c6a5e4ae26f3fa76f81de274a62b933e1ade80d1c7475d2b"}},{"ruleId":"D2","level":"warning","message":{"text":"hiveComponents.InstanceCard (cognitive 20): hiveComponents.InstanceCard has cognitive complexity 20 (threshold 15). Drivers by points: boolean chains 16, ternaries 2 (3 pts), error handling 1 (nesting depth added 1). Of this number, 18 points are the body\u0027s own statements and 2 belong to 3 function literals inside it that branch. To reduce it, name the conditions: bind each compound test to a well-named local or a small predicate function, so the body reads as a sequence of named decisions rather than a chain of operators."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/settings/hiveComponents.tsx"},"region":{"startLine":114}}}],"partialFingerprints":{"codehealthFindingId/v1":"983e06baac54fff20b702320b9ce7875a3de338f47f35a14a864a4f1f6b0038c"}},{"ruleId":"D2","level":"warning","message":{"text":"TerminalTab.TerminalTab (cognitive 20): TerminalTab.TerminalTab has cognitive complexity 20 (threshold 15). Drivers by points: if/else 9 (10 pts), boolean chains 5, error handling 3 (5 pts) (nesting depth added 3). Most of this is not in the body itself: 0 of the 20 points are its own statements and the rest belongs to 6 function literals inside it that branch (lines 233, 154, 107, \u2026). The decisions are inside those literals, which nothing outside this body can call, review or test on its own, so splitting the enclosing body is not the move available here. To reduce it, lift the literals\u0027 work into a named function or method at the enclosing scope and have each literal call it, then reduce whichever part then reads as the largest."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/terminal/TerminalTab.tsx"},"region":{"startLine":61}}}],"partialFingerprints":{"codehealthFindingId/v1":"c1bb31e9770a5a70a0095224ab28cf8ab8cdcbaf4eeaac81a3a62625ddfa738f"}},{"ruleId":"D2","level":"warning","message":{"text":"useReferencedFiles.useReferencedFiles (cognitive 20): useReferencedFiles.useReferencedFiles has cognitive complexity 20 (threshold 15). Drivers by points: if/else 13 (17 pts), boolean chains 2, loops 1 (nesting depth added 4). Most of this is not in the body itself: 0 of the 20 points are its own statements and the rest belongs to 6 function literals inside it that branch (lines 286, 276, 283, \u2026). The decisions are inside those literals, which nothing outside this body can call, review or test on its own, so splitting the enclosing body is not the move available here. To reduce it, lift the literals\u0027 work into a named function or method at the enclosing scope and have each literal call it, then reduce whichever part then reads as the largest."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/hooks/useReferencedFiles.ts"},"region":{"startLine":263}}}],"partialFingerprints":{"codehealthFindingId/v1":"9d6c01fa45d72939c5916608b7ef031bd10451132f0b24973428330e971913b4"}},{"ruleId":"D2","level":"warning","message":{"text":"AttachmentPreviewCard.AttachmentPreviewCard (cognitive 20): AttachmentPreviewCard.AttachmentPreviewCard has cognitive complexity 20 (threshold 15). Drivers by points: ternaries 6 (16 pts), boolean chains 4 (nesting depth added 10). To reduce it, flatten the nesting: this score is depth rather than breadth \u2014 most of its points come from checks stacked inside one another, so the work sits several levels in. Invert each enclosing check into an early exit (a return, or the language\u0027s equivalent) so the happy path stays at one level, and where a level cannot be exited early, lift the block it encloses into its own named function."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/chat/AttachmentPreviewCard.tsx"},"region":{"startLine":36}}}],"partialFingerprints":{"codehealthFindingId/v1":"b40e73378b0319d4b926ba3be07d559d08e54279d18a5f10aa39ac873c06c051"}},{"ruleId":"D2","level":"warning","message":{"text":"AttachedFileChips.AttachedFileChips (cognitive 20): AttachedFileChips.AttachedFileChips has cognitive complexity 20 (threshold 15). Drivers by points: if/else 9 (14 pts), boolean chains 4, match/switch 1, ternaries 1 (nesting depth added 5). Most of this is not in the body itself: 2 of the 20 points are its own statements and the rest belongs to 6 function literals inside it that branch (lines 184, 197, 220, \u2026). The decisions are inside those literals, which nothing outside this body can call, review or test on its own, so splitting the enclosing body is not the move available here. To reduce it, lift the literals\u0027 work into a named function or method at the enclosing scope and have each literal call it, then reduce whichever part then reads as the largest."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/chat/AttachedFileChips.tsx"},"region":{"startLine":174}}}],"partialFingerprints":{"codehealthFindingId/v1":"6d2ff0dc793b00dc779107661350904190ba28c8cd5363a9e81308a754e1b44b"}},{"ruleId":"D2","level":"warning","message":{"text":"(anonymous)::_onKey (cognitive 20): (anonymous)::_onKey has cognitive complexity 20 (threshold 15). Drivers by points: if/else 11 (12 pts), boolean chains 6, ternaries 1 (2 pts) (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":"backend/skills/s_pollinate/templates/html-deck/shared/deck-stage.js"},"region":{"startLine":559}}}],"partialFingerprints":{"codehealthFindingId/v1":"08d8d6e96026dce9fdbf6351b59151e3719c84e6c43010f2b861da74ec43d595"}},{"ruleId":"D2","level":"warning","message":{"text":"claude_environment._configure_claude_environment (cognitive 19): claude_environment._configure_claude_environment has cognitive complexity 19 (threshold 15). Drivers by points: if/else 9 (12 pts), boolean chains 7 (nesting depth added 3). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/core/claude_environment.py"},"region":{"startLine":184}}}],"partialFingerprints":{"codehealthFindingId/v1":"e0f999d6516e07abbe59fa4c8b37030ff67e7e242a20e02d46a73ebebbdfd702"}},{"ruleId":"D2","level":"warning","message":{"text":"GraphStore.resolve_bare_targets (cognitive 19): GraphStore.resolve_bare_targets has cognitive complexity 19 (threshold 15). Drivers by points: if/else 5 (11 pts), ternaries 2 (4 pts), loops 3, 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":"backend/core/code_intel/graph_store.py"},"region":{"startLine":1547}}}],"partialFingerprints":{"codehealthFindingId/v1":"3dc6dd4c1ca6be94f12eee6f07b121c7915942a05dd33b6755bf8abf40f11894"}},{"ruleId":"D2","level":"warning","message":{"text":"parser.parse_file_with_status (cognitive 19): parser.parse_file_with_status has cognitive complexity 19 (threshold 15). Drivers by points: if/else 5 (10 pts), boolean chains 3, error handling 2 (3 pts), loops 1 (2 pts), ternaries 1 (nesting depth added 7). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/core/code_intel/parser.py"},"region":{"startLine":1848}}}],"partialFingerprints":{"codehealthFindingId/v1":"0c9b87e639e04bd7918de3a33d02704b4cb69ccb829d4381ff508ce8a53f8b53"}},{"ruleId":"D2","level":"warning","message":{"text":"context_recall.recall_context (cognitive 19): context_recall.recall_context has cognitive complexity 19 (threshold 15). Drivers by points: if/else 8 (13 pts), ternaries 3, boolean chains 1, error handling 1, 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":"backend/core/context_recall.py"},"region":{"startLine":258}}}],"partialFingerprints":{"codehealthFindingId/v1":"d4824d3c7949354ecf516a83b6ae9b4bbc5d0ba0a35f5cac508615fb874f23ba"}},{"ruleId":"D2","level":"warning","message":{"text":"evolution_optimizer._write_cycle_changelog (cognitive 19): evolution_optimizer._write_cycle_changelog has cognitive complexity 19 (threshold 15). Drivers by points: if/else 6 (9 pts), ternaries 2 (4 pts), error handling 3, loops 1 (2 pts), boolean chains 1 (nesting depth added 6). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/core/evolution_optimizer.py"},"region":{"startLine":1792}}}],"partialFingerprints":{"codehealthFindingId/v1":"20f898f7f903d8ea4cd2bb7f594f9c86745d1683388f617dee1c9566f760ead2"}},{"ruleId":"D2","level":"warning","message":{"text":"LifecycleManager._process_cultivation_events (cognitive 19): LifecycleManager._process_cultivation_events has cognitive complexity 19 (threshold 15). Drivers by points: if/else 7 (11 pts), loops 3 (5 pts), error handling 2, 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":"backend/core/lifecycle_manager.py"},"region":{"startLine":1378}}}],"partialFingerprints":{"codehealthFindingId/v1":"af88c0af7e44a64d92b2b9398b1ca177864332767b8080e1c16170b7a50a6c80"}},{"ruleId":"D2","level":"warning","message":{"text":"needs_human_review._worktree_roots (cognitive 19): needs_human_review._worktree_roots has cognitive complexity 19 (threshold 15). Drivers by points: if/else 5 (11 pts), error handling 2 (5 pts), 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":"backend/core/needs_human_review.py"},"region":{"startLine":137}}}],"partialFingerprints":{"codehealthFindingId/v1":"8b4cbe51e87bc4026fd50d050df3e4aeb8ef3f50eb2bac6988b2d001c407375b"}},{"ruleId":"D2","level":"warning","message":{"text":"proactive_intelligence._newest_completed_run (cognitive 19): proactive_intelligence._newest_completed_run has cognitive complexity 19 (threshold 15). Drivers by points: if/else 6 (11 pts), error handling 3 (6 pts), boolean chains 1, 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":"backend/core/proactive_intelligence.py"},"region":{"startLine":759}}}],"partialFingerprints":{"codehealthFindingId/v1":"b7eb0586072e42a172e70602614f1d66b8b1341df9845bebb5473c7d0d913ab4"}},{"ruleId":"D2","level":"warning","message":{"text":"security_hooks._segment_is_history_rewrite (cognitive 19): security_hooks._segment_is_history_rewrite has cognitive complexity 19 (threshold 15). Drivers by points: if/else 11 (13 pts), boolean chains 4, loops 2 (nesting depth added 2). To reduce it, split the body: most of this score is breadth rather than depth \u2014 checks laid out side by side rather than stacked \u2014 so group the statements between the checks into named steps and move each step into its own function. Some of it IS depth: where a check sits inside another whose only job is to reach it, merge the two into one condition, and where an else follows a branch that already returns, drop the trailing else and let the rest of the body continue at one level."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/core/security_hooks.py"},"region":{"startLine":669}}}],"partialFingerprints":{"codehealthFindingId/v1":"64a92a6c65b595b249f9c7c6d53cdf349b3f7fb752c9c1df228a1c66ad6639e8"}},{"ruleId":"D2","level":"warning","message":{"text":"session_harvest._parse_draft (cognitive 19): session_harvest._parse_draft has cognitive complexity 19 (threshold 15). Drivers by points: if/else 6 (8 pts), boolean chains 6, error handling 2 (3 pts), ternaries 1 (2 pts) (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":"backend/core/session_harvest.py"},"region":{"startLine":104}}}],"partialFingerprints":{"codehealthFindingId/v1":"a2cc6b83fdcba359764570d9354001386c33c8c35294af307777113fb645c7cb"}},{"ruleId":"D2","level":"warning","message":{"text":"session_healing.build_rich_checkpoint (cognitive 19): session_healing.build_rich_checkpoint has cognitive complexity 19 (threshold 15). Drivers by points: if/else 7 (11 pts), boolean chains 5, error handling 1 (2 pts), 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":"backend/core/session_healing.py"},"region":{"startLine":937}}}],"partialFingerprints":{"codehealthFindingId/v1":"208f9fff12ba21220527b9de7f2cc91d2242aa4774ee57d8c4aeb87f0748312c"}},{"ruleId":"D2","level":"warning","message":{"text":"SessionUnit._ensure_spawned (cognitive 19): SessionUnit._ensure_spawned has cognitive complexity 19 (threshold 15). Drivers by points: if/else 8 (10 pts), error handling 3 (5 pts), boolean chains 2, loops 1 (2 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, 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":"backend/core/session_unit.py"},"region":{"startLine":2622}}}],"partialFingerprints":{"codehealthFindingId/v1":"104acf7fd7640e10266e118b7c75bba3fcc995b73a52b0a539de5d9aa9873e29"}},{"ruleId":"D2","level":"warning","message":{"text":"session_utils.read_owner_pid (cognitive 19): session_utils.read_owner_pid has cognitive complexity 19 (threshold 15). Drivers by points: if/else 6 (12 pts), error handling 2 (4 pts), loops 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":"backend/core/session_utils.py"},"region":{"startLine":587}}}],"partialFingerprints":{"codehealthFindingId/v1":"d089eb32960ccfd25271f4a1d600143d7dba81a665ece739b43ff0c00056c7f6"}},{"ruleId":"D2","level":"warning","message":{"text":"SkillManager._scan_ddd_tier (cognitive 19): SkillManager._scan_ddd_tier has cognitive complexity 19 (threshold 15). Drivers by points: if/else 5 (9 pts), error handling 4 (7 pts), loops 2, boolean chains 1 (nesting depth added 7). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/core/skill_manager.py"},"region":{"startLine":512}}}],"partialFingerprints":{"codehealthFindingId/v1":"a16f4333c657fc8fa53713f49947912f6820e4d87a8f735478eefb540a0025c3"}},{"ruleId":"D2","level":"warning","message":{"text":"transcript_indexer.chunk_transcript (cognitive 19): transcript_indexer.chunk_transcript has cognitive complexity 19 (threshold 15). Drivers by points: if/else 5 (12 pts), loops 2 (4 pts), boolean chains 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":"backend/core/transcript_indexer.py"},"region":{"startLine":126}}}],"partialFingerprints":{"codehealthFindingId/v1":"0878cb51d1b46db20578678c0ab1499dc2f1f2820a9bb31951c8571accb03503"}},{"ruleId":"D2","level":"warning","message":{"text":"ContextHealthHook._expire_stale_proposals (cognitive 19): ContextHealthHook._expire_stale_proposals has cognitive complexity 19 (threshold 15). Drivers by points: if/else 5 (10 pts), boolean chains 3, error handling 1 (3 pts), 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":"backend/hooks/context_health_hook.py"},"region":{"startLine":2179}}}],"partialFingerprints":{"codehealthFindingId/v1":"6a2c17d9a8d9ee0c1795ee060395e7cadb247654b6d600fdc30fa1365ef5d949"}},{"ruleId":"D2","level":"warning","message":{"text":"ddd_refresh.run_ddd_refresh (cognitive 19): ddd_refresh.run_ddd_refresh has cognitive complexity 19 (threshold 15). Drivers by points: if/else 6 (11 pts), error handling 2 (4 pts), boolean chains 2, loops 1, ternaries 1 (nesting depth added 7). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/jobs/handlers/ddd_refresh.py"},"region":{"startLine":34}}}],"partialFingerprints":{"codehealthFindingId/v1":"5b53ae8ad50876af6bf229f9bcb85393dad984cb7c7a72b31e5fd06a9dd8d3f5"}},{"ruleId":"D2","level":"warning","message":{"text":"session_health_probe.run_session_health_probe (cognitive 19): session_health_probe.run_session_health_probe has cognitive complexity 19 (threshold 15). Drivers by points: error handling 3 (7 pts), boolean chains 5, if/else 3 (4 pts), ternaries 3 (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":"backend/jobs/handlers/session_health_probe.py"},"region":{"startLine":172}}}],"partialFingerprints":{"codehealthFindingId/v1":"098a33db348aed5d972b6c756ddff5c53f0b84f7db1d5d7e1242967c66a0907d"}},{"ruleId":"D2","level":"warning","message":{"text":"skill_proposer._gather_skill_context (cognitive 19): skill_proposer._gather_skill_context has cognitive complexity 19 (threshold 15). Drivers by points: if/else 5 (10 pts), loops 3 (4 pts), error handling 1 (2 pts), ternaries 1 (2 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":"backend/jobs/handlers/skill_proposer.py"},"region":{"startLine":217}}}],"partialFingerprints":{"codehealthFindingId/v1":"d94b0fc6e2f139148d9eb7082f8b404df0d877ab66e3ef9592337f2ec95bd853"}},{"ruleId":"D2","level":"warning","message":{"text":"skill_proposer._generate_skill_proposal (cognitive 19): skill_proposer._generate_skill_proposal has cognitive complexity 19 (threshold 15). Drivers by points: if/else 5 (10 pts), ternaries 2 (6 pts), loops 1 (2 pts), error handling 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":"backend/jobs/handlers/skill_proposer.py"},"region":{"startLine":274}}}],"partialFingerprints":{"codehealthFindingId/v1":"be083191c252ce1b891bd87515035e6ce204e2234eb75aa0c94170432bfd5771"}},{"ruleId":"D2","level":"warning","message":{"text":"main.write_backend_json (cognitive 19): main.write_backend_json has cognitive complexity 19 (threshold 15). Drivers by points: if/else 4 (10 pts), error handling 3 (8 pts), boolean chains 1 (nesting depth added 11). 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":"backend/main.py"},"region":{"startLine":220}}}],"partialFingerprints":{"codehealthFindingId/v1":"ff19dd27db4f9fce082e59e0485ad51cf9c55160ebf617bdf7a2ef42df906cda"}},{"ruleId":"D2","level":"warning","message":{"text":"pipelines.list_pipelines (cognitive 19): pipelines.list_pipelines has cognitive complexity 19 (threshold 15). Drivers by points: if/else 11 (16 pts), loops 1 (2 pts), boolean chains 1 (nesting depth added 6). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/routers/pipelines.py"},"region":{"startLine":308}}}],"partialFingerprints":{"codehealthFindingId/v1":"a8bb194d4747e3d02a9263f0eaf6a125333a743eb1d08a1bc48cda43b1eb93b4"}},{"ruleId":"D2","level":"warning","message":{"text":"system._verify_bedrock (cognitive 19): system._verify_bedrock has cognitive complexity 19 (threshold 15). Drivers by points: if/else 9 (14 pts), boolean chains 3, error handling 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":"backend/routers/system.py"},"region":{"startLine":464}}}],"partialFingerprints":{"codehealthFindingId/v1":"41adc6da6d3bdadb6d68fafb796a0eab067ca58432207a37fce8a5c94cddd9da"}},{"ruleId":"D2","level":"warning","message":{"text":"migrate_skills.extract_first_docstring (cognitive 19): migrate_skills.extract_first_docstring has cognitive complexity 19 (threshold 15). Drivers by points: if/else 5 (11 pts), loops 2 (4 pts), error handling 2 (3 pts), boolean chains 1 (nesting depth added 9). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/scripts/migrate_skills.py"},"region":{"startLine":185}}}],"partialFingerprints":{"codehealthFindingId/v1":"510a66f7c5799b90ec7d1c10b0791eaef0517a8acfd93d6c6c22262e46cdf6dc"}},{"ruleId":"D2","level":"warning","message":{"text":"pipeline_validator._blocked_findings (cognitive 19): pipeline_validator._blocked_findings has cognitive complexity 19 (threshold 15). Drivers by points: if/else 6 (13 pts), error handling 1 (4 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":"backend/scripts/pipeline_validator.py"},"region":{"startLine":106}}}],"partialFingerprints":{"codehealthFindingId/v1":"b81f88995dd2f8183ae52671f565146a6cd15cbb5021465ddca4fe291c4c2ce4"}},{"ruleId":"D2","level":"warning","message":{"text":"DOCXSchemaValidator.validate_insertions (cognitive 19): DOCXSchemaValidator.validate_insertions has cognitive complexity 19 (threshold 15). Drivers by points: if/else 4 (6 pts), loops 3 (5 pts), boolean chains 3, ternaries 1 (3 pts), error handling 1 (2 pts) (nesting depth added 7). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/skills/s_docx/ooxml/scripts/validation/docx.py"},"region":{"startLine":216}}}],"partialFingerprints":{"codehealthFindingId/v1":"1e6d5bbcd96cc174efa0faa7a506b27e25be30c9a54dc201754055f99be1b973"}},{"ruleId":"D2","level":"warning","message":{"text":"design_system.format_markdown (cognitive 19): design_system.format_markdown has cognitive complexity 19 (threshold 15). Drivers by points: if/else 15 (16 pts), boolean chains 2, loops 1 (nesting depth added 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":"backend/skills/s_frontend-design/scripts/design_system.py"},"region":{"startLine":422}}}],"partialFingerprints":{"codehealthFindingId/v1":"e60e5ace4c7e87df86a99a779cf098e2d733e1f7cbc574231265ed61a62f773b"}},{"ruleId":"D2","level":"warning","message":{"text":"SelfLoopsHealthEngine._check_coherence (cognitive 19): SelfLoopsHealthEngine._check_coherence has cognitive complexity 19 (threshold 15). Drivers by points: ternaries 9 (11 pts), if/else 3 (4 pts), error handling 1 (3 pts), 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, 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":"backend/skills/s_loops-health/scripts/loops_health_check.py"},"region":{"startLine":496}}}],"partialFingerprints":{"codehealthFindingId/v1":"dd819b2535c5ef84b507adae8757e1c44d1c81c1dc3fda62d256d2449e3b87d3"}},{"ruleId":"D2","level":"warning","message":{"text":"DOCXSchemaValidator.validate_insertions (cognitive 19): DOCXSchemaValidator.validate_insertions has cognitive complexity 19 (threshold 15). Drivers by points: if/else 4 (6 pts), loops 3 (5 pts), boolean chains 3, ternaries 1 (3 pts), error handling 1 (2 pts) (nesting depth added 7). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/skills/s_pptx/ooxml/scripts/validation/docx.py"},"region":{"startLine":216}}}],"partialFingerprints":{"codehealthFindingId/v1":"e751fbb624affeb02b37b1e2e92492bf189583f09ac090934925564adf6c4f3e"}},{"ruleId":"D2","level":"warning","message":{"text":"todo_db.cmd_update (cognitive 19): todo_db.cmd_update has cognitive complexity 19 (threshold 15). Drivers by points: if/else 9 (14 pts), loops 1 (2 pts), ternaries 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":"backend/skills/s_radar-todo/scripts/todo_db.py"},"region":{"startLine":335}}}],"partialFingerprints":{"codehealthFindingId/v1":"eaa72466d19d54a2945666596f56f3d2252d85b5a82d03501d43d44029ec7d9e"}},{"ruleId":"D2","level":"warning","message":{"text":"ai_ready_helpers._render_step_spec_table (cognitive 19): ai_ready_helpers._render_step_spec_table has cognitive complexity 19 (threshold 15). Drivers by points: if/else 7 (10 pts), boolean chains 4, ternaries 2 (4 pts), loops 1 (nesting depth added 5). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py"},"region":{"startLine":1483}}}],"partialFingerprints":{"codehealthFindingId/v1":"56116f36d4cbd9d54ce5b68697fd031133f002bab4dc6d0afdbac3c7908f2ba0"}},{"ruleId":"D2","level":"warning","message":{"text":"ai_ready_helpers._build_file_tree (cognitive 19): ai_ready_helpers._build_file_tree has cognitive complexity 19 (threshold 15). Drivers by points: if/else 6 (15 pts), loops 1 (2 pts), boolean chains 1, error handling 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":"backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py"},"region":{"startLine":2098}}}],"partialFingerprints":{"codehealthFindingId/v1":"bb80d0bfdabba7a1aebc50345da86eee611f5370fc4204df42c4df03201d057b"}},{"ruleId":"D2","level":"warning","message":{"text":"ai_ready_helpers._language_mix (cognitive 19): ai_ready_helpers._language_mix has cognitive complexity 19 (threshold 15). Drivers by points: if/else 7 (13 pts), error handling 2 (3 pts), loops 1 (2 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":"backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py"},"region":{"startLine":3723}}}],"partialFingerprints":{"codehealthFindingId/v1":"415dfed3aa4ee7edaf8f6cf34ce3ea528fe9c45157fdbb8aca38969315d0a386"}},{"ruleId":"D2","level":"warning","message":{"text":"ai_ready_helpers._render_step_spec_table (cognitive 19): ai_ready_helpers._render_step_spec_table has cognitive complexity 19 (threshold 15). Drivers by points: if/else 7 (10 pts), boolean chains 4, ternaries 2 (4 pts), loops 1 (nesting depth added 5). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py"},"region":{"startLine":1194}}}],"partialFingerprints":{"codehealthFindingId/v1":"c7a2fc930107c9b2b3c52e003de9107d0da55240bd24384e23a40086bc3cdcc2"}},{"ruleId":"D2","level":"warning","message":{"text":"ai_ready_helpers._build_file_tree (cognitive 19): ai_ready_helpers._build_file_tree has cognitive complexity 19 (threshold 15). Drivers by points: if/else 6 (15 pts), loops 1 (2 pts), boolean chains 1, error handling 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":"backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py"},"region":{"startLine":1747}}}],"partialFingerprints":{"codehealthFindingId/v1":"2b2d18f8664e099302b25ec9a67d3984336f9c1874c9ea396d75710a7d8abd93"}},{"ruleId":"D2","level":"warning","message":{"text":"ai_ready_helpers._language_mix (cognitive 19): ai_ready_helpers._language_mix has cognitive complexity 19 (threshold 15). Drivers by points: if/else 7 (13 pts), error handling 2 (3 pts), loops 1 (2 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":"backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py"},"region":{"startLine":3354}}}],"partialFingerprints":{"codehealthFindingId/v1":"32a861df8677d0c6102174da98b0e0571c2e6e0aa7ff256cb28228980d3b4c79"}},{"ruleId":"D2","level":"warning","message":{"text":"security_scan._cors_fingerprints (cognitive 19): security_scan._cors_fingerprints has cognitive complexity 19 (threshold 15). Drivers by points: if/else 4 (9 pts), error handling 2 (4 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":"scripts/security_scan.py"},"region":{"startLine":332}}}],"partialFingerprints":{"codehealthFindingId/v1":"53b524d195fb6f96ca65837f63e70335ecc89d35f20100860932b12c0d41b89b"}},{"ruleId":"D2","level":"warning","message":{"text":"CMBrainOverlay.KnowledgeGraph (cognitive 19): CMBrainOverlay.KnowledgeGraph has cognitive complexity 19 (threshold 15). Drivers by points: ternaries 11 (15 pts), boolean chains 4 (nesting depth added 4). Of this number, 10 points are the body\u0027s own statements and 9 belong to 3 function literals inside it that branch. To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/layout/CMBrainOverlay.tsx"},"region":{"startLine":669}}}],"partialFingerprints":{"codehealthFindingId/v1":"ca5c12ad77de6acf652d2393ffe10de57c85d3e76207c0231d8329892636f44b"}},{"ruleId":"D2","level":"warning","message":{"text":"useChatStreamingLifecycle.cleanupStalePendingEntries (cognitive 19): useChatStreamingLifecycle.cleanupStalePendingEntries has cognitive complexity 19 (threshold 15). Drivers by points: if/else 5 (10 pts), error handling 3 (7 pts), 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":"desktop/src/hooks/useChatStreamingLifecycle.ts"},"region":{"startLine":845}}}],"partialFingerprints":{"codehealthFindingId/v1":"f3a14e8c6dccef82aad15b60e008bc2c179898311d84869517b2ef00a193269a"}},{"ruleId":"D2","level":"warning","message":{"text":"PollinateOverlay.InsightsView (cognitive 19): PollinateOverlay.InsightsView has cognitive complexity 19 (threshold 15). Drivers by points: if/else 6 (11 pts), loops 4 (5 pts), boolean chains 2, ternaries 1 (nesting depth added 6). Most of this is not in the body itself: 5 of the 19 points are its own statements and the rest belongs to one function literal inside it that branches (line 694). The decisions are inside the literal, which nothing outside this body can call, review or test on its own, so splitting the enclosing body is not the move available here. To reduce it, lift the literal\u0027s work into a named function or method at the enclosing scope and have the literal call it, then reduce whichever part then reads as the largest."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/layout/PollinateOverlay.tsx"},"region":{"startLine":693}}}],"partialFingerprints":{"codehealthFindingId/v1":"ae28c7f919bd525f25d8e5ad8b76ece0ae9f3456d7fee2214b434f63b058651b"}},{"ruleId":"D2","level":"warning","message":{"text":"ThreeColumnLayout.LeftSidebar (cognitive 19): ThreeColumnLayout.LeftSidebar has cognitive complexity 19 (threshold 15). Drivers by points: if/else 16, boolean chains 2, ternaries 1. Most of this is not in the body itself: 3 of the 19 points are its own statements and the rest belongs to 15 function literals inside it that branch (lines 313, 314, 224, \u2026). The decisions are inside those literals, which nothing outside this body can call, review or test on its own, so splitting the enclosing body is not the move available here. To reduce it, lift the literals\u0027 work into a named function or method at the enclosing scope and have each literal call it, then reduce whichever part then reads as the largest."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/layout/ThreeColumnLayout.tsx"},"region":{"startLine":177}}}],"partialFingerprints":{"codehealthFindingId/v1":"f48d6fabcb1101f991a240df50268414f86c748b94b376e0d6a50e270e0209c8"}},{"ruleId":"D2","level":"warning","message":{"text":"useStreamingActivity.useStreamingActivity (cognitive 19): useStreamingActivity.useStreamingActivity has cognitive complexity 19 (threshold 15). Drivers by points: if/else 12 (16 pts), boolean chains 3 (nesting depth added 4). Most of this is not in the body itself: 0 of the 19 points are its own statements and the rest belongs to 4 function literals inside it that branch (lines 52, 118, 88, \u2026). The decisions are inside those literals, which nothing outside this body can call, review or test on its own, so splitting the enclosing body is not the move available here. To reduce it, lift the literals\u0027 work into a named function or method at the enclosing scope and have each literal call it, then reduce whichever part then reads as the largest."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/hooks/useStreamingActivity.ts"},"region":{"startLine":37}}}],"partialFingerprints":{"codehealthFindingId/v1":"8eddf172738e953b1bdb9e609d440aa59f571fffd5298c0a8d676d1a7c1cfbda"}},{"ruleId":"D2","level":"warning","message":{"text":"OnboardingPage.StepRestore (cognitive 19): OnboardingPage.StepRestore has cognitive complexity 19 (threshold 15). Drivers by points: if/else 7 (10 pts), boolean chains 7, error handling 1, loops 1 (nesting depth added 3). Most of this is not in the body itself: 7 of the 19 points are its own statements and the rest belongs to 3 function literals inside it that branch (lines 386, 372, 462). The decisions are inside those literals, which nothing outside this body can call, review or test on its own, so splitting the enclosing body is not the move available here. To reduce it, lift the literals\u0027 work into a named function or method at the enclosing scope and have each literal call it, then reduce whichever part then reads as the largest."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/pages/OnboardingPage.tsx"},"region":{"startLine":354}}}],"partialFingerprints":{"codehealthFindingId/v1":"c447ceb4fc70f570090e2481a4f2bc474146ba87ff32811db5e2b9750b2b5923"}},{"ruleId":"D2","level":"warning","message":{"text":"SkillsPage.SkillsPage (cognitive 19): SkillsPage.SkillsPage has cognitive complexity 19 (threshold 15). Drivers by points: ternaries 5 (7 pts), boolean chains 6, error handling 3, if/else 3 (nesting depth added 2). Most of this is not in the body itself: 5 of the 19 points are its own statements and the rest belongs to 6 function literals inside it that branch (lines 205, 110, 122, \u2026). The decisions are inside those literals, which nothing outside this body can call, review or test on its own, so splitting the enclosing body is not the move available here. To reduce it, lift the literals\u0027 work into a named function or method at the enclosing scope and have each literal call it, then reduce whichever part then reads as the largest."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/pages/SkillsPage.tsx"},"region":{"startLine":77}}}],"partialFingerprints":{"codehealthFindingId/v1":"fec677613fb85cbc1101004075a922f2e81af367b5b632bab1ced7413fc9b83f"}},{"ruleId":"D2","level":"warning","message":{"text":"SlackChannelAdapter.update_message (cognitive 18): SlackChannelAdapter.update_message has cognitive complexity 18 (threshold 15). Drivers by points: if/else 5 (7 pts), error handling 3 (5 pts), ternaries 2 (4 pts), loops 1 (2 pts) (nesting depth added 7). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/channels/adapters/slack.py"},"region":{"startLine":1208}}}],"partialFingerprints":{"codehealthFindingId/v1":"266de1b4c48d7faf53c876756182a14e5bccb556c2ed90ae2b650841f06b2dc5"}},{"ruleId":"D2","level":"warning","message":{"text":"SlackChannelAdapter._try_socket_mode_reconnect (cognitive 18): SlackChannelAdapter._try_socket_mode_reconnect has cognitive complexity 18 (threshold 15). Drivers by points: if/else 6 (9 pts), error handling 3 (6 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":"backend/channels/adapters/slack.py"},"region":{"startLine":1574}}}],"partialFingerprints":{"codehealthFindingId/v1":"2873d8ae776e2dc4ff65551b0907b968372ae3b045e868bd9eab12a1bf3acff3"}},{"ruleId":"D2","level":"warning","message":{"text":"streaming.handle_tool_use (cognitive 18): streaming.handle_tool_use has cognitive complexity 18 (threshold 15). Drivers by points: if/else 8 (12 pts), error handling 2 (4 pts), ternaries 1 (2 pts) (nesting depth added 7). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/channels/streaming.py"},"region":{"startLine":344}}}],"partialFingerprints":{"codehealthFindingId/v1":"912caf307de5c29cebbbc029b213972c12ca5a9b372bf1ca2983b74da6f22477"}},{"ruleId":"D2","level":"warning","message":{"text":"cjk_index._expand_token (cognitive 18): cjk_index._expand_token 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":"backend/core/cjk_index.py"},"region":{"startLine":98}}}],"partialFingerprints":{"codehealthFindingId/v1":"876c528c90ea37d4ac2a053d310d0f2d58e8d71cd36ceb6e1a1fb100ceb46ffe"}},{"ruleId":"D2","level":"warning","message":{"text":"context_injector._extract_user_directives (cognitive 18): context_injector._extract_user_directives has cognitive complexity 18 (threshold 15). Drivers by points: if/else 7 (14 pts), boolean chains 2, error handling 1, 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":"backend/core/context_injector.py"},"region":{"startLine":511}}}],"partialFingerprints":{"codehealthFindingId/v1":"9977ec9524debc303f75870ff8c37fda0241d5fe856ec2fdbaebba0d640526b4"}},{"ruleId":"D2","level":"warning","message":{"text":"context_injector._format_recent_turns (cognitive 18): context_injector._format_recent_turns has cognitive complexity 18 (threshold 15). Drivers by points: if/else 7 (12 pts), boolean chains 2, ternaries 1 (2 pts), error handling 1, loops 1 (nesting depth added 6). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/core/context_injector.py"},"region":{"startLine":876}}}],"partialFingerprints":{"codehealthFindingId/v1":"6b0da90dd768f1ca6ad50fbfed44f67e1d3344be5b784b15c6fb8695c23f2160"}},{"ruleId":"D2","level":"warning","message":{"text":"ddd_packager.emit_target_aim (cognitive 18): ddd_packager.emit_target_aim has cognitive complexity 18 (threshold 15). Drivers by points: if/else 7 (10 pts), boolean chains 3, loops 3, ternaries 2 (nesting depth added 3). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/core/ddd_packager.py"},"region":{"startLine":1500}}}],"partialFingerprints":{"codehealthFindingId/v1":"97c66bf2fd58f96c4cc97a637a8541b12973d1dbff79b6d826b640e761a0800f"}},{"ruleId":"D2","level":"warning","message":{"text":"EvalService._merge_partition_cases (cognitive 18): EvalService._merge_partition_cases has cognitive complexity 18 (threshold 15). Drivers by points: if/else 5 (11 pts), loops 3 (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":"backend/core/eval_service.py"},"region":{"startLine":1338}}}],"partialFingerprints":{"codehealthFindingId/v1":"4f3dd06cc129b2384a05fb9a4e3e31381631a846185905e125935c510a8917ca"}},{"ruleId":"D2","level":"warning","message":{"text":"evolution_optimizer.run_evolution_cycle (cognitive 18): evolution_optimizer.run_evolution_cycle has cognitive complexity 18 (threshold 15). Drivers by points: if/else 5 (13 pts), error handling 3 (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":"backend/core/evolution_optimizer.py"},"region":{"startLine":1066}}}],"partialFingerprints":{"codehealthFindingId/v1":"a3d5281dabd74e6230e229844dd576c13922d528a5c3ae5b1cbea6129e1e8ce1"}},{"ruleId":"D2","level":"warning","message":{"text":"git_sync_engine._export_tables_sync (cognitive 18): git_sync_engine._export_tables_sync has cognitive complexity 18 (threshold 15). Drivers by points: if/else 6 (10 pts), error handling 2 (3 pts), loops 2 (3 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":"backend/core/git_sync_engine.py"},"region":{"startLine":66}}}],"partialFingerprints":{"codehealthFindingId/v1":"b1dcb9c1998e48a498e295a431b2697dc3b4dcd7cbfb92f32bebb768afe54968"}},{"ruleId":"D2","level":"warning","message":{"text":"git_sync_engine._import_tables_sync (cognitive 18): git_sync_engine._import_tables_sync has cognitive complexity 18 (threshold 15). Drivers by points: if/else 5 (9 pts), error handling 3 (6 pts), 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":"backend/core/git_sync_engine.py"},"region":{"startLine":209}}}],"partialFingerprints":{"codehealthFindingId/v1":"32a06037fa4cd0e274749503ecb045331523bb09682370ccd46eb2e4cfb42ac3"}},{"ruleId":"D2","level":"warning","message":{"text":"library_mounts.judge_mount_kind (cognitive 18): library_mounts.judge_mount_kind has cognitive complexity 18 (threshold 15). Drivers by points: if/else 6 (11 pts), error handling 3 (5 pts), loops 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":"backend/core/library_mounts.py"},"region":{"startLine":391}}}],"partialFingerprints":{"codehealthFindingId/v1":"1855aedacb9ae02658c3501307fe02cbe2ab55a9ebcb73e20c6b5f8974513a44"}},{"ruleId":"D2","level":"warning","message":{"text":"LifecycleManager._check_memory_pressure (cognitive 18): LifecycleManager._check_memory_pressure has cognitive complexity 18 (threshold 15). Drivers by points: if/else 9 (15 pts), boolean chains 1, error handling 1, loops 1 (nesting depth added 6). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/core/lifecycle_manager.py"},"region":{"startLine":1534}}}],"partialFingerprints":{"codehealthFindingId/v1":"2d28e11d8afa0fb5aa56e007b64dea4a1efd4727923f340b6f467b66c1f96fd2"}},{"ruleId":"D2","level":"warning","message":{"text":"ManifestLoader.ensure_dependencies (cognitive 18): ManifestLoader.ensure_dependencies has cognitive complexity 18 (threshold 15). Drivers by points: if/else 13 (15 pts), error handling 3 (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":"backend/core/manifest_loader.py"},"region":{"startLine":161}}}],"partialFingerprints":{"codehealthFindingId/v1":"e23dbc79a8516003b59fdd94c0369cf732575c27aa734a9ab866421d549090d3"}},{"ruleId":"D2","level":"warning","message":{"text":"proactive_intelligence._extract_first_heading (cognitive 18): proactive_intelligence._extract_first_heading has cognitive complexity 18 (threshold 15). Drivers by points: if/else 5 (13 pts), loops 2 (3 pts), boolean chains 1, error handling 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":"backend/core/proactive_intelligence.py"},"region":{"startLine":1658}}}],"partialFingerprints":{"codehealthFindingId/v1":"e0416016036be2d9f45657cc5af2b3b560ef8c2c8fdc99a1a412aac212bd1d99"}},{"ruleId":"D2","level":"warning","message":{"text":"recall_multi.render_recall_body (cognitive 18): recall_multi.render_recall_body has cognitive complexity 18 (threshold 15). Drivers by points: if/else 6 (9 pts), boolean chains 6, ternaries 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":"backend/core/recall_multi.py"},"region":{"startLine":567}}}],"partialFingerprints":{"codehealthFindingId/v1":"9a3fd0ef9eda4532eb27144b13a98bf01b59d33166a83efdc3c75f114863e2be"}},{"ruleId":"D2","level":"warning","message":{"text":"TaskManager._handle_pending_interaction (cognitive 18): TaskManager._handle_pending_interaction has cognitive complexity 18 (threshold 15). Drivers by points: if/else 6 (14 pts), loops 2 (3 pts), error handling 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":"backend/core/task_manager.py"},"region":{"startLine":321}}}],"partialFingerprints":{"codehealthFindingId/v1":"5ad39fd75cb935585262cb4f1e5e24b14fe4a26e2b3328b0f41f9d3bc4eef1d3"}},{"ruleId":"D2","level":"warning","message":{"text":"todo_stats.compute_history_stats (cognitive 18): todo_stats.compute_history_stats has cognitive complexity 18 (threshold 15). Drivers by points: if/else 6 (13 pts), boolean chains 2, ternaries 2, 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":"backend/core/todo_stats.py"},"region":{"startLine":55}}}],"partialFingerprints":{"codehealthFindingId/v1":"e261176f6d18f56620e6cdb78fce6f3b1b326d512c240eabd4358c260366024e"}},{"ruleId":"D2","level":"warning","message":{"text":"tool_risk.classify (cognitive 18): tool_risk.classify has cognitive complexity 18 (threshold 15). Drivers by points: if/else 11 (15 pts), ternaries 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":"backend/core/tool_risk.py"},"region":{"startLine":103}}}],"partialFingerprints":{"codehealthFindingId/v1":"21cfd7daf6b8438faf983fe9fd6373a5280a1708d3a3887a4015ad981b0ddec1"}},{"ruleId":"D2","level":"warning","message":{"text":"user_observer._extract_text (cognitive 18): user_observer._extract_text has cognitive complexity 18 (threshold 15). Drivers by points: if/else 5 (10 pts), ternaries 2 (6 pts), loops 1 (2 pts) (nesting depth added 10). To reduce it, flatten the nesting: this score is depth rather than breadth \u2014 most of its points come from checks stacked inside one another, so the work sits several levels in. Invert each enclosing check into an early exit (a return, or the language\u0027s equivalent) so the happy path stays at one level, and where a level cannot be exited early, lift the block it encloses into its own named function."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/core/user_observer.py"},"region":{"startLine":56}}}],"partialFingerprints":{"codehealthFindingId/v1":"560a149907918e874cd7cb4ee55e3c9f025d798e73725dd9b1c05aa9e34319d9"}},{"ruleId":"D2","level":"warning","message":{"text":"TodoLifecycleHook._handle_implicit_matching (cognitive 18): TodoLifecycleHook._handle_implicit_matching has cognitive complexity 18 (threshold 15). Drivers by points: if/else 8 (13 pts), error handling 1 (3 pts), boolean chains 1, 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":"backend/hooks/todo_lifecycle_hook.py"},"region":{"startLine":351}}}],"partialFingerprints":{"codehealthFindingId/v1":"3880a77b3f39151e81ae0829797c0240b078ab4da97bf033b7fb0ccd3dbba33c"}},{"ruleId":"D2","level":"warning","message":{"text":"self_tune.prune_unused_feeds (cognitive 18): self_tune.prune_unused_feeds has cognitive complexity 18 (threshold 15). Drivers by points: if/else 7 (17 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":"backend/jobs/self_tune.py"},"region":{"startLine":286}}}],"partialFingerprints":{"codehealthFindingId/v1":"c6003bf6042fa647f12007e1657caf4b946d73da2488e9d4f24047c889370545"}},{"ruleId":"D2","level":"warning","message":{"text":"system.get_system_status (cognitive 18): system.get_system_status has cognitive complexity 18 (threshold 15). Drivers by points: ternaries 4 (7 pts), error handling 4, if/else 4, boolean chains 3 (nesting depth added 3). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/routers/system.py"},"region":{"startLine":150}}}],"partialFingerprints":{"codehealthFindingId/v1":"088519e81a9bb15edd6112f7e705d6ce70d3bf558f06c2df906daf563aa3c6c7"}},{"ruleId":"D2","level":"warning","message":{"text":"system._probe_aws_profiles (cognitive 18): system._probe_aws_profiles has cognitive complexity 18 (threshold 15). Drivers by points: if/else 4 (7 pts), boolean chains 5, ternaries 2 (4 pts), error handling 1, 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":"backend/routers/system.py"},"region":{"startLine":807}}}],"partialFingerprints":{"codehealthFindingId/v1":"5fc1fbe3530a29ba5b34481edd13ff7af76079044a5a9cdfd7ede60942d30d14"}},{"ruleId":"D2","level":"warning","message":{"text":"judge_telemetry_report._load_rows (cognitive 18): judge_telemetry_report._load_rows has cognitive complexity 18 (threshold 15). Drivers by points: if/else 5 (11 pts), error handling 2 (5 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":"backend/scripts/judge_telemetry_report.py"},"region":{"startLine":38}}}],"partialFingerprints":{"codehealthFindingId/v1":"f1761f43e6281bfbeda527a090f0d9a6c5b385f75704b5a5069d9af5da2fb0ef"}},{"ruleId":"D2","level":"warning","message":{"text":"refresh_ai_docs.check_staleness (cognitive 18): refresh_ai_docs.check_staleness has cognitive complexity 18 (threshold 15). Drivers by points: if/else 7 (17 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":"backend/scripts/refresh_ai_docs.py"},"region":{"startLine":343}}}],"partialFingerprints":{"codehealthFindingId/v1":"091ff14059023a641e9bc12dcacdf196c2be26e0e31259c582dad1290f577d66"}},{"ruleId":"D2","level":"warning","message":{"text":"refresh_ai_docs.refresh (cognitive 18): refresh_ai_docs.refresh has cognitive complexity 18 (threshold 15). Drivers by points: if/else 8 (12 pts), loops 3 (5 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":"backend/scripts/refresh_ai_docs.py"},"region":{"startLine":406}}}],"partialFingerprints":{"codehealthFindingId/v1":"983e306fe51df7302b7c21a6b75f34f76a32cef2117e0cf67cf7b7d730df19e3"}},{"ruleId":"D2","level":"warning","message":{"text":"uninstall_cleanup.main (cognitive 18): uninstall_cleanup.main has cognitive complexity 18 (threshold 15). Drivers by points: if/else 12 (17 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":"backend/scripts/uninstall_cleanup.py"},"region":{"startLine":65}}}],"partialFingerprints":{"codehealthFindingId/v1":"99cc776067fd542715cc645e3fbaa76b93e813c0e856e1eae319e8cf451758d6"}},{"ruleId":"D2","level":"warning","message":{"text":"design_system.format_master_md (cognitive 18): design_system.format_master_md has cognitive complexity 18 (threshold 15). Drivers by points: if/else 12 (15 pts), loops 2 (3 pts) (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":"backend/skills/s_frontend-design/scripts/design_system.py"},"region":{"startLine":612}}}],"partialFingerprints":{"codehealthFindingId/v1":"7ce0cff9596789d03e8c0c97056397d79b51e02dd2a9b421e3331cc8f9846db8"}},{"ruleId":"D2","level":"warning","message":{"text":"cross_format_check.check_naming_conventions (cognitive 18): cross_format_check.check_naming_conventions has cognitive complexity 18 (threshold 15). Drivers by points: if/else 7 (14 pts), loops 2 (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":"backend/skills/s_pollinate/scripts/cross_format_check.py"},"region":{"startLine":180}}}],"partialFingerprints":{"codehealthFindingId/v1":"d159ba4ed237944501fd25ea07f597dc61430fc53de843a09bd1787a1c656ead"}},{"ruleId":"D2","level":"warning","message":{"text":"azure.synthesize (cognitive 18): azure.synthesize has cognitive complexity 18 (threshold 15). Drivers by points: if/else 6 (15 pts), 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":"backend/skills/s_pollinate/scripts/tts/backends/azure.py"},"region":{"startLine":9}}}],"partialFingerprints":{"codehealthFindingId/v1":"dbe7a1b936e06fbb8a29f495f67e65445dfb2b21b116489815f991081b0406a7"}},{"ruleId":"D2","level":"warning","message":{"text":"ShapeData.__init__ (cognitive 18): ShapeData.__init__ has cognitive complexity 18 (threshold 15). Drivers by points: ternaries 9, if/else 3 (6 pts), boolean chains 3 (nesting depth added 3). To reduce it, split the body: most of this score is breadth rather than depth \u2014 checks laid out side by side rather than stacked \u2014 so group the statements between the checks into named steps and move each step into its own function. Some of it IS depth: where a check sits inside another whose only job is to reach it, merge the two into one condition."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/skills/s_pptx/scripts/inventory.py"},"region":{"startLine":388}}}],"partialFingerprints":{"codehealthFindingId/v1":"dbaa18c5cf61bc7e0e8bc2f857fbcaa52a3406b422f6a307165bc51b7052d01c"}},{"ruleId":"D2","level":"warning","message":{"text":"ShapeData._get_default_font_size (cognitive 18): ShapeData._get_default_font_size has cognitive complexity 18 (threshold 15). Drivers by points: if/else 5 (9 pts), loops 2 (4 pts), boolean chains 2, ternaries 1 (2 pts), error handling 1 (nesting depth added 7). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/skills/s_pptx/scripts/inventory.py"},"region":{"startLine":480}}}],"partialFingerprints":{"codehealthFindingId/v1":"bf075fbd22a73ec091fbf7f47a4707c1bd366affeefb07f16f5560e81f1a0fc2"}},{"ruleId":"D2","level":"warning","message":{"text":"ai_ready_helpers.parse_git_gotchas (cognitive 18): ai_ready_helpers.parse_git_gotchas has cognitive complexity 18 (threshold 15). Drivers by points: if/else 5 (8 pts), loops 5 (6 pts), ternaries 1 (3 pts), error handling 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":"backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py"},"region":{"startLine":1903}}}],"partialFingerprints":{"codehealthFindingId/v1":"488748e7a3d6cb4e2e2a6a99fce5bfc5acd5de52bbdf1e92a5132e05adfc795b"}},{"ruleId":"D2","level":"warning","message":{"text":"ai_ready_helpers.incremental_update (cognitive 18): ai_ready_helpers.incremental_update has cognitive complexity 18 (threshold 15). Drivers by points: if/else 8, boolean chains 4, error handling 4, ternaries 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":"backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py"},"region":{"startLine":2746}}}],"partialFingerprints":{"codehealthFindingId/v1":"53eabb7347df9811f570564568b62050edf1dbaf24e115dc13adc73413af98f2"}},{"ruleId":"D2","level":"warning","message":{"text":"ai_ready_helpers._expand_globs (cognitive 18): ai_ready_helpers._expand_globs has cognitive complexity 18 (threshold 15). Drivers by points: if/else 4 (8 pts), error handling 2 (5 pts), loops 2 (3 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":"backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py"},"region":{"startLine":3571}}}],"partialFingerprints":{"codehealthFindingId/v1":"a98f1a7e250ea0fe5e6fa351cc39d0a1c17182dfeb03c9c880cedccbdfe54294"}},{"ruleId":"D2","level":"warning","message":{"text":"ai_ready_helpers.detect_package_roots (cognitive 18): ai_ready_helpers.detect_package_roots has cognitive complexity 18 (threshold 15). Drivers by points: error handling 2 (5 pts), if/else 3 (5 pts), loops 3 (4 pts), ternaries 2 (4 pts) (nesting depth added 8). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py"},"region":{"startLine":3755}}}],"partialFingerprints":{"codehealthFindingId/v1":"f4ca67aea02423c74e4f625a4e14fc504c048717c82317df498279b6e853ad02"}},{"ruleId":"D2","level":"warning","message":{"text":"ai_ready_helpers.parse_git_gotchas (cognitive 18): ai_ready_helpers.parse_git_gotchas has cognitive complexity 18 (threshold 15). Drivers by points: if/else 5 (8 pts), loops 5 (6 pts), ternaries 1 (3 pts), error handling 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":"backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py"},"region":{"startLine":1567}}}],"partialFingerprints":{"codehealthFindingId/v1":"e8e4e6debbfa2aa6864e303b75c263ec5218fddb749bbb0a0faff5e740ebc0ed"}},{"ruleId":"D2","level":"warning","message":{"text":"ai_ready_helpers.incremental_update (cognitive 18): ai_ready_helpers.incremental_update has cognitive complexity 18 (threshold 15). Drivers by points: if/else 8, boolean chains 4, error handling 4, ternaries 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":"backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py"},"region":{"startLine":2399}}}],"partialFingerprints":{"codehealthFindingId/v1":"21137fe98630540419e4c2f90a6c4557d6df67571df4ae1a375e55f6d46fbd2d"}},{"ruleId":"D2","level":"warning","message":{"text":"ai_ready_helpers._expand_globs (cognitive 18): ai_ready_helpers._expand_globs has cognitive complexity 18 (threshold 15). Drivers by points: if/else 4 (8 pts), error handling 2 (5 pts), loops 2 (3 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":"backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py"},"region":{"startLine":3202}}}],"partialFingerprints":{"codehealthFindingId/v1":"9ced45bfb69dc2c581339fb20f37059007b195e6133476991d524ec8a2d7a117"}},{"ruleId":"D2","level":"warning","message":{"text":"ai_ready_helpers.detect_package_roots (cognitive 18): ai_ready_helpers.detect_package_roots has cognitive complexity 18 (threshold 15). Drivers by points: error handling 2 (5 pts), if/else 3 (5 pts), loops 3 (4 pts), ternaries 2 (4 pts) (nesting depth added 8). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py"},"region":{"startLine":3386}}}],"partialFingerprints":{"codehealthFindingId/v1":"2cf414be0f17b0ad4e60f15658fd2a767ca93839e8fc5a2cf8715732f410c64c"}},{"ruleId":"D2","level":"warning","message":{"text":"swarmai::screen_capture::prune_old_screenshots (cognitive 18): swarmai::screen_capture::prune_old_screenshots has cognitive complexity 18 (threshold 15). Drivers by points: if/else 6 (17 pts), loops 1 (nesting depth added 11). 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":"desktop/src-tauri/src/screen_capture.rs"},"region":{"startLine":70}}}],"partialFingerprints":{"codehealthFindingId/v1":"8a53bc3eda6820a79032fdf9cc75e132c6f48d5194a929a67a415417dddd890f"}},{"ruleId":"D2","level":"warning","message":{"text":"EvalDashboard.CaseDetailDrawer (cognitive 18): EvalDashboard.CaseDetailDrawer has cognitive complexity 18 (threshold 15). Drivers by points: boolean chains 17, if/else 1. Of this number, 16 points are the body\u0027s own statements and 2 belong to one function literal inside it that branches. To reduce it, name the conditions: bind each compound test to a well-named local or a small predicate function, so the body reads as a sequence of named decisions rather than a chain of operators."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/pages/EvalDashboard.tsx"},"region":{"startLine":2191}}}],"partialFingerprints":{"codehealthFindingId/v1":"c7dfb4efb2a4bf3dbdccf100aafaf2acaae825fea828924cbab8183fabe49609"}},{"ruleId":"D2","level":"warning","message":{"text":"TerminalPanel.TerminalPanel (cognitive 18): TerminalPanel.TerminalPanel has cognitive complexity 18 (threshold 15). Drivers by points: ternaries 8 (9 pts), if/else 5, boolean chains 4 (nesting depth added 1). Most of this is not in the body itself: 6 of the 18 points are its own statements and the rest belongs to 7 function literals inside it that branch (lines 57, 70, 123, \u2026). The decisions are inside those literals, which nothing outside this body can call, review or test on its own, so splitting the enclosing body is not the move available here. To reduce it, lift the literals\u0027 work into a named function or method at the enclosing scope and have each literal call it, then reduce whichever part then reads as the largest."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/terminal/TerminalPanel.tsx"},"region":{"startLine":23}}}],"partialFingerprints":{"codehealthFindingId/v1":"a1890081b3106915b3a265e4af9510094a99044132cfea47e1d58e326e421c05"}},{"ruleId":"D2","level":"warning","message":{"text":"CanvasOutputRail.OutputRow (cognitive 18): CanvasOutputRail.OutputRow has cognitive complexity 18 (threshold 15). Drivers by points: ternaries 9 (11 pts), boolean chains 6, if/else 1 (nesting depth added 2). Of this number, 16 points are the body\u0027s own statements and 2 belong to 2 function literals inside it that branch. 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":"desktop/src/components/file-viewer/CanvasOutputRail.tsx"},"region":{"startLine":109}}}],"partialFingerprints":{"codehealthFindingId/v1":"deaa981c0e0266652bebb9e448d608be6791c0a1179fdc699fa2629de154957f"}},{"ruleId":"D2","level":"warning","message":{"text":"fileClassification.determineDeliveryStrategy (cognitive 18): fileClassification.determineDeliveryStrategy has cognitive complexity 18 (threshold 15). Drivers by points: if/else 5 (14 pts), ternaries 1 (2 pts), boolean chains 1, match/switch 1 (nesting depth added 10). The drivers above price the dispatch low by construction \u2014 a dispatch is charged once however many cases it lists, while each branch inside an arm is charged in full \u2014 so most of this count is what the case bodies hold, and the arms are where it can be reduced. To reduce it, keep the dispatch but shrink the arms: move each non-trivial case body into its own named function (or onto the value being matched) so the dispatch reads one line per case, and group related cases into a sub-dispatch. Keep every case explicit, and make the behaviour for cases you do not list a deliberate choice rather than an accident."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/utils/fileClassification.ts"},"region":{"startLine":177}}}],"partialFingerprints":{"codehealthFindingId/v1":"62dd38e69a31ef5f3ed52aa047b0b2e984dc9d21a5d4ce49217254592d00f519"}},{"ruleId":"D2","level":"warning","message":{"text":"parser._is_entry_point (cognitive 17): parser._is_entry_point has cognitive complexity 17 (threshold 15). Drivers by points: if/else 7 (13 pts), boolean chains 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":"backend/core/code_intel/parser.py"},"region":{"startLine":746}}}],"partialFingerprints":{"codehealthFindingId/v1":"850d4d7ec8af4002de32785da5a59568e22bf003e6dbd156a783ff231e39412f"}},{"ruleId":"D2","level":"warning","message":{"text":"CompactionGuard.work_summary (cognitive 17): CompactionGuard.work_summary has cognitive complexity 17 (threshold 15). Drivers by points: loops 4 (6 pts), if/else 2 (4 pts), error handling 2 (3 pts), ternaries 1 (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":"backend/core/compaction_guard.py"},"region":{"startLine":748}}}],"partialFingerprints":{"codehealthFindingId/v1":"c7c378659dda98c76dafead981626d93dfc404fb844f231078785c612a0a719d"}},{"ruleId":"D2","level":"warning","message":{"text":"ddd_cultivation._locate_target_entry (cognitive 17): ddd_cultivation._locate_target_entry has cognitive complexity 17 (threshold 15). Drivers by points: if/else 6 (8 pts), boolean chains 4, loops 3 (4 pts), error handling 1 (nesting depth added 3). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/core/ddd_cultivation.py"},"region":{"startLine":1546}}}],"partialFingerprints":{"codehealthFindingId/v1":"8a544be16707572de21411d7f8659f74f1e6751c61f527067a226036cee530e7"}},{"ruleId":"D2","level":"warning","message":{"text":"ddd_cultivation.derive_gate2_outcome (cognitive 17): ddd_cultivation.derive_gate2_outcome has cognitive complexity 17 (threshold 15). Drivers by points: if/else 7 (13 pts), boolean chains 2, loops 1, ternaries 1 (nesting depth added 6). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/core/ddd_cultivation.py"},"region":{"startLine":1917}}}],"partialFingerprints":{"codehealthFindingId/v1":"049ab70be181598cde6c4b83003d76836873d3f9b4fe4f3ea71642da35825d19"}},{"ruleId":"D2","level":"warning","message":{"text":"ddd_packager.gate_provenance_leaks (cognitive 17): ddd_packager.gate_provenance_leaks has cognitive complexity 17 (threshold 15). Drivers by points: if/else 3 (7 pts), loops 2 (3 pts), ternaries 1 (3 pts), boolean chains 2, error handling 1 (2 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":"backend/core/ddd_packager.py"},"region":{"startLine":494}}}],"partialFingerprints":{"codehealthFindingId/v1":"eb396d7e40e31f7c9e50aa3e2275075f11a3e54ac8bafb5b1148e6c7c3bc5d32"}},{"ruleId":"D2","level":"warning","message":{"text":"EvalService._load_golden_set (cognitive 17): EvalService._load_golden_set has cognitive complexity 17 (threshold 15). Drivers by points: if/else 6 (10 pts), boolean chains 4, 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":"backend/core/eval_service.py"},"region":{"startLine":91}}}],"partialFingerprints":{"codehealthFindingId/v1":"3c6b8b28628d3be559898aeec07acdd1c6577e278bc1221cd975bd87cf0a210f"}},{"ruleId":"D2","level":"warning","message":{"text":"EvolutionOptimizer.optimize_skill (cognitive 17): EvolutionOptimizer.optimize_skill has cognitive complexity 17 (threshold 15). Drivers by points: if/else 9 (11 pts), boolean chains 3, loops 1 (2 pts), ternaries 1 (nesting depth added 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":"backend/core/evolution_optimizer.py"},"region":{"startLine":785}}}],"partialFingerprints":{"codehealthFindingId/v1":"4a7f8f5876d0fc296600ac281d2de7a2f7db1e6e24e520cc99951ad11f29a15d"}},{"ruleId":"D2","level":"warning","message":{"text":"EvolutionOptimizer._log_to_evolution (cognitive 17): EvolutionOptimizer._log_to_evolution has cognitive complexity 17 (threshold 15). Drivers by points: if/else 7 (12 pts), error handling 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":"backend/core/evolution_optimizer.py"},"region":{"startLine":935}}}],"partialFingerprints":{"codehealthFindingId/v1":"36aba59d6ffc7317b1c859f55dfd5329ce012f9f65efb26eb4c8465a939bd5b0"}},{"ruleId":"D2","level":"warning","message":{"text":"hook_builder.build_hooks (cognitive 17): hook_builder.build_hooks has cognitive complexity 17 (threshold 15). Drivers by points: if/else 8 (9 pts), error handling 2 (4 pts), boolean chains 3, ternaries 1 (nesting depth added 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":"backend/core/hook_builder.py"},"region":{"startLine":229}}}],"partialFingerprints":{"codehealthFindingId/v1":"ced58faf744c859369177878fa3b7a4300523072e2285180394cda008e35990d"}},{"ruleId":"D2","level":"warning","message":{"text":"LifecycleManager._maintenance_loop (cognitive 17): LifecycleManager._maintenance_loop has cognitive complexity 17 (threshold 15). Drivers by points: if/else 4 (8 pts), error handling 3 (6 pts), boolean chains 2, 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":"backend/core/lifecycle_manager.py"},"region":{"startLine":264}}}],"partialFingerprints":{"codehealthFindingId/v1":"9050fcefa11019a4e2c93a46e903dde23034f3f57b88e8565d51f958d98a9d69"}},{"ruleId":"D2","level":"warning","message":{"text":"LifecycleManager._reap_by_pattern (cognitive 17): LifecycleManager._reap_by_pattern has cognitive complexity 17 (threshold 15). Drivers by points: if/else 6 (11 pts), error handling 2 (4 pts), boolean chains 1, 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":"backend/core/lifecycle_manager.py"},"region":{"startLine":1817}}}],"partialFingerprints":{"codehealthFindingId/v1":"c52178d40c6ce38be38fcb68376e603951904d4455022c2840adfe2160d665b0"}},{"ruleId":"D2","level":"warning","message":{"text":"observation_hooks._maybe_emit_ddd_event_sync (cognitive 17): observation_hooks._maybe_emit_ddd_event_sync has cognitive complexity 17 (threshold 15). Drivers by points: if/else 5 (7 pts), error handling 2 (6 pts), boolean chains 2, loops 1 (2 pts) (nesting depth added 7). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/core/observation_hooks.py"},"region":{"startLine":125}}}],"partialFingerprints":{"codehealthFindingId/v1":"6b12ba9ab62e51b88303c255107728ddcb5b861dd3eefd291085957f3212de3a"}},{"ruleId":"D2","level":"warning","message":{"text":"PluginManager._detect_standalone_skill (cognitive 17): PluginManager._detect_standalone_skill has cognitive complexity 17 (threshold 15). Drivers by points: if/else 4 (8 pts), error handling 2 (4 pts), loops 2 (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":"backend/core/plugin_manager.py"},"region":{"startLine":406}}}],"partialFingerprints":{"codehealthFindingId/v1":"a07b44c98a6eed52628e97b52962824d038f46e01758ed1c63c73837f5dedf9b"}},{"ruleId":"D2","level":"warning","message":{"text":"runtime_hooks.read_correction_stats (cognitive 17): runtime_hooks.read_correction_stats has cognitive complexity 17 (threshold 15). Drivers by points: if/else 6 (11 pts), error handling 2 (3 pts), boolean chains 2, loops 1 (nesting depth added 6). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/core/runtime_hooks.py"},"region":{"startLine":1414}}}],"partialFingerprints":{"codehealthFindingId/v1":"d998658380bab5505dac5698318d104f7c5958de1ed2dca8301d59c480c143c9"}},{"ruleId":"D2","level":"warning","message":{"text":"security_hooks._match_governance_tier (cognitive 17): security_hooks._match_governance_tier has cognitive complexity 17 (threshold 15). Drivers by points: if/else 5 (9 pts), boolean chains 6, loops 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":"backend/core/security_hooks.py"},"region":{"startLine":2332}}}],"partialFingerprints":{"codehealthFindingId/v1":"3a0999872b27113f761781339cf76c4ded6db765cdef2abcd044c2138daf1441"}},{"ruleId":"D2","level":"warning","message":{"text":"ServiceManager._health_monitor (cognitive 17): ServiceManager._health_monitor has cognitive complexity 17 (threshold 15). Drivers by points: if/else 3 (10 pts), loops 2 (3 pts), boolean chains 2, error handling 1 (2 pts) (nesting depth added 9). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/core/service_manager.py"},"region":{"startLine":343}}}],"partialFingerprints":{"codehealthFindingId/v1":"9f8a62144f95d795654064723de5cf94c747d8e0057e13a8f1f497d6f9bbe7eb"}},{"ruleId":"D2","level":"warning","message":{"text":"SessionRouter._acquire_channel_slot (cognitive 17): SessionRouter._acquire_channel_slot has cognitive complexity 17 (threshold 15). Drivers by points: if/else 7 (13 pts), error handling 1 (2 pts), boolean chains 1, 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":"backend/core/session_router.py"},"region":{"startLine":2236}}}],"partialFingerprints":{"codehealthFindingId/v1":"6b323438e622eede9c39f5e6070439ebc814e72284246743c485cc28e3c20f03"}},{"ruleId":"D2","level":"warning","message":{"text":"session_utils.classify_failure (cognitive 17): session_utils.classify_failure has cognitive complexity 17 (threshold 15). Drivers by points: if/else 10 (13 pts), boolean chains 3, error handling 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."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/core/session_utils.py"},"region":{"startLine":57}}}],"partialFingerprints":{"codehealthFindingId/v1":"70e19da6d653b1a0764c221821214bc96b1aec4b0f9516294ce7ea114403c3df"}},{"ruleId":"D2","level":"warning","message":{"text":"skill_health.build_health_map (cognitive 17): skill_health.build_health_map has cognitive complexity 17 (threshold 15). Drivers by points: ternaries 5 (10 pts), boolean chains 3, if/else 1 (2 pts), loops 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":"backend/core/skill_health.py"},"region":{"startLine":96}}}],"partialFingerprints":{"codehealthFindingId/v1":"6dc3e9ee2fc3c2b06c3a1d1e5d53e5f9e317a242bd3309027d798fc32b545948"}},{"ruleId":"D2","level":"warning","message":{"text":"code_change_feed._reindex_changed_files (cognitive 17): code_change_feed._reindex_changed_files has cognitive complexity 17 (threshold 15). Drivers by points: if/else 8 (13 pts), error handling 2 (3 pts), loops 1 (nesting depth added 6). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/hooks/code_change_feed.py"},"region":{"startLine":378}}}],"partialFingerprints":{"codehealthFindingId/v1":"f5e68897cb5ccef9ef04190f93c658c653da34ef24b2c9918699b29a655f42c7"}},{"ruleId":"D2","level":"warning","message":{"text":"ContextHealthHook._update_maturity (cognitive 17): ContextHealthHook._update_maturity has cognitive complexity 17 (threshold 15). Drivers by points: if/else 5 (10 pts), loops 2 (3 pts), error handling 1 (2 pts), boolean chains 1, ternaries 1 (nesting depth added 7). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/hooks/context_health_hook.py"},"region":{"startLine":1343}}}],"partialFingerprints":{"codehealthFindingId/v1":"166205d5ca360e954fb677c4a3b9f6e0f2b80a979c50d34f2ed149232215fb88"}},{"ruleId":"D2","level":"warning","message":{"text":"ContextHealthHook._extract_title (cognitive 17): ContextHealthHook._extract_title has cognitive complexity 17 (threshold 15). Drivers by points: if/else 6 (14 pts), boolean chains 1, error handling 1, 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":"backend/hooks/context_health_hook.py"},"region":{"startLine":3613}}}],"partialFingerprints":{"codehealthFindingId/v1":"56415023214958fa446bceabc618321d498b6659c8a3686d204343d62b5369a6"}},{"ruleId":"D2","level":"warning","message":{"text":"DailyActivityExtractionHook._execute_locked (cognitive 17): DailyActivityExtractionHook._execute_locked has cognitive complexity 17 (threshold 15). Drivers by points: if/else 8 (12 pts), error handling 4 (5 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":"backend/hooks/daily_activity_hook.py"},"region":{"startLine":188}}}],"partialFingerprints":{"codehealthFindingId/v1":"2315a57f0886e94496e1ba94607c7d5ee69bbebd17fb22a1908317b588b81e58"}},{"ruleId":"D2","level":"warning","message":{"text":"DistillationTriggerHook._extract_competence (cognitive 17): DistillationTriggerHook._extract_competence has cognitive complexity 17 (threshold 15). Drivers by points: if/else 6 (12 pts), boolean chains 4, loops 1 (nesting depth added 6). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/hooks/distillation_hook.py"},"region":{"startLine":1237}}}],"partialFingerprints":{"codehealthFindingId/v1":"f5770b52621807f60e2a4e039060d0f90be6aba0d630e1cc62462216510911d6"}},{"ruleId":"D2","level":"warning","message":{"text":"signal_ddd_bridge.bridge_signals_to_ddd (cognitive 17): signal_ddd_bridge.bridge_signals_to_ddd has cognitive complexity 17 (threshold 15). Drivers by points: if/else 7 (11 pts), boolean chains 4, error handling 1, 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":"backend/hooks/signal_ddd_bridge.py"},"region":{"startLine":44}}}],"partialFingerprints":{"codehealthFindingId/v1":"91674865d778e9cd02b99fe421edca61587e9b7605665d46724005842b682a71"}},{"ruleId":"D2","level":"warning","message":{"text":"swarmai_monthly_report._collect_job_metrics (cognitive 17): swarmai_monthly_report._collect_job_metrics has cognitive complexity 17 (threshold 15). Drivers by points: if/else 6 (12 pts), error handling 1 (2 pts), boolean chains 1, loops 1, ternaries 1 (nesting depth added 7). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/jobs/handlers/swarmai_monthly_report.py"},"region":{"startLine":374}}}],"partialFingerprints":{"codehealthFindingId/v1":"5f2e9e7c9b87001bc71fa1732afbd0f34877540ecee0b1116e34f91770038484"}},{"ruleId":"D2","level":"warning","message":{"text":"scheduler.validate_config (cognitive 17): scheduler.validate_config has cognitive complexity 17 (threshold 15). Drivers by points: if/else 5 (8 pts), error handling 4 (6 pts), 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":"backend/jobs/scheduler.py"},"region":{"startLine":689}}}],"partialFingerprints":{"codehealthFindingId/v1":"abebb2850d23e0919d01e233400a56d52c40e381aafb128fe9b8237bde0c0f72"}},{"ruleId":"D2","level":"warning","message":{"text":"main._start_code_intel_watchers (cognitive 17): main._start_code_intel_watchers has cognitive complexity 17 (threshold 15). Drivers by points: if/else 8 (14 pts), boolean chains 1, error handling 1, loops 1 (nesting depth added 6). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/main.py"},"region":{"startLine":770}}}],"partialFingerprints":{"codehealthFindingId/v1":"e6b9167a34ff8d0150afe961e442d36db07c032ec9164e43c32fb1e6351d05d4"}},{"ruleId":"D2","level":"warning","message":{"text":"pollinate.pollinate_assets (cognitive 17): pollinate.pollinate_assets has cognitive complexity 17 (threshold 15). Drivers by points: if/else 5 (11 pts), loops 2 (3 pts), error handling 1 (2 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":"backend/routers/pollinate.py"},"region":{"startLine":558}}}],"partialFingerprints":{"codehealthFindingId/v1":"fa6ddec13800ad63bef366b1c3458b944966da3484f1f5f19b9499a243797972"}},{"ruleId":"D2","level":"warning","message":{"text":"workspace_config.update_mcp_configs (cognitive 17): workspace_config.update_mcp_configs has cognitive complexity 17 (threshold 15). Drivers by points: ternaries 3 (9 pts), if/else 3 (5 pts), boolean chains 1, error handling 1, 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":"backend/routers/workspace_config.py"},"region":{"startLine":167}}}],"partialFingerprints":{"codehealthFindingId/v1":"afd063cad7503d9d2384ad80bbea6585affcb45c1b5e4c718681d5085ec61bd3"}},{"ruleId":"D2","level":"warning","message":{"text":"eval_runner.eval_recall_at_k (cognitive 17): eval_runner.eval_recall_at_k has cognitive complexity 17 (threshold 15). Drivers by points: if/else 6 (12 pts), boolean chains 3, error handling 1 (2 pts) (nesting depth added 7). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/scripts/eval_runner.py"},"region":{"startLine":376}}}],"partialFingerprints":{"codehealthFindingId/v1":"83aeeb5a407b6fec96bc5e486f6dc8ac69449b22e71d3084207b3a6c673f0d0e"}},{"ruleId":"D2","level":"warning","message":{"text":"seed_corrections.write_corrections (cognitive 17): seed_corrections.write_corrections has cognitive complexity 17 (threshold 15). Drivers by points: if/else 4 (10 pts), error handling 1 (4 pts), 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":"backend/scripts/seed_corrections.py"},"region":{"startLine":128}}}],"partialFingerprints":{"codehealthFindingId/v1":"ac8d3b3fba954c7a85d55cac995010c5fcc599df1db492ef9138349e253f1ac9"}},{"ruleId":"D2","level":"warning","message":{"text":"DesignSystemGenerator._select_best_match (cognitive 17): DesignSystemGenerator._select_best_match has cognitive complexity 17 (threshold 15). Drivers by points: if/else 4 (8 pts), loops 4 (6 pts), boolean chains 2, ternaries 1 (nesting depth added 6). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/skills/s_frontend-design/scripts/design_system.py"},"region":{"startLine":122}}}],"partialFingerprints":{"codehealthFindingId/v1":"6a75fc7883f9df557dececbf3d0521a71455d458e318b667c6559b5e97b1ca2d"}},{"ruleId":"D2","level":"warning","message":{"text":"generate_tts._hard_split (cognitive 17): generate_tts._hard_split has cognitive complexity 17 (threshold 15). Drivers by points: if/else 6 (12 pts), loops 2 (4 pts), 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":"backend/skills/s_pollinate/scripts/generate_tts.py"},"region":{"startLine":39}}}],"partialFingerprints":{"codehealthFindingId/v1":"24e10d48ed6a399577ff75c98058b351795e639f8f55f505b943408ebbce7e5a"}},{"ruleId":"D2","level":"warning","message":{"text":"generate_tts.chunk_text (cognitive 17): generate_tts.chunk_text has cognitive complexity 17 (threshold 15). Drivers by points: if/else 5 (9 pts), ternaries 2 (6 pts), loops 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":"backend/skills/s_pollinate/scripts/generate_tts.py"},"region":{"startLine":75}}}],"partialFingerprints":{"codehealthFindingId/v1":"fc3811388bea250c824ce50c13157b9141452079046d1df2fafed8b1a443cdba"}},{"ruleId":"D2","level":"warning","message":{"text":"inventory.extract_text_inventory (cognitive 17): inventory.extract_text_inventory has cognitive complexity 17 (threshold 15). Drivers by points: if/else 6 (12 pts), loops 3 (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":"backend/skills/s_pptx/scripts/inventory.py"},"region":{"startLine":914}}}],"partialFingerprints":{"codehealthFindingId/v1":"587b9e4e441adb9796d66bc5b59a7955c6daf759b190b88d555f81f2135b9be6"}},{"ruleId":"D2","level":"warning","message":{"text":"thumbnail.create_grid (cognitive 17): thumbnail.create_grid has cognitive complexity 17 (threshold 15). Drivers by points: if/else 5 (11 pts), loops 2 (4 pts), boolean chains 1, 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":"backend/skills/s_pptx/scripts/thumbnail.py"},"region":{"startLine":321}}}],"partialFingerprints":{"codehealthFindingId/v1":"4254b7141ee95620431d1a2bd92484cc7f3ae9733cf99cd2ea31056d23b73eef"}},{"ruleId":"D2","level":"warning","message":{"text":"mcp_validation.validate_env_no_system_db (cognitive 17): mcp_validation.validate_env_no_system_db has cognitive complexity 17 (threshold 15). Drivers by points: if/else 5 (10 pts), error handling 2 (5 pts), boolean chains 1, 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":"backend/utils/mcp_validation.py"},"region":{"startLine":27}}}],"partialFingerprints":{"codehealthFindingId/v1":"f770a1c52dbc7d7e4a35b951b5aaa4600edc690e4a4496b02f6212b4d4c0985d"}},{"ruleId":"D2","level":"warning","message":{"text":"swarmai::probe_daemon_health_adaptive (cognitive 17): swarmai::probe_daemon_health_adaptive has cognitive complexity 17 (threshold 15). Drivers by points: if/else 5 (8 pts), match/switch 4 (8 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":"desktop/src-tauri/src/lib.rs"},"region":{"startLine":962}}}],"partialFingerprints":{"codehealthFindingId/v1":"40e09f4fe09dd1989252c310f203ac119f0d88cc8bced8ce3d7564772b688a02"}},{"ruleId":"D2","level":"warning","message":{"text":"swarmai::auto_install_daemon (cognitive 17): swarmai::auto_install_daemon has cognitive complexity 17 (threshold 15). Drivers by points: if/else 13 (16 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":"desktop/src-tauri/src/lib.rs"},"region":{"startLine":1448}}}],"partialFingerprints":{"codehealthFindingId/v1":"d9ae6b59a9e64b16b37ddb5b84ed3866a8ac9b6cb710dbc6d2049a300abcb110"}},{"ruleId":"D2","level":"warning","message":{"text":"MarkdownRenderer.MermaidModal (cognitive 17): MarkdownRenderer.MermaidModal has cognitive complexity 17 (threshold 15). Drivers by points: if/else 8 (11 pts), boolean chains 4, ternaries 1 (2 pts) (nesting depth added 4). Most of this is not in the body itself: 1 of the 17 points is its own statement and the rest belongs to 6 function literals inside it that branch (lines 98, 142, 139, \u2026). The decisions are inside those literals, which nothing outside this body can call, review or test on its own, so splitting the enclosing body is not the move available here. To reduce it, lift the literals\u0027 work into a named function or method at the enclosing scope and have each literal call it, then reduce whichever part then reads as the largest."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/common/MarkdownRenderer.tsx"},"region":{"startLine":79}}}],"partialFingerprints":{"codehealthFindingId/v1":"9afa19a28ad167be9a778163b68d03b7cb077224030a6f9662e20e59e73bc5ad"}},{"ruleId":"D2","level":"warning","message":{"text":"ErrorBoundary.ApiError (cognitive 17): ErrorBoundary.ApiError has cognitive complexity 17 (threshold 15). Drivers by points: if/else 10, boolean chains 7. Most of this is not in the body itself: 7 of the 17 points are its own statements and the rest belongs to 2 function literals inside it that branch (lines 155, 165). The decisions are inside those literals, which nothing outside this body can call, review or test on its own, so splitting the enclosing body is not the move available here. To reduce it, lift the literals\u0027 work into a named function or method at the enclosing scope and have each literal call it, then reduce whichever part then reads as the largest."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/common/ErrorBoundary.tsx"},"region":{"startLine":154}}}],"partialFingerprints":{"codehealthFindingId/v1":"b2cf7c2ca1bbb61b6b5701220aca4a9427b105e4eff07903b6020a05060456fc"}},{"ruleId":"D2","level":"warning","message":{"text":"JobsRunsOverlay.JobsRunsContent (cognitive 17): JobsRunsOverlay.JobsRunsContent has cognitive complexity 17 (threshold 15). Drivers by points: if/else 9, ternaries 5, boolean chains 2, error handling 1. Most of this is not in the body itself: 4 of the 17 points are its own statements and the rest belongs to 6 function literals inside it that branch (lines 74, 93, 114, \u2026). The decisions are inside those literals, which nothing outside this body can call, review or test on its own, so splitting the enclosing body is not the move available here. To reduce it, lift the literals\u0027 work into a named function or method at the enclosing scope and have each literal call it, then reduce whichever part then reads as the largest."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/layout/JobsRunsOverlay.tsx"},"region":{"startLine":59}}}],"partialFingerprints":{"codehealthFindingId/v1":"008caa9009e0a08a7c1ef505b1f2dbe42cd7e316a310cd38c8ccac01b29ca713"}},{"ruleId":"D2","level":"warning","message":{"text":"SettingsTabs.SettingsTabs (cognitive 17): SettingsTabs.SettingsTabs has cognitive complexity 17 (threshold 15). Drivers by points: boolean chains 11, if/else 2 (3 pts), ternaries 3 (nesting depth added 1). Most of this is not in the body itself: 0 of the 17 points are its own statements and the rest belongs to 5 function literals inside it that branch (lines 103, 72, 63, \u2026). The decisions are inside those literals, which nothing outside this body can call, review or test on its own, so splitting the enclosing body is not the move available here. To reduce it, lift the literals\u0027 work into a named function or method at the enclosing scope and have each literal call it, then reduce whichever part then reads as the largest."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/settings/SettingsTabs.tsx"},"region":{"startLine":58}}}],"partialFingerprints":{"codehealthFindingId/v1":"a6273f4c7a58012d0d4e84f80dee28dad49fcd1d8ad21279cf67d5223338cc57"}},{"ruleId":"D2","level":"warning","message":{"text":"CommentPopover.CommentPopover (cognitive 17): CommentPopover.CommentPopover has cognitive complexity 17 (threshold 15). Drivers by points: if/else 9 (10 pts), boolean chains 5, ternaries 2 (nesting depth added 1). Most of this is not in the body itself: 4 of the 17 points are its own statements and the rest belongs to 6 function literals inside it that branch (lines 96, 52, 77, \u2026). The decisions are inside those literals, which nothing outside this body can call, review or test on its own, so splitting the enclosing body is not the move available here. To reduce it, lift the literals\u0027 work into a named function or method at the enclosing scope and have each literal call it, then reduce whichever part then reads as the largest."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/common/CommentPopover.tsx"},"region":{"startLine":34}}}],"partialFingerprints":{"codehealthFindingId/v1":"6347c72cf2ddc1d2f8107dcc70b35486bf469137fd0ae64260e7614368f8f2e4"}},{"ruleId":"D2","level":"warning","message":{"text":"useChangeStatus.useChangeStatus (cognitive 17): useChangeStatus.useChangeStatus has cognitive complexity 17 (threshold 15). Drivers by points: if/else 9 (12 pts), loops 2, ternaries 1 (2 pts), boolean chains 1 (nesting depth added 4). Most of this is not in the body itself: 0 of the 17 points are its own statements and the rest belongs to 7 function literals inside it that branch (lines 115, 150, 140, \u2026). The decisions are inside those literals, which nothing outside this body can call, review or test on its own, so splitting the enclosing body is not the move available here. To reduce it, lift the literals\u0027 work into a named function or method at the enclosing scope and have each literal call it, then reduce whichever part then reads as the largest."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/hooks/useChangeStatus.ts"},"region":{"startLine":91}}}],"partialFingerprints":{"codehealthFindingId/v1":"2a2decce49e11423d04b5daa54a79911087d4f522c551bf159a03f467f640cde"}},{"ruleId":"D2","level":"warning","message":{"text":"EvolutionMessage.EvolutionMessage (cognitive 17): EvolutionMessage.EvolutionMessage has cognitive complexity 17 (threshold 15). Drivers by points: boolean chains 8, ternaries 6 (8 pts), if/else 1 (nesting depth added 2). Of this number, 15 points are the body\u0027s own statements and 2 belong to 2 function literals inside it that branch. 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":"desktop/src/components/chat/EvolutionMessage.tsx"},"region":{"startLine":82}}}],"partialFingerprints":{"codehealthFindingId/v1":"98aee1fb63793b4d8bab80761f25374588fc95b0f0dae330f5fb3a7d3dd79a2f"}},{"ruleId":"D2","level":"warning","message":{"text":"TSCCModules.RecallTab (cognitive 17): TSCCModules.RecallTab has cognitive complexity 17 (threshold 15). Drivers by points: boolean chains 8, if/else 4 (5 pts), ternaries 2 (3 pts), loops 1 (nesting depth added 2). Of this number, 12 points are the body\u0027s own statements and 5 belong to 2 function literals inside it that branch. To reduce it, name the conditions: bind each compound test to a well-named local or a small predicate function, so the body reads as a sequence of named decisions rather than a chain of operators."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/pages/chat/components/TSCCModules.tsx"},"region":{"startLine":369}}}],"partialFingerprints":{"codehealthFindingId/v1":"d7f731439e4f25daa26651b9908fc2dc640e957464f641547168db8c9d7ad019"}},{"ruleId":"D2","level":"warning","message":{"text":"TSCCPopoverButton.TSCCPopoverButton (cognitive 17): TSCCPopoverButton.TSCCPopoverButton has cognitive complexity 17 (threshold 15). Drivers by points: if/else 9, boolean chains 4, ternaries 3 (4 pts) (nesting depth added 1). Most of this is not in the body itself: 5 of the 17 points are its own statements and the rest belongs to 7 function literals inside it that branch (lines 105, 80, 70, \u2026). The decisions are inside those literals, which nothing outside this body can call, review or test on its own, so splitting the enclosing body is not the move available here. To reduce it, lift the literals\u0027 work into a named function or method at the enclosing scope and have each literal call it, then reduce whichever part then reads as the largest."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/pages/chat/components/TSCCPopoverButton.tsx"},"region":{"startLine":62}}}],"partialFingerprints":{"codehealthFindingId/v1":"e05444c7aa886ac50504b04d611dc0107818b1c6e3016dc494fac51264e5ea9a"}},{"ruleId":"D2","level":"warning","message":{"text":"compressDOM::(anonymous)::buildSelector (cognitive 17): compressDOM::(anonymous)::buildSelector has cognitive complexity 17 (threshold 15). Drivers by points: if/else 8 (13 pts), boolean chains 3, 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":"backend/skills/s_browser-agent/browser-agent.mjs"},"region":{"startLine":164}}}],"partialFingerprints":{"codehealthFindingId/v1":"2e0bb9b4d0fd44f7d8f73e88d4a9afb74b03a5e08665e4033f628ea7da915faa"}},{"ruleId":"D2","level":"warning","message":{"text":"ChannelGateway.resolve_approval (cognitive 16): ChannelGateway.resolve_approval has cognitive complexity 16 (threshold 15). Drivers by points: if/else 10, boolean chains 3, error handling 1 (2 pts), ternaries 1 (nesting depth added 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":"backend/channels/gateway.py"},"region":{"startLine":574}}}],"partialFingerprints":{"codehealthFindingId/v1":"72fafad334e4f49b8f5111cace399ed68cab528aaf3fc8367eb17de18a3bd40b"}},{"ruleId":"D2","level":"warning","message":{"text":"canvas_noise.is_noise_path (cognitive 16): canvas_noise.is_noise_path has cognitive complexity 16 (threshold 15). Drivers by points: if/else 7 (10 pts), loops 3, boolean chains 2, error handling 1 (nesting depth added 3). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/core/canvas_noise.py"},"region":{"startLine":223}}}],"partialFingerprints":{"codehealthFindingId/v1":"00b311f5363348c4d59fee124431782babc8d72e3a41928996560a87648e2d76"}},{"ruleId":"D2","level":"warning","message":{"text":"code_intel.invalidate_cache (cognitive 16): code_intel.invalidate_cache has cognitive complexity 16 (threshold 15). Drivers by points: error handling 2 (6 pts), if/else 4 (6 pts), loops 2 (4 pts) (nesting depth added 8). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/core/code_intel/__init__.py"},"region":{"startLine":88}}}],"partialFingerprints":{"codehealthFindingId/v1":"a00dcb1c291c952dff6716a0464c1c765be5d1c99bd5da7f5b3d445cd496fe62"}},{"ruleId":"D2","level":"warning","message":{"text":"parser._sql_call_edges (cognitive 16): parser._sql_call_edges has cognitive complexity 16 (threshold 15). Drivers by points: if/else 3 (9 pts), loops 2 (3 pts), boolean chains 2, ternaries 1 (2 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":"backend/core/code_intel/parser.py"},"region":{"startLine":1680}}}],"partialFingerprints":{"codehealthFindingId/v1":"7e7c84a21de0c45fbcd70eda2d5aa3ced4647afd8e30fb5acf7a708214e76a2e"}},{"ruleId":"D2","level":"warning","message":{"text":"community_data.parse_sources (cognitive 16): community_data.parse_sources has cognitive complexity 16 (threshold 15). Drivers by points: boolean chains 5, if/else 3 (5 pts), ternaries 2 (4 pts), error handling 1, 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":"backend/core/community_data.py"},"region":{"startLine":209}}}],"partialFingerprints":{"codehealthFindingId/v1":"d7eaea658038100be46e7c74b44c0ac2bbede0927026854f2d1d1912fb7bb8a6"}},{"ruleId":"D2","level":"warning","message":{"text":"context_directory_loader._filter_dormant_entries (cognitive 16): context_directory_loader._filter_dormant_entries has cognitive complexity 16 (threshold 15). Drivers by points: if/else 4 (11 pts), loops 2 (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":"backend/core/context_directory_loader.py"},"region":{"startLine":165}}}],"partialFingerprints":{"codehealthFindingId/v1":"fbbce34d662c85f5058c7c8874421bc4052ed34842b580690050cb2c12a4b605"}},{"ruleId":"D2","level":"warning","message":{"text":"context_injector._format_message (cognitive 16): context_injector._format_message has cognitive complexity 16 (threshold 15). Drivers by points: if/else 7 (12 pts), boolean chains 1, error handling 1, loops 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":"backend/core/context_injector.py"},"region":{"startLine":116}}}],"partialFingerprints":{"codehealthFindingId/v1":"ee0d42f9723bea11cb22eb6fa53480439ab771f9f46982441fb78fc35b64abd2"}},{"ruleId":"D2","level":"warning","message":{"text":"daily_activity_writer._sanitize_summary_injection (cognitive 16): daily_activity_writer._sanitize_summary_injection has cognitive complexity 16 (threshold 15). Drivers by points: if/else 5 (13 pts), boolean chains 1, error handling 1, 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":"backend/core/daily_activity_writer.py"},"region":{"startLine":399}}}],"partialFingerprints":{"codehealthFindingId/v1":"252629ff4963941696dc5e5cf23e9277aefb50fa1420ec0a2c1d09afa15aa279"}},{"ruleId":"D2","level":"warning","message":{"text":"ddd_maturity.inject_maturity (cognitive 16): ddd_maturity.inject_maturity has cognitive complexity 16 (threshold 15). Drivers by points: if/else 7 (13 pts), boolean chains 2, loops 1 (nesting depth added 6). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/core/ddd_maturity.py"},"region":{"startLine":216}}}],"partialFingerprints":{"codehealthFindingId/v1":"8b1dc56e2b5204f9ee1949e5e53aa92509918fccc7ee702c8397cd36decb7946"}},{"ruleId":"D2","level":"warning","message":{"text":"EvalService.reclaim_stale_skeletons (cognitive 16): EvalService.reclaim_stale_skeletons has cognitive complexity 16 (threshold 15). Drivers by points: if/else 6 (11 pts), error handling 1 (2 pts), boolean chains 1, loops 1, ternaries 1 (nesting depth added 6). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/core/eval_service.py"},"region":{"startLine":751}}}],"partialFingerprints":{"codehealthFindingId/v1":"44441aa4c7252cca37a123007cb467bdd6d9c817682d8bd348551b41ec645799"}},{"ruleId":"D2","level":"warning","message":{"text":"CorrectionClassTracker.briefing_lines (cognitive 16): CorrectionClassTracker.briefing_lines has cognitive complexity 16 (threshold 15). Drivers by points: if/else 5 (9 pts), error handling 1 (3 pts), ternaries 1 (3 pts), 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":"backend/core/evolution/correction_tracker.py"},"region":{"startLine":517}}}],"partialFingerprints":{"codehealthFindingId/v1":"d32abc033c7a785789ccc81a7deab132cda9acd9b9577105358328ba5ecf851f"}},{"ruleId":"D2","level":"warning","message":{"text":"escalation_ladder.decide_escalation (cognitive 16): escalation_ladder.decide_escalation has cognitive complexity 16 (threshold 15). Drivers by points: if/else 7, boolean chains 6, error handling 2, ternaries 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":"backend/core/evolution/escalation_ladder.py"},"region":{"startLine":75}}}],"partialFingerprints":{"codehealthFindingId/v1":"5536e50a4171794b09759fafb8a0f999b5b37e59242984ea731275a6c6a286cc"}},{"ruleId":"D2","level":"warning","message":{"text":"LifecycleManager._check_ttl (cognitive 16): LifecycleManager._check_ttl has cognitive complexity 16 (threshold 15). Drivers by points: if/else 5 (15 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":"backend/core/lifecycle_manager.py"},"region":{"startLine":933}}}],"partialFingerprints":{"codehealthFindingId/v1":"3c744d123ea558b4dbec3cc36cab692717ee429e2b7de1a3ca9d8026ab0d49fa"}},{"ruleId":"D2","level":"warning","message":{"text":"ManifestLoader.load (cognitive 16): ManifestLoader.load has cognitive complexity 16 (threshold 15). Drivers by points: if/else 7 (10 pts), loops 2 (3 pts), boolean chains 2, error handling 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":"backend/core/manifest_loader.py"},"region":{"startLine":116}}}],"partialFingerprints":{"codehealthFindingId/v1":"9509970285b0df90c8a56ad8ac8a953586e253036e2a60eff46a60e1e128d684"}},{"ruleId":"D2","level":"warning","message":{"text":"proactive_intelligence._detect_patterns (cognitive 16): proactive_intelligence._detect_patterns has cognitive complexity 16 (threshold 15). Drivers by points: if/else 8 (13 pts), loops 2, 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":"backend/core/proactive_intelligence.py"},"region":{"startLine":405}}}],"partialFingerprints":{"codehealthFindingId/v1":"afd14475ad129da07f25926f507ac1a44026ae2e11b1d503ee6cea1be2a3f5ec"}},{"ruleId":"D2","level":"warning","message":{"text":"proactive_scoring.generate_reasoning (cognitive 16): proactive_scoring.generate_reasoning has cognitive complexity 16 (threshold 15). Drivers by points: if/else 5 (10 pts), ternaries 2 (4 pts), boolean chains 1, 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":"backend/core/proactive_scoring.py"},"region":{"startLine":240}}}],"partialFingerprints":{"codehealthFindingId/v1":"570b1e44849b2b69a2f5cb238c7695951f866a7afc0e2c67a026cb93a24a4027"}},{"ruleId":"D2","level":"warning","message":{"text":"RetryManager._inject_abandon_continuation (cognitive 16): RetryManager._inject_abandon_continuation has cognitive complexity 16 (threshold 15). Drivers by points: error handling 4 (6 pts), if/else 6, boolean chains 4 (nesting depth added 2). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/core/retry_manager.py"},"region":{"startLine":637}}}],"partialFingerprints":{"codehealthFindingId/v1":"387b6ffd99a1262056674b839217fdd22f9765d33961784db9a5a4351d4c7f7c"}},{"ruleId":"D2","level":"warning","message":{"text":"ServiceManager.start_all (cognitive 16): ServiceManager.start_all has cognitive complexity 16 (threshold 15). Drivers by points: if/else 7 (10 pts), error handling 1 (2 pts), loops 2, boolean chains 1, ternaries 1 (nesting depth added 4). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/core/service_manager.py"},"region":{"startLine":123}}}],"partialFingerprints":{"codehealthFindingId/v1":"5a2614b675e0d7690034d2bc3aed9b6a35c50f25c64425dc7cca823331d1753b"}},{"ruleId":"D2","level":"warning","message":{"text":"StreamingOrchestrator._stream_response (cognitive 16): StreamingOrchestrator._stream_response has cognitive complexity 16 (threshold 15). Drivers by points: if/else 6 (11 pts), loops 2 (3 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":"backend/core/streaming_orchestrator.py"},"region":{"startLine":241}}}],"partialFingerprints":{"codehealthFindingId/v1":"719d907bdad06b5b3c3b4a39cfd01936f32e6b8ba27277f23d651610efb37f5c"}},{"ruleId":"D2","level":"warning","message":{"text":"SummarizationPipeline._derive_title (cognitive 16): SummarizationPipeline._derive_title has cognitive complexity 16 (threshold 15). Drivers by points: if/else 8 (13 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":"backend/core/summarization.py"},"region":{"startLine":543}}}],"partialFingerprints":{"codehealthFindingId/v1":"7727f5c992bec9259fb0d9cdf3ac6e0e93fc1cee0d2bc9445684cac9a3ea6933"}},{"ruleId":"D2","level":"warning","message":{"text":"swarm_workspace_manager._assert_ai_instruction_sentinels (cognitive 16): swarm_workspace_manager._assert_ai_instruction_sentinels has cognitive complexity 16 (threshold 15). Drivers by points: if/else 3 (7 pts), error handling 2 (5 pts), boolean chains 3, 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":"backend/core/swarm_workspace_manager.py"},"region":{"startLine":112}}}],"partialFingerprints":{"codehealthFindingId/v1":"d1a241cbdc4ab6e17ecfa369d6a89d2556bb0d1314a27d0cd4bb6c8f4ceb0818"}},{"ruleId":"D2","level":"warning","message":{"text":"transcript_indexer.sync_transcript_index (cognitive 16): transcript_indexer.sync_transcript_index has cognitive complexity 16 (threshold 15). Drivers by points: if/else 4 (7 pts), error handling 3 (6 pts), loops 2 (3 pts) (nesting depth added 7). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/core/transcript_indexer.py"},"region":{"startLine":680}}}],"partialFingerprints":{"codehealthFindingId/v1":"824b8f399139c9796ea3e6b978c81bf6c275810a84181f4541167413bd79c9ad"}},{"ruleId":"D2","level":"warning","message":{"text":"CodeChangeFeed._detect_arch_changes (cognitive 16): CodeChangeFeed._detect_arch_changes has cognitive complexity 16 (threshold 15). Drivers by points: if/else 7 (11 pts), boolean chains 4, 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":"backend/hooks/code_change_feed.py"},"region":{"startLine":182}}}],"partialFingerprints":{"codehealthFindingId/v1":"3c242e950208d5e9071d5b05dd4ffff6d29a7889d17286e61c1d032f0bb98867"}},{"ruleId":"D2","level":"warning","message":{"text":"DistillationTriggerHook._passes_frequency_gate (cognitive 16): DistillationTriggerHook._passes_frequency_gate has cognitive complexity 16 (threshold 15). Drivers by points: if/else 7 (12 pts), boolean chains 2, 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":"backend/hooks/distillation_hook.py"},"region":{"startLine":1387}}}],"partialFingerprints":{"codehealthFindingId/v1":"f8c3674ed9bb647d2db68a7cddc68fa1ac63084b32b95541d4df2f5c9c11e629"}},{"ruleId":"D2","level":"warning","message":{"text":"hacker_news.fetch_hacker_news (cognitive 16): hacker_news.fetch_hacker_news has cognitive complexity 16 (threshold 15). Drivers by points: if/else 2 (6 pts), loops 2 (3 pts), ternaries 1 (3 pts), boolean chains 2, error handling 1 (2 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":"backend/jobs/adapters/hacker_news.py"},"region":{"startLine":22}}}],"partialFingerprints":{"codehealthFindingId/v1":"2c2a573b6d96ff287e5e1da2e5c6991e05a5ac032be2e677592eed30818a965f"}},{"ruleId":"D2","level":"warning","message":{"text":"executor._handle_script (cognitive 16): executor._handle_script has cognitive complexity 16 (threshold 15). Drivers by points: if/else 8, ternaries 3 (4 pts), boolean chains 3, error handling 1 (nesting depth added 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":"backend/jobs/executor.py"},"region":{"startLine":986}}}],"partialFingerprints":{"codehealthFindingId/v1":"ae91a31600a447969aba519b75bb877eedfbe157a8f2a6b943983574ef9725b9"}},{"ruleId":"D2","level":"warning","message":{"text":"executor._purge_terminal_todos (cognitive 16): executor._purge_terminal_todos has cognitive complexity 16 (threshold 15). Drivers by points: if/else 4 (5 pts), boolean chains 3, error handling 2 (3 pts), loops 2 (3 pts), ternaries 2 (nesting depth added 3). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/jobs/executor.py"},"region":{"startLine":1920}}}],"partialFingerprints":{"codehealthFindingId/v1":"74882ef495782bf6575a597e1fcfebfc0acb66f54656617f0fc3cfa471fa5f13"}},{"ruleId":"D2","level":"warning","message":{"text":"signal_digest._llm_digest (cognitive 16): signal_digest._llm_digest has cognitive complexity 16 (threshold 15). Drivers by points: ternaries 2 (6 pts), if/else 4 (5 pts), boolean chains 3, error handling 1, 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":"backend/jobs/handlers/signal_digest.py"},"region":{"startLine":253}}}],"partialFingerprints":{"codehealthFindingId/v1":"a08fc7110652e17924118bb3a1cdb086277fe24e52ca10b7bfeadb2655983f85"}},{"ruleId":"D2","level":"warning","message":{"text":"signal_digest._write_l4_json (cognitive 16): signal_digest._write_l4_json has cognitive complexity 16 (threshold 15). Drivers by points: if/else 9 (11 pts), error handling 1 (2 pts), loops 2, 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."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/jobs/handlers/signal_digest.py"},"region":{"startLine":494}}}],"partialFingerprints":{"codehealthFindingId/v1":"1d08d2653dd15a1e5166bd215fbb89775ffdf00439a1438593e846a4b5b76ed5"}},{"ruleId":"D2","level":"warning","message":{"text":"skill_proposer._find_existing_skill (cognitive 16): skill_proposer._find_existing_skill has cognitive complexity 16 (threshold 15). Drivers by points: if/else 7 (11 pts), boolean chains 2, error handling 1 (2 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":"backend/jobs/handlers/skill_proposer.py"},"region":{"startLine":172}}}],"partialFingerprints":{"codehealthFindingId/v1":"9f6943798505455cfe5eebee8532890bbd5f5a76c9f51818c4a00042eb733640"}},{"ruleId":"D2","level":"warning","message":{"text":"ddd_brain._gallery_entry_stats (cognitive 16): ddd_brain._gallery_entry_stats has cognitive complexity 16 (threshold 15). Drivers by points: if/else 5 (11 pts), loops 2 (3 pts), error handling 1 (2 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":"backend/routers/ddd_brain.py"},"region":{"startLine":563}}}],"partialFingerprints":{"codehealthFindingId/v1":"033f215855ac26a6b9c33393c9297667fdda58e4b97efa6fc4c078638fce9c9f"}},{"ruleId":"D2","level":"warning","message":{"text":"pollinate._build_card (cognitive 16): pollinate._build_card has cognitive complexity 16 (threshold 15). Drivers by points: if/else 8 (9 pts), boolean chains 6, ternaries 1 (nesting depth added 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":"backend/routers/pollinate.py"},"region":{"startLine":490}}}],"partialFingerprints":{"codehealthFindingId/v1":"996fb07a8fdfd3f45a3cbda25b93db2dd20f02851cbc69c56d04803fda435838"}},{"ruleId":"D2","level":"warning","message":{"text":"artifact_cli._release_marker_authorizes_head (cognitive 16): artifact_cli._release_marker_authorizes_head has cognitive complexity 16 (threshold 15). Drivers by points: if/else 8 (11 pts), boolean chains 4, error handling 1 (nesting depth added 3). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/scripts/artifact_cli.py"},"region":{"startLine":3194}}}],"partialFingerprints":{"codehealthFindingId/v1":"88f886ec93944822cd0ae15a82b2051d53a47e1b73d4036f0da19445322c7ed0"}},{"ruleId":"D2","level":"warning","message":{"text":"backfill_cjk_escapes.audit_unlisted_columns (cognitive 16): backfill_cjk_escapes.audit_unlisted_columns has cognitive complexity 16 (threshold 15). Drivers by points: if/else 3 (7 pts), error handling 2 (5 pts), loops 2 (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":"backend/scripts/backfill_cjk_escapes.py"},"region":{"startLine":256}}}],"partialFingerprints":{"codehealthFindingId/v1":"1ebdd5a09035acfd52ec8c4b45eec4625d4e8d58df858c9c7ac21f69e1442c94"}},{"ruleId":"D2","level":"warning","message":{"text":"eval_runner._resolve_reference (cognitive 16): eval_runner._resolve_reference has cognitive complexity 16 (threshold 15). Drivers by points: if/else 7 (11 pts), boolean chains 3, error handling 1 (2 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":"backend/scripts/eval_runner.py"},"region":{"startLine":910}}}],"partialFingerprints":{"codehealthFindingId/v1":"39c0b200f571da550aa0cce627b4b0b548d641f3ab03654e099cbb65e919c699"}},{"ruleId":"D2","level":"warning","message":{"text":"eval_runner.run_eval (cognitive 16): eval_runner.run_eval has cognitive complexity 16 (threshold 15). Drivers by points: if/else 8 (10 pts), boolean chains 3, ternaries 1 (2 pts), loops 1 (nesting depth added 3). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/scripts/eval_runner.py"},"region":{"startLine":1771}}}],"partialFingerprints":{"codehealthFindingId/v1":"10e6c1cb4ca0544450ba2d11dba5a35685f7e833cc02a28772964310064a837f"}},{"ruleId":"D2","level":"warning","message":{"text":"pipeline_analytics.analyze_adversarial_value (cognitive 16): pipeline_analytics.analyze_adversarial_value has cognitive complexity 16 (threshold 15). Drivers by points: if/else 8 (13 pts), 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":"backend/scripts/pipeline_analytics.py"},"region":{"startLine":576}}}],"partialFingerprints":{"codehealthFindingId/v1":"0bf7d1ff1a52eb15b1efee732ce9c3743a07f119bc960a25f7662ec0223c234c"}},{"ruleId":"D2","level":"warning","message":{"text":"seed_corrections.parse_corrections (cognitive 16): seed_corrections.parse_corrections has cognitive complexity 16 (threshold 15). Drivers by points: if/else 4 (7 pts), ternaries 3 (6 pts), loops 2 (3 pts) (nesting depth added 7). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/scripts/seed_corrections.py"},"region":{"startLine":28}}}],"partialFingerprints":{"codehealthFindingId/v1":"b328dc6a61b35853a5f3d8b9651b7c9a48b764753e68a10150e8b4f38a130ba6"}},{"ruleId":"D2","level":"warning","message":{"text":"SelfLoopsHealthEngine._check_brain_safety (cognitive 16): SelfLoopsHealthEngine._check_brain_safety has cognitive complexity 16 (threshold 15). Drivers by points: ternaries 7, error handling 2 (3 pts), boolean chains 2, if/else 2, loops 1 (2 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":"backend/skills/s_loops-health/scripts/loops_health_check.py"},"region":{"startLine":551}}}],"partialFingerprints":{"codehealthFindingId/v1":"f5993a791c8b9b778efc8f00c2722b927c968906f51cf6867f0f1919d6f613b2"}},{"ruleId":"D2","level":"warning","message":{"text":"geo_score.main (cognitive 16): geo_score.main has cognitive complexity 16 (threshold 15). Drivers by points: if/else 6 (8 pts), loops 2 (5 pts), ternaries 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":"backend/skills/s_pollinate/scripts/geo_score.py"},"region":{"startLine":345}}}],"partialFingerprints":{"codehealthFindingId/v1":"92981055bb46aa84d1111bea7447c5dc9cae1d641dbf87b05de04818fe0e5614"}},{"ruleId":"D2","level":"warning","message":{"text":"ai_ready_helpers.merge_code_intel (cognitive 16): ai_ready_helpers.merge_code_intel has cognitive complexity 16 (threshold 15). Drivers by points: if/else 4 (7 pts), boolean chains 5, loops 2, ternaries 1 (2 pts) (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":"backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py"},"region":{"startLine":1042}}}],"partialFingerprints":{"codehealthFindingId/v1":"1f5c75d32a5081bc523e020ea3d0b6199cfd8a6bb130cd52aa153843c6e60780"}},{"ruleId":"D2","level":"warning","message":{"text":"ai_ready_helpers.merge_code_intel (cognitive 16): ai_ready_helpers.merge_code_intel has cognitive complexity 16 (threshold 15). Drivers by points: if/else 4 (7 pts), boolean chains 5, loops 2, ternaries 1 (2 pts) (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":"backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py"},"region":{"startLine":778}}}],"partialFingerprints":{"codehealthFindingId/v1":"e4ea114a584e73503c1013ff19574cfa56e360fbca1ebf748da8671441868488"}},{"ruleId":"D2","level":"warning","message":{"text":"check_commit_trailers.main (cognitive 16): check_commit_trailers.main has cognitive complexity 16 (threshold 15). Drivers by points: if/else 7 (9 pts), error handling 3 (5 pts), loops 1, ternaries 1 (nesting depth added 4). To reduce it, split the body: most of this score is breadth rather than depth \u2014 checks laid out side by side rather than stacked \u2014 so group the statements between the checks into named steps and move each step into its own function. Some of it IS depth: where a check sits inside another whose only job is to reach it, merge the two into one condition, 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":"scripts/check_commit_trailers.py"},"region":{"startLine":137}}}],"partialFingerprints":{"codehealthFindingId/v1":"58a3d4be0aed1c62e24556d5fbaaf82746afc364bd4b8c0a5186d9ccabb2323f"}},{"ruleId":"D2","level":"warning","message":{"text":"smoke_import.main (cognitive 16): smoke_import.main has cognitive complexity 16 (threshold 15). Drivers by points: error handling 3 (6 pts), if/else 3 (5 pts), loops 2 (3 pts), boolean chains 1, ternaries 1 (nesting depth added 6). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"scripts/smoke_import.py"},"region":{"startLine":23}}}],"partialFingerprints":{"codehealthFindingId/v1":"cf58c4a6d553680528f6654733ee63889b4fe807154bf62a85e457c5b22577f3"}},{"ruleId":"D2","level":"warning","message":{"text":"SectionLayouts.StepCard (cognitive 16): SectionLayouts.StepCard has cognitive complexity 16 (threshold 15). Drivers by points: ternaries 15, boolean chains 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":"backend/skills/s_pollinate/templates/remotion/components/SectionLayouts.tsx"},"region":{"startLine":579}}}],"partialFingerprints":{"codehealthFindingId/v1":"9d2be462cb34b439185716dfad80fcf0230e813fc2b96389f10b14a948910847"}},{"ruleId":"D2","level":"warning","message":{"text":"ChapterProgressBar.ChapterProgressBar (cognitive 16): ChapterProgressBar.ChapterProgressBar has cognitive complexity 16 (threshold 15). Drivers by points: ternaries 8 (11 pts), boolean chains 4, if/else 1 (nesting depth added 3). Most of this is not in the body itself: 2 of the 16 points are its own statements and the rest belongs to one function literal inside it that branches (line 40). The decisions are inside the literal, which nothing outside this body can call, review or test on its own, so splitting the enclosing body is not the move available here. To reduce it, lift the literal\u0027s work into a named function or method at the enclosing scope and have the literal call it, then reduce whichever part then reads as the largest."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/skills/s_pollinate/templates/remotion/components/ChapterProgressBar.tsx"},"region":{"startLine":7}}}],"partialFingerprints":{"codehealthFindingId/v1":"2e8fc69092c2355df958bfce8f0beaff582a45fd0e8325268e0ad2bfb4db6a7a"}},{"ruleId":"D2","level":"warning","message":{"text":"html2pptx.html2pptx (cognitive 16): html2pptx.html2pptx has cognitive complexity 16 (threshold 15). Drivers by points: if/else 7 (8 pts), boolean chains 4, ternaries 2 (3 pts), error handling 1 (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."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/skills/s_pptx/scripts/html2pptx.js"},"region":{"startLine":896}}}],"partialFingerprints":{"codehealthFindingId/v1":"2d9962ac2ae2ac5b2616041db850816e6add196d13b1bf72ae3762de6ad7767a"}},{"ruleId":"D2","level":"warning","message":{"text":"MarkdownRenderer.MermaidDiagram (cognitive 16): MarkdownRenderer.MermaidDiagram has cognitive complexity 16 (threshold 15). Drivers by points: if/else 8, ternaries 4 (5 pts), error handling 2, boolean chains 1 (nesting depth added 1). Most of this is not in the body itself: 3 of the 16 points are its own statements and the rest belongs to 5 function literals inside it that branch (lines 316, 284, 247, \u2026). The decisions are inside those literals, which nothing outside this body can call, review or test on its own, so splitting the enclosing body is not the move available here. To reduce it, lift the literals\u0027 work into a named function or method at the enclosing scope and have each literal call it, then reduce whichever part then reads as the largest."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/common/MarkdownRenderer.tsx"},"region":{"startLine":238}}}],"partialFingerprints":{"codehealthFindingId/v1":"406281f37622f70e4dc1744ab2ef89a6c55a5c9cd66a8cb7602afc2575dc9aea"}},{"ruleId":"D2","level":"warning","message":{"text":"MarkdownRenderer.isWorkspaceFilePath (cognitive 16): MarkdownRenderer.isWorkspaceFilePath has cognitive complexity 16 (threshold 15). Drivers by points: if/else 11 (13 pts), boolean chains 3 (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."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/common/MarkdownRenderer.tsx"},"region":{"startLine":617}}}],"partialFingerprints":{"codehealthFindingId/v1":"11e4fadf3914c5daace6f6d4d3f03a0a480aed3433f711105e45383af0792fb0"}},{"ruleId":"D2","level":"warning","message":{"text":"api.parseApiError (cognitive 16): api.parseApiError has cognitive complexity 16 (threshold 15). Drivers by points: boolean chains 7, ternaries 3 (6 pts), if/else 2, match/switch 1 (nesting depth added 3). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/services/api.ts"},"region":{"startLine":49}}}],"partialFingerprints":{"codehealthFindingId/v1":"637b834150ba8b6bda24ebe4ed081a7bce4c528dd3cba507acca7421b84b5393"}},{"ruleId":"D2","level":"warning","message":{"text":"JobsRunsOverlay.JobDetailDrawer (cognitive 16): JobsRunsOverlay.JobDetailDrawer has cognitive complexity 16 (threshold 15). Drivers by points: boolean chains 7, ternaries 5 (6 pts), if/else 3 (nesting depth added 1). Of this number, 12 points are the body\u0027s own statements and 4 belong to 4 function literals inside it that branch. 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":"desktop/src/components/layout/JobsRunsOverlay.tsx"},"region":{"startLine":316}}}],"partialFingerprints":{"codehealthFindingId/v1":"7833fa2bf399feb07b399d621b8d8626e0c7486a39bea86ba3ca9bea392e90f7"}},{"ruleId":"D2","level":"warning","message":{"text":"PipelineOverlay.PipelineContent (cognitive 16): PipelineOverlay.PipelineContent has cognitive complexity 16 (threshold 15). Drivers by points: boolean chains 7, if/else 5, ternaries 3, error handling 1. Of this number, 8 points are the body\u0027s own statements and 8 belong to 8 function literals inside it that branch. 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":"desktop/src/components/layout/PipelineOverlay.tsx"},"region":{"startLine":89}}}],"partialFingerprints":{"codehealthFindingId/v1":"8297988eb417d8d892f9d6e2b28d7da110ed2afb12b8ff815d6b152156548374"}},{"ruleId":"D2","level":"warning","message":{"text":"DddCard.FullBody (cognitive 16): DddCard.FullBody has cognitive complexity 16 (threshold 15). Drivers by points: boolean chains 6, if/else 5, ternaries 5. 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":"desktop/src/components/layout/DddCard.tsx"},"region":{"startLine":291}}}],"partialFingerprints":{"codehealthFindingId/v1":"0719494aeb0d7acb5bd5a2dda0a00c73c4eda645940c276f9a3be682c46a5dfd"}},{"ruleId":"D2","level":"warning","message":{"text":"dddOverview.docSignalMap (cognitive 16): dddOverview.docSignalMap has cognitive complexity 16 (threshold 15). Drivers by points: if/else 4 (9 pts), loops 5 (7 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":"desktop/src/components/layout/dddOverview.ts"},"region":{"startLine":72}}}],"partialFingerprints":{"codehealthFindingId/v1":"dffe5e8e3035255e03836a23d9d3c61542bc63ac0d0edfeb1e4c5c10210ddf2f"}},{"ruleId":"D2","level":"warning","message":{"text":"dddOverview.weeklyReportModel (cognitive 16): dddOverview.weeklyReportModel has cognitive complexity 16 (threshold 15). Drivers by points: if/else 4 (8 pts), loops 3 (6 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":"desktop/src/components/layout/dddOverview.ts"},"region":{"startLine":144}}}],"partialFingerprints":{"codehealthFindingId/v1":"d0f1a53a223fe9c41086de2cb6d8d2a04cd36f18eeff5c47e2edb009b394128e"}},{"ruleId":"D2","level":"warning","message":{"text":"BrainHub.hunkSummary (cognitive 16): BrainHub.hunkSummary has cognitive complexity 16 (threshold 15). Drivers by points: if/else 6 (14 pts), boolean chains 1, 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":"desktop/src/components/layout/BrainHub.tsx"},"region":{"startLine":50}}}],"partialFingerprints":{"codehealthFindingId/v1":"39bb2db7c39b7917137bddbea1b1756521e3fc9bd70264183dab9d2f5aaa3b68"}},{"ruleId":"D2","level":"warning","message":{"text":"useReferencedFiles.applyWrite (cognitive 16): useReferencedFiles.applyWrite has cognitive complexity 16 (threshold 15). Drivers by points: if/else 5 (11 pts), loops 1 (3 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":"desktop/src/hooks/useReferencedFiles.ts"},"region":{"startLine":188}}}],"partialFingerprints":{"codehealthFindingId/v1":"dc61d993a30df82152200befeb82cdb2d2592d3eb8f0be32be190663a5a79590"}},{"ruleId":"D2","level":"warning","message":{"text":"TSCCModules.PromptTab (cognitive 16): TSCCModules.PromptTab has cognitive complexity 16 (threshold 15). Drivers by points: ternaries 9 (12 pts), boolean chains 2, error handling 1, if/else 1 (nesting depth added 3). Of this number, 13 points are the body\u0027s own statements and 3 belong to one function literal inside it that branches. 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":"desktop/src/pages/chat/components/TSCCModules.tsx"},"region":{"startLine":555}}}],"partialFingerprints":{"codehealthFindingId/v1":"8969119392741b2c449a844350256bfef0e07e55b5971acd799ac6883ef9a93b"}},{"ruleId":"D3","level":"warning","message":{"text":"FunctionTooLong: ChatPage.ChatPage: FunctionTooLong \u2014 ChatPage runs 1923 significant lines (blank, comment-only and punctuation-only lines excluded) in one body. The bar is 100 significant lines; this is 1823 over it, 19.23\u00D7 the bar. This is length, not branching: a long straight-line body scores low on complexity and is still read whole to change any part of it, so the complexity numbers beside this row neither confirm nor excuse it. To reduce it, extract each cohesive step of the body \u2014 the runs of statements that work on the same values and would earn the same name \u2014 into its own named unit, and have this one call them in order."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/pages/ChatPage.tsx"},"region":{"startLine":129}}}],"partialFingerprints":{"codehealthFindingId/v1":"9387973e654bde06c22bbfc4f6680632e53d61e69cc0e261ad9770e18373437b"}},{"ruleId":"D3","level":"warning","message":{"text":"FunctionTooLong: useChatStreamingLifecycle.useChatStreamingLifecycle: FunctionTooLong \u2014 useChatStreamingLifecycle runs 1648 significant lines (blank, comment-only and punctuation-only lines excluded) in one body. The bar is 100 significant lines; this is 1548 over it, 16.48\u00D7 the bar. This is length, not branching: a long straight-line body scores low on complexity and is still read whole to change any part of it, so the complexity numbers beside this row neither confirm nor excuse it. To reduce it, extract each cohesive step of the body \u2014 the runs of statements that work on the same values and would earn the same name \u2014 into its own named unit, and have this one call them in order."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/hooks/useChatStreamingLifecycle.ts"},"region":{"startLine":1030}}}],"partialFingerprints":{"codehealthFindingId/v1":"a2ce7ecb182844cdce404030a4f1e4e3115cc6c31dd6e185d0d3b4389b5f81c2"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: scripts/artifact_cli.py: FileTooLong \u2014 3360 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 2860 over it, 6.72\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":"backend/scripts/artifact_cli.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"1acc0fdb5292c69064033c39da886b3862dc2aed13fb02f0f77dcd8134ca12f4"}},{"ruleId":"D3","level":"warning","message":{"text":"FunctionTooLong: SkillsPage.GenerateSkillForm: FunctionTooLong \u2014 GenerateSkillForm runs 505 significant lines (blank, comment-only and punctuation-only lines excluded) in one body. The bar is 100 significant lines; this is 405 over it, 5.05\u00D7 the bar. This is length, not branching: a long straight-line body scores low on complexity and is still read whole to change any part of it, so the complexity numbers beside this row neither confirm nor excuse it. To reduce it, extract each cohesive step of the body \u2014 the runs of statements that work on the same values and would earn the same name \u2014 into its own named unit, and have this one call them in order."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/pages/SkillsPage.tsx"},"region":{"startLine":327}}}],"partialFingerprints":{"codehealthFindingId/v1":"04afbda2bcbf49d540395a9d24aab9a1eb0e499bbeec5ae857cc2c3593e1928c"}},{"ruleId":"D3","level":"warning","message":{"text":"ClassTooLong: ChatPage: ClassTooLong \u2014 1923 significant lines (blank, comment-only and punctuation-only lines excluded), 2 methods. The bar is 400 significant lines; this is 1523 over it, 4.81\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":"desktop/src/pages/ChatPage.tsx"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"38151f0bddb256aa9aab3bee6ed71d47f9f444451a05d046d581d02d55816c99"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: scripts/ai_ready_helpers.py: FileTooLong \u2014 2257 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 1757 over it, 4.51\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":"backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"0a70dd9ea2c47b6513c13d778f3813c773bd74219db896e2cbab73fd05838634"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: scripts/pipeline_validator.py: FileTooLong \u2014 2125 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 1625 over it, 4.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":"backend/scripts/pipeline_validator.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"64871b918280712e8c5e20bf6de9d69c5a008d36ac66de6279fd94c649403b9b"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: core/session_unit.py: FileTooLong \u2014 2115 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 1615 over it, 4.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":"backend/core/session_unit.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"e17ca0cab772920c27a7a0ee65f86df95e3ac4b1f43da997f3d05e7e2b3e164b"}},{"ruleId":"D3","level":"warning","message":{"text":"FunctionTooLong: AuthConfigPanel.AuthConfigPanel: FunctionTooLong \u2014 AuthConfigPanel runs 415 significant lines (blank, comment-only and punctuation-only lines excluded) in one body. The bar is 100 significant lines; this is 315 over it, 4.15\u00D7 the bar. This is length, not branching: a long straight-line body scores low on complexity and is still read whole to change any part of it, so the complexity numbers beside this row neither confirm nor excuse it. To reduce it, extract each cohesive step of the body \u2014 the runs of statements that work on the same values and would earn the same name \u2014 into its own named unit, and have this one call them in order."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/settings/AuthConfigPanel.tsx"},"region":{"startLine":29}}}],"partialFingerprints":{"codehealthFindingId/v1":"d0172a6d0f5df4b48322f0a4ad2458fa1c8cd1fcfd3488d76f495aab551c8a89"}},{"ruleId":"D3","level":"warning","message":{"text":"ClassTooLong: useChatStreamingLifecycle: ClassTooLong \u2014 1648 significant lines (blank, comment-only and punctuation-only lines excluded), 18 methods. The bar is 400 significant lines; this is 1248 over it, 4.12\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":"desktop/src/hooks/useChatStreamingLifecycle.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"5b31045a300c8c2bd567b4e1e2777969610def2d34eca94be9268b84cb1a71cb"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: hooks/useChatStreamingLifecycle.ts: FileTooLong \u2014 2045 significant lines (blank, comment-only and punctuation-only lines excluded), about 81% of them inside a single declaration: useChatStreamingLifecycle (1030-4584). The bar is 500 significant lines; this is 1545 over it, 4.09\u00D7 the bar. Moving the declarations that sit BESIDE it into sibling files will not shorten this file. Extract from INSIDE that declaration instead: lift each cohesive group of its body \u2014 the parts that share the same inputs and are named together \u2014 into its own unit in a sibling file, and have the original call them."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/hooks/useChatStreamingLifecycle.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"f13cf1655695418286e284f18d17e1090de18cd0d2e938871b2c4c913dfe5367"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: pages/EvalDashboard.tsx: FileTooLong \u2014 2022 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 1522 over it, 4.04\u00D7 the bar. To reduce it, split the file along the responsibilities already in it: move each cohesive group of declarations into its own sibling file in the same module or package, so no one file has to be read whole to change one of them."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/pages/EvalDashboard.tsx"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"dc28664f2aa0fc755010b56b37f92bea96ea4fb4c72f4f84d59d5a60dab85874"}},{"ruleId":"D3","level":"warning","message":{"text":"FunctionTooLong: html2pptx.extractSlideData: FunctionTooLong \u2014 extractSlideData runs 402 significant lines (blank, comment-only and punctuation-only lines excluded) in one body. The bar is 100 significant lines; this is 302 over it, 4.02\u00D7 the bar. This is length, not branching: a long straight-line body scores low on complexity and is still read whole to change any part of it, so the complexity numbers beside this row neither confirm nor excuse it. To reduce it, extract each cohesive step of the body \u2014 the runs of statements that work on the same values and would earn the same name \u2014 into its own named unit, and have this one call them in order."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/skills/s_pptx/scripts/html2pptx.js"},"region":{"startLine":244}}}],"partialFingerprints":{"codehealthFindingId/v1":"9fbb7f2174977f9291cc393c434c86ca5367bd0af76e19ee519546e592364500"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: pages/ChatPage.tsx: FileTooLong \u2014 1995 significant lines (blank, comment-only and punctuation-only lines excluded), about 96% of them inside a single declaration: ChatPage (129-3557). The bar is 500 significant lines; this is 1495 over it, 3.99\u00D7 the bar. Moving the declarations that sit BESIDE it into sibling files will not shorten this file. Extract from INSIDE that declaration instead: lift each cohesive group of its body \u2014 the parts that share the same inputs and are named together \u2014 into its own unit in a sibling file, and have the original call them."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/pages/ChatPage.tsx"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"1dec29ccf9b0993f81e5bdad48f140c7983938c1210c9f25e1d220a2d7e9a329"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: hooks/context_health_hook.py: FileTooLong \u2014 1992 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 1492 over it, 3.98\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":"backend/hooks/context_health_hook.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"de5f92290d2618f54f5b6b03720001f10edc8304c0600586b54756f99a292d12"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: scripts/ai_ready_helpers.py: FileTooLong \u2014 1983 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 1483 over it, 3.97\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":"backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"1234df887ee28257b546ff7dd774a5d0b66bc5782efe94976508248da4b31bb3"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: database/sqlite.py: FileTooLong \u2014 1760 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 1260 over it, 3.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":"backend/database/sqlite.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"63c0a3d58284c46a26789c4c56574905c03bf42aa6ffc4af7ac912549107ac36"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: core/session_router.py: FileTooLong \u2014 1755 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 1255 over it, 3.51\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":"backend/core/session_router.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"e11c9d2074420247ec87a1d4bbf84b8395a9021efcc1ab7c1b71aa3db5dde1db"}},{"ruleId":"D3","level":"warning","message":{"text":"FunctionTooLong: EvalDashboard.GuideTab: FunctionTooLong \u2014 GuideTab runs 343 significant lines (blank, comment-only and punctuation-only lines excluded) in one body. The bar is 100 significant lines; this is 243 over it, 3.43\u00D7 the bar. This is length, not branching: a long straight-line body scores low on complexity and is still read whole to change any part of it, so the complexity numbers beside this row neither confirm nor excuse it. To reduce it, extract each cohesive step of the body \u2014 the runs of statements that work on the same values and would earn the same name \u2014 into its own named unit, and have this one call them in order."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/pages/EvalDashboard.tsx"},"region":{"startLine":1698}}}],"partialFingerprints":{"codehealthFindingId/v1":"b083f220f0fa0bc33756fc0ba3a63238a2a92c6dfe1e3efa7a4325a949659a3d"}},{"ruleId":"D3","level":"warning","message":{"text":"FunctionTooLong: BackendStartupOverlay.BackendStartupOverlay: FunctionTooLong \u2014 BackendStartupOverlay runs 328 significant lines (blank, comment-only and punctuation-only lines excluded) in one body. The bar is 100 significant lines; this is 228 over it, 3.28\u00D7 the bar. This is length, not branching: a long straight-line body scores low on complexity and is still read whole to change any part of it, so the complexity numbers beside this row neither confirm nor excuse it. To reduce it, extract each cohesive step of the body \u2014 the runs of statements that work on the same values and would earn the same name \u2014 into its own named unit, and have this one call them in order."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/common/BackendStartupOverlay.tsx"},"region":{"startLine":241}}}],"partialFingerprints":{"codehealthFindingId/v1":"3b6d6914a779c2c2ddbf2eb7310247fb84945add8523f2bc81316e2f31f6333a"}},{"ruleId":"D3","level":"warning","message":{"text":"FunctionTooLong: AgentFormModal.AgentFormModal: FunctionTooLong \u2014 AgentFormModal runs 327 significant lines (blank, comment-only and punctuation-only lines excluded) in one body. The bar is 100 significant lines; this is 227 over it, 3.27\u00D7 the bar. This is length, not branching: a long straight-line body scores low on complexity and is still read whole to change any part of it, so the complexity numbers beside this row neither confirm nor excuse it. To reduce it, extract each cohesive step of the body \u2014 the runs of statements that work on the same values and would earn the same name \u2014 into its own named unit, and have this one call them in order."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/common/AgentFormModal.tsx"},"region":{"startLine":36}}}],"partialFingerprints":{"codehealthFindingId/v1":"b381f608d88075342a62d37204a43804ee45ce0011f37866bc56b13364e17e71"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: scripts/eval_runner.py: FileTooLong \u2014 1631 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 1131 over it, 3.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":"backend/scripts/eval_runner.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"ee9cdb1a85ab32d6ea20b8a05c60eacf877cfa6d539bfad850e7f6b8eb308117"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: hooks/distillation_hook.py: FileTooLong \u2014 1625 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 1125 over it, 3.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":"backend/hooks/distillation_hook.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"03ef500057f175a5cabedc4a928848f40e439238178f375b23cb0c05e996343f"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: channels/gateway.py: FileTooLong \u2014 1581 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 1081 over it, 3.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":"backend/channels/gateway.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"b537ef60b247f71b2686ac2425abdc56099374594888bbb7bd78031ffdbbc5b4"}},{"ruleId":"D3","level":"warning","message":{"text":"FunctionTooLong: TabView.TabViewImpl: FunctionTooLong \u2014 TabViewImpl runs 304 significant lines (blank, comment-only and punctuation-only lines excluded) in one body. The bar is 100 significant lines; this is 204 over it, 3.04\u00D7 the bar. This is length, not branching: a long straight-line body scores low on complexity and is still read whole to change any part of it, so the complexity numbers beside this row neither confirm nor excuse it. To reduce it, extract each cohesive step of the body \u2014 the runs of statements that work on the same values and would earn the same name \u2014 into its own named unit, and have this one call them in order."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/pages/chat/components/TabView.tsx"},"region":{"startLine":208}}}],"partialFingerprints":{"codehealthFindingId/v1":"e147a91c750e61ab17eabc4daedd8df6a8e64e72412089c7a8c7bf217ab2772b"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: src/lib.rs: FileTooLong \u2014 1491 significant lines (blank, comment-only and punctuation-only lines excluded, and inline test code \u2014 #[cfg(test)] modules and bare #[test] functions \u2014 not counted), declaring 38 free functions. The bar is 500 significant lines; this is 991 over it, 2.98\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":"desktop/src-tauri/src/lib.rs"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"b9cf0e243cc85e97071d88c3718ac1caf9f3d765bdd5291b0ae699fcdeb3d098"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: common/FileEditorCore.tsx: FileTooLong \u2014 1460 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 960 over it, 2.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":"desktop/src/components/common/FileEditorCore.tsx"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"54d922928aa3f4406959bccc17d90fa1ba9b5ebf1d847945e30e8b2cc9658a2a"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: core/security_hooks.py: FileTooLong \u2014 1452 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 952 over it, 2.90\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":"backend/core/security_hooks.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"a2fa7ddc1b10953bf2d61aaa992281b0de460f96f90a4f2de40a211496981f44"}},{"ruleId":"D3","level":"warning","message":{"text":"FunctionTooLong: browser-agent.main: FunctionTooLong \u2014 main runs 286 significant lines (blank, comment-only and punctuation-only lines excluded) in one body. The bar is 100 significant lines; this is 186 over it, 2.86\u00D7 the bar. This is length, not branching: a long straight-line body scores low on complexity and is still read whole to change any part of it, so the complexity numbers beside this row neither confirm nor excuse it. To reduce it, extract each cohesive step of the body \u2014 the runs of statements that work on the same values and would earn the same name \u2014 into its own named unit, and have this one call them in order."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/skills/s_browser-agent/browser-agent.mjs"},"region":{"startLine":304}}}],"partialFingerprints":{"codehealthFindingId/v1":"a92a6d625bd91d93bef7d8316f6a04bf0bdce244e6528ff4445747ea5f06ccb7"}},{"ruleId":"D3","level":"warning","message":{"text":"FunctionTooLong: FileContextMenu.FileContextMenu: FunctionTooLong \u2014 FileContextMenu runs 282 significant lines (blank, comment-only and punctuation-only lines excluded) in one body. The bar is 100 significant lines; this is 182 over it, 2.82\u00D7 the bar. This is length, not branching: a long straight-line body scores low on complexity and is still read whole to change any part of it, so the complexity numbers beside this row neither confirm nor excuse it. To reduce it, extract each cohesive step of the body \u2014 the runs of statements that work on the same values and would earn the same name \u2014 into its own named unit, and have this one call them in order."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/workspace-explorer/FileContextMenu.tsx"},"region":{"startLine":58}}}],"partialFingerprints":{"codehealthFindingId/v1":"d88e234a2a01c0f1b884df4b4dd1516317f535601d1d250b7222d57dd8ce2afc"}},{"ruleId":"D3","level":"warning","message":{"text":"FunctionTooLong: useUnifiedTabState.useUnifiedTabState: FunctionTooLong \u2014 useUnifiedTabState runs 279 significant lines (blank, comment-only and punctuation-only lines excluded) in one body. The bar is 100 significant lines; this is 179 over it, 2.79\u00D7 the bar. This is length, not branching: a long straight-line body scores low on complexity and is still read whole to change any part of it, so the complexity numbers beside this row neither confirm nor excuse it. To reduce it, extract each cohesive step of the body \u2014 the runs of statements that work on the same values and would earn the same name \u2014 into its own named unit, and have this one call them in order."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/hooks/useUnifiedTabState.ts"},"region":{"startLine":419}}}],"partialFingerprints":{"codehealthFindingId/v1":"010906aa0cdafb7ab8214432b9e044c74b79fffce11966320b106ac9e6ce2a48"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: core/proactive_intelligence.py: FileTooLong \u2014 1361 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 861 over it, 2.72\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":"backend/core/proactive_intelligence.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"dbb3cc21b2867fb5961b9926a3298eb15ff685daa5f309008c194e3e563055f0"}},{"ruleId":"D3","level":"warning","message":{"text":"FunctionTooLong: CapabilitiesOverlay.CapabilitiesContent: FunctionTooLong \u2014 CapabilitiesContent runs 269 significant lines (blank, comment-only and punctuation-only lines excluded) in one body. The bar is 100 significant lines; this is 169 over it, 2.69\u00D7 the bar. This is length, not branching: a long straight-line body scores low on complexity and is still read whole to change any part of it, so the complexity numbers beside this row neither confirm nor excuse it. To reduce it, extract each cohesive step of the body \u2014 the runs of statements that work on the same values and would earn the same name \u2014 into its own named unit, and have this one call them in order."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/layout/CapabilitiesOverlay.tsx"},"region":{"startLine":173}}}],"partialFingerprints":{"codehealthFindingId/v1":"1ce6888cacaa5f4c33ac28d5636c85da0145624146a58c9d24bc1842cd1313cc"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: backend/main.py: FileTooLong \u2014 1281 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 781 over it, 2.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":"backend/main.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"42b528708d9fd6ab4e60dcae3fc2254938956cc3aaa37d2c14844592bccdccba"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: jobs/executor.py: FileTooLong \u2014 1272 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 772 over it, 2.54\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":"backend/jobs/executor.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"ebfd8b95fd2058d441e5656c19e594a60ed8d0d6c1bf4f606bc06b4d972e6e28"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: adapters/slack.py: FileTooLong \u2014 1261 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 761 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":"backend/channels/adapters/slack.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"1996bc3f70bcd86004d6eebd7b2c9df7cf3a89b2548310a48ccebaa5e9823178"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: core/swarm_workspace_manager.py: FileTooLong \u2014 1242 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 742 over it, 2.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":"backend/core/swarm_workspace_manager.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"6372cd226c4d327145238bd8b62517933dae52f6b414f500dfa21059f0ac37df"}},{"ruleId":"D3","level":"warning","message":{"text":"FunctionTooLong: AIModelsTab.AIModelsTab: FunctionTooLong \u2014 AIModelsTab runs 242 significant lines (blank, comment-only and punctuation-only lines excluded) in one body. The bar is 100 significant lines; this is 142 over it, 2.42\u00D7 the bar. This is length, not branching: a long straight-line body scores low on complexity and is still read whole to change any part of it, so the complexity numbers beside this row neither confirm nor excuse it. To reduce it, extract each cohesive step of the body \u2014 the runs of statements that work on the same values and would earn the same name \u2014 into its own named unit, and have this one call them in order."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/settings/AIModelsTab.tsx"},"region":{"startLine":15}}}],"partialFingerprints":{"codehealthFindingId/v1":"eb37074846e9f9145518debc0c7ba2e495d795c4d5b12dcf23cc51cb6016312b"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: core/evolution_optimizer.py: FileTooLong \u2014 1188 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 688 over it, 2.38\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":"backend/core/evolution_optimizer.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"75cbfd07bf9200748b89b7cb38e747cb36f01c3d486afb205556ccb0e86038dd"}},{"ruleId":"D3","level":"warning","message":{"text":"FunctionTooLong: FolderPickerModal.FolderPickerModal: FunctionTooLong \u2014 FolderPickerModal runs 233 significant lines (blank, comment-only and punctuation-only lines excluded) in one body. The bar is 100 significant lines; this is 133 over it, 2.33\u00D7 the bar. This is length, not branching: a long straight-line body scores low on complexity and is still read whole to change any part of it, so the complexity numbers beside this row neither confirm nor excuse it. To reduce it, extract each cohesive step of the body \u2014 the runs of statements that work on the same values and would earn the same name \u2014 into its own named unit, and have this one call them in order."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/workspace/FolderPickerModal.tsx"},"region":{"startLine":21}}}],"partialFingerprints":{"codehealthFindingId/v1":"06083e055a127ccd72bbde18a8f56692fe55bedac228fe2b2fb21b957bf9e129"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: core/ddd_cultivation.py: FileTooLong \u2014 1157 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 657 over it, 2.31\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":"backend/core/ddd_cultivation.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"47cdcbd1cd30cfd7eabcf70f748b8d2a1c85912e189f1121a92c2fab158ce2c5"}},{"ruleId":"D3","level":"warning","message":{"text":"FunctionTooLong: VirtualizedTree.VirtualizedTree: FunctionTooLong \u2014 VirtualizedTree runs 214 significant lines (blank, comment-only and punctuation-only lines excluded) in one body. The bar is 100 significant lines; this is 114 over it, 2.14\u00D7 the bar. This is length, not branching: a long straight-line body scores low on complexity and is still read whole to change any part of it, so the complexity numbers beside this row neither confirm nor excuse it. To reduce it, extract each cohesive step of the body \u2014 the runs of statements that work on the same values and would earn the same name \u2014 into its own named unit, and have this one call them in order."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/workspace-explorer/VirtualizedTree.tsx"},"region":{"startLine":688}}}],"partialFingerprints":{"codehealthFindingId/v1":"44225fe59b73b7bf9d0574ac45e797877aec7c69fcd643920852b1856209a2d1"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: code_intel/parser.py: FileTooLong \u2014 1062 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 562 over it, 2.12\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":"backend/core/code_intel/parser.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"2cb53c89ee230e49d800486642959dd893d7be643a121dca01c9fa4dbdd667b9"}},{"ruleId":"D3","level":"warning","message":{"text":"FunctionTooLong: EvalDashboard.GoldenSetTab: FunctionTooLong \u2014 GoldenSetTab runs 211 significant lines (blank, comment-only and punctuation-only lines excluded) in one body. The bar is 100 significant lines; this is 111 over it, 2.11\u00D7 the bar. This is length, not branching: a long straight-line body scores low on complexity and is still read whole to change any part of it, so the complexity numbers beside this row neither confirm nor excuse it. To reduce it, extract each cohesive step of the body \u2014 the runs of statements that work on the same values and would earn the same name \u2014 into its own named unit, and have this one call them in order."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/pages/EvalDashboard.tsx"},"region":{"startLine":495}}}],"partialFingerprints":{"codehealthFindingId/v1":"9e2c4208b7de8c1c79c33b607a140908b0ef6f0ab7a71fc51daaad81d25ee408"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: core/lifecycle_manager.py: FileTooLong \u2014 1051 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 551 over it, 2.10\u00D7 the bar. To reduce it, split the file along the responsibilities already in it: move each cohesive group of declarations into its own sibling file in the same module or package, so no one file has to be read whole to change one of them."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/core/lifecycle_manager.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"72067e6ea99111c2cca0b8276a0d263bfb0ad91786b34f4502af68e79860304d"}},{"ruleId":"D3","level":"warning","message":{"text":"FunctionTooLong: PollinateOverlay.PollinateContent: FunctionTooLong \u2014 PollinateContent runs 203 significant lines (blank, comment-only and punctuation-only lines excluded) in one body. The bar is 100 significant lines; this is 103 over it, 2.03\u00D7 the bar. This is length, not branching: a long straight-line body scores low on complexity and is still read whole to change any part of it, so the complexity numbers beside this row neither confirm nor excuse it. To reduce it, extract each cohesive step of the body \u2014 the runs of statements that work on the same values and would earn the same name \u2014 into its own named unit, and have this one call them in order."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/layout/PollinateOverlay.tsx"},"region":{"startLine":108}}}],"partialFingerprints":{"codehealthFindingId/v1":"e0b1a066627e109066dbde09672a0ba9c4bebcbef24e9df0343c2a83603fcdbf"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: routers/ddd_brain.py: FileTooLong \u2014 1012 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 512 over it, 2.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":"backend/routers/ddd_brain.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"9b12f2c3522e86c8f6ce4f521b54193a4f4a373c76a88a42285eea98c823c2d0"}},{"ruleId":"D3","level":"warning","message":{"text":"FunctionTooLong: SkillsPage.SkillsPage: FunctionTooLong \u2014 SkillsPage runs 202 significant lines (blank, comment-only and punctuation-only lines excluded) in one body. The bar is 100 significant lines; this is 102 over it, 2.02\u00D7 the bar. This is length, not branching: a long straight-line body scores low on complexity and is still read whole to change any part of it, so the complexity numbers beside this row neither confirm nor excuse it. To reduce it, extract each cohesive step of the body \u2014 the runs of statements that work on the same values and would earn the same name \u2014 into its own named unit, and have this one call them in order."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/pages/SkillsPage.tsx"},"region":{"startLine":77}}}],"partialFingerprints":{"codehealthFindingId/v1":"88ce5ecc25c5b949fb236f69df6ba841ded18e01f3e595c57d835272fdfadc41"}},{"ruleId":"D3","level":"warning","message":{"text":"FunctionTooLong: EngineMetricsTab.EngineMetricsTab: FunctionTooLong \u2014 EngineMetricsTab runs 199 significant lines (blank, comment-only and punctuation-only lines excluded) in one body. The bar is 100 significant lines; this is 99 over it, 1.99\u00D7 the bar. This is length, not branching: a long straight-line body scores low on complexity and is still read whole to change any part of it, so the complexity numbers beside this row neither confirm nor excuse it. To reduce it, extract each cohesive step of the body \u2014 the runs of statements that work on the same values and would earn the same name \u2014 into its own named unit, and have this one call them in order."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/settings/EngineMetricsTab.tsx"},"region":{"startLine":54}}}],"partialFingerprints":{"codehealthFindingId/v1":"0f9ca7e15ab764ccedf689e564d8bd0918cab685ba605f18520305218c2b0a2a"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: hive/provisioner.py: FileTooLong \u2014 982 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 482 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":"backend/hive/provisioner.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"41bfad506f5ca70c47085f964e0e896818a6b0e9aa64b50edb51e423796328c2"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: scripts/loops_health_check.py: FileTooLong \u2014 982 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 482 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":"backend/skills/s_loops-health/scripts/loops_health_check.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"26559f23f9d91b3ef387f96b91e282a95356aac18c681514dfcb77ab6206a22a"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: core/streaming_orchestrator.py: FileTooLong \u2014 976 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 476 over it, 1.95\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":"backend/core/streaming_orchestrator.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"c0646b3c2ebcf874e50b6d6a05b56283f9f1095841a6a23349ccb14294edc3f8"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: core/eval_service.py: FileTooLong \u2014 967 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 467 over it, 1.93\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":"backend/core/eval_service.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"6d2c6c5017ea31e32a55982fed80c4401ac2af5709ba4b04e183ca1ce5bf57f5"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: layout/BrainHub.tsx: FileTooLong \u2014 964 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 464 over it, 1.93\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":"desktop/src/components/layout/BrainHub.tsx"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"167d4dafccdf8d3ce7165c840349f189779277c002810d52bc086536ff9f97c5"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: core/ddd_packager.py: FileTooLong \u2014 962 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 462 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":"backend/core/ddd_packager.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"ea2225a9895f239d627727239c09a97a54374aa9ecdc5cef5f62fb1485816279"}},{"ruleId":"D3","level":"warning","message":{"text":"FunctionTooLong: useUnifiedAttachments.useUnifiedAttachments: FunctionTooLong \u2014 useUnifiedAttachments runs 192 significant lines (blank, comment-only and punctuation-only lines excluded) in one body. The bar is 100 significant lines; this is 92 over it, 1.92\u00D7 the bar. This is length, not branching: a long straight-line body scores low on complexity and is still read whole to change any part of it, so the complexity numbers beside this row neither confirm nor excuse it. To reduce it, extract each cohesive step of the body \u2014 the runs of statements that work on the same values and would earn the same name \u2014 into its own named unit, and have this one call them in order."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/hooks/useUnifiedAttachments.ts"},"region":{"startLine":117}}}],"partialFingerprints":{"codehealthFindingId/v1":"03aeed47d30babc1c8fb1cd9e20a0daac6f7411c11ac4ee38bfa85f524315f6d"}},{"ruleId":"D3","level":"warning","message":{"text":"FunctionTooLong: useVoiceRecorder.useVoiceRecorder: FunctionTooLong \u2014 useVoiceRecorder runs 192 significant lines (blank, comment-only and punctuation-only lines excluded) in one body. The bar is 100 significant lines; this is 92 over it, 1.92\u00D7 the bar. This is length, not branching: a long straight-line body scores low on complexity and is still read whole to change any part of it, so the complexity numbers beside this row neither confirm nor excuse it. To reduce it, extract each cohesive step of the body \u2014 the runs of statements that work on the same values and would earn the same name \u2014 into its own named unit, and have this one call them in order."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/hooks/useVoiceRecorder.ts"},"region":{"startLine":48}}}],"partialFingerprints":{"codehealthFindingId/v1":"4c18ec008f5e1fe67588baf43a5a508f72eda0a81beee7edf6669b9bf37e347f"}},{"ruleId":"D3","level":"warning","message":{"text":"FunctionTooLong: KnowledgebasesTab.KnowledgebasesTab: FunctionTooLong \u2014 KnowledgebasesTab runs 190 significant lines (blank, comment-only and punctuation-only lines excluded) in one body. The bar is 100 significant lines; this is 90 over it, 1.90\u00D7 the bar. This is length, not branching: a long straight-line body scores low on complexity and is still read whole to change any part of it, so the complexity numbers beside this row neither confirm nor excuse it. To reduce it, extract each cohesive step of the body \u2014 the runs of statements that work on the same values and would earn the same name \u2014 into its own named unit, and have this one call them in order."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/workspace-settings/KnowledgebasesTab.tsx"},"region":{"startLine":23}}}],"partialFingerprints":{"codehealthFindingId/v1":"b2bc0de87331efd6a45acb36bef334d45bf9d1e309ba8b6ca5cca3a0a12f30db"}},{"ruleId":"D3","level":"warning","message":{"text":"FunctionTooLong: ExplorerToolbar.ExplorerToolbar: FunctionTooLong \u2014 ExplorerToolbar runs 188 significant lines (blank, comment-only and punctuation-only lines excluded) in one body. The bar is 100 significant lines; this is 88 over it, 1.88\u00D7 the bar. This is length, not branching: a long straight-line body scores low on complexity and is still read whole to change any part of it, so the complexity numbers beside this row neither confirm nor excuse it. To reduce it, extract each cohesive step of the body \u2014 the runs of statements that work on the same values and would earn the same name \u2014 into its own named unit, and have this one call them in order."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/workspace-explorer/ExplorerToolbar.tsx"},"region":{"startLine":34}}}],"partialFingerprints":{"codehealthFindingId/v1":"3044da96daa0e0cea519e13b1a649694b1a29434bf9214e56b85ba78a9f99247"}},{"ruleId":"D3","level":"warning","message":{"text":"FunctionTooLong: useHealthMonitor.useHealthMonitor: FunctionTooLong \u2014 useHealthMonitor runs 188 significant lines (blank, comment-only and punctuation-only lines excluded) in one body. The bar is 100 significant lines; this is 88 over it, 1.88\u00D7 the bar. This is length, not branching: a long straight-line body scores low on complexity and is still read whole to change any part of it, so the complexity numbers beside this row neither confirm nor excuse it. To reduce it, extract each cohesive step of the body \u2014 the runs of statements that work on the same values and would earn the same name \u2014 into its own named unit, and have this one call them in order."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/hooks/useHealthMonitor.ts"},"region":{"startLine":134}}}],"partialFingerprints":{"codehealthFindingId/v1":"78be8a899bd56abf411ed59a592dc279538a088254c8799e29e847fcad82f110"}},{"ruleId":"D3","level":"warning","message":{"text":"FunctionTooLong: MultiSelect.MultiSelect: FunctionTooLong \u2014 MultiSelect runs 185 significant lines (blank, comment-only and punctuation-only lines excluded) in one body. The bar is 100 significant lines; this is 85 over it, 1.85\u00D7 the bar. This is length, not branching: a long straight-line body scores low on complexity and is still read whole to change any part of it, so the complexity numbers beside this row neither confirm nor excuse it. To reduce it, extract each cohesive step of the body \u2014 the runs of statements that work on the same values and would earn the same name \u2014 into its own named unit, and have this one call them in order."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/common/MultiSelect.tsx"},"region":{"startLine":25}}}],"partialFingerprints":{"codehealthFindingId/v1":"6f825f8936c57aa70070d4343ef3c54da74f13eff9313a251ccc8c225fbbb37f"}},{"ruleId":"D3","level":"warning","message":{"text":"TooManyMethods: SessionUnit: TooManyMethods \u2014 55 methods. The bar is 30 methods; this is 25 over it, 1.83\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":"backend/core/session_unit.py"},"region":{"startLine":452}}}],"partialFingerprints":{"codehealthFindingId/v1":"4678b74fcf2901c2f5640a69fd245267db858b7d854096a21fdaf490314a9dea"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: core/ddd_entry_lifecycle.py: FileTooLong \u2014 912 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 412 over it, 1.82\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":"backend/core/ddd_entry_lifecycle.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"98b7089e6937ffd4053e5616bff8e4a993d6673a1401f5c999fda9ed7489cffd"}},{"ruleId":"D3","level":"warning","message":{"text":"FunctionTooLong: AskUserQuestion.AskUserQuestion: FunctionTooLong \u2014 AskUserQuestion runs 180 significant lines (blank, comment-only and punctuation-only lines excluded) in one body. The bar is 100 significant lines; this is 80 over it, 1.80\u00D7 the bar. This is length, not branching: a long straight-line body scores low on complexity and is still read whole to change any part of it, so the complexity numbers beside this row neither confirm nor excuse it. To reduce it, extract each cohesive step of the body \u2014 the runs of statements that work on the same values and would earn the same name \u2014 into its own named unit, and have this one call them in order."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/common/AskUserQuestion.tsx"},"region":{"startLine":19}}}],"partialFingerprints":{"codehealthFindingId/v1":"84ed728ad487e7dba5200eab21f3133a832995f78c6ed853248987a2755b313f"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: core/prompt_builder.py: FileTooLong \u2014 897 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 397 over it, 1.79\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":"backend/core/prompt_builder.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"ab4f74e56dc58d23849b370e1095b35e732c67e134c275915dbff168c2c0eef3"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: layout/ToDoOverlay.tsx: FileTooLong \u2014 897 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 397 over it, 1.79\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":"desktop/src/components/layout/ToDoOverlay.tsx"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"764603ffeebb9c30eb5e8ba15732dbdd09d6303fb8d27494f2d2fe3ce0b6089a"}},{"ruleId":"D3","level":"warning","message":{"text":"FunctionTooLong: ToDoOverlay.ToDoContent: FunctionTooLong \u2014 ToDoContent runs 178 significant lines (blank, comment-only and punctuation-only lines excluded) in one body. The bar is 100 significant lines; this is 78 over it, 1.78\u00D7 the bar. This is length, not branching: a long straight-line body scores low on complexity and is still read whole to change any part of it, so the complexity numbers beside this row neither confirm nor excuse it. To reduce it, extract each cohesive step of the body \u2014 the runs of statements that work on the same values and would earn the same name \u2014 into its own named unit, and have this one call them in order."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/layout/ToDoOverlay.tsx"},"region":{"startLine":195}}}],"partialFingerprints":{"codehealthFindingId/v1":"23d783a4385c89edc06be71d75b2c1846c40e4211c91dd1b9424955d2e6c5418"}},{"ruleId":"D3","level":"warning","message":{"text":"FunctionTooLong: BackupTab.BackupTab: FunctionTooLong \u2014 BackupTab runs 178 significant lines (blank, comment-only and punctuation-only lines excluded) in one body. The bar is 100 significant lines; this is 78 over it, 1.78\u00D7 the bar. This is length, not branching: a long straight-line body scores low on complexity and is still read whole to change any part of it, so the complexity numbers beside this row neither confirm nor excuse it. To reduce it, extract each cohesive step of the body \u2014 the runs of statements that work on the same values and would earn the same name \u2014 into its own named unit, and have this one call them in order."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/settings/BackupTab.tsx"},"region":{"startLine":15}}}],"partialFingerprints":{"codehealthFindingId/v1":"0aef028f6216626bde29e7a23db2495cafa9950da2a15895211fe20da6194cbb"}},{"ruleId":"D3","level":"warning","message":{"text":"FunctionTooLong: streaming-machine.streamingReducer: FunctionTooLong \u2014 streamingReducer runs 177 significant lines (blank, comment-only and punctuation-only lines excluded) in one body. The bar is 100 significant lines; this is 77 over it, 1.77\u00D7 the bar. This is length, not branching: a long straight-line body scores low on complexity and is still read whole to change any part of it, so the complexity numbers beside this row neither confirm nor excuse it. To reduce it, extract each cohesive step of the body \u2014 the runs of statements that work on the same values and would earn the same name \u2014 into its own named unit, and have this one call them in order."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/hooks/streaming-machine.ts"},"region":{"startLine":110}}}],"partialFingerprints":{"codehealthFindingId/v1":"8474fcf72b9afc91247346f1e241b01dc220ab5c21cd16d1989f411e7f503b0b"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: layout/CMBrainOverlay.tsx: FileTooLong \u2014 877 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 377 over it, 1.75\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":"desktop/src/components/layout/CMBrainOverlay.tsx"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"f4b9a62947c20018dae606e44a50f811730fc4e4464e57c9a82396cf17da6e99"}},{"ruleId":"D3","level":"warning","message":{"text":"FunctionTooLong: ExplorerContext.ExplorerProvider: FunctionTooLong \u2014 ExplorerProvider runs 175 significant lines (blank, comment-only and punctuation-only lines excluded) in one body. The bar is 100 significant lines; this is 75 over it, 1.75\u00D7 the bar. This is length, not branching: a long straight-line body scores low on complexity and is still read whole to change any part of it, so the complexity numbers beside this row neither confirm nor excuse it. To reduce it, extract each cohesive step of the body \u2014 the runs of statements that work on the same values and would earn the same name \u2014 into its own named unit, and have this one call them in order."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/contexts/ExplorerContext.tsx"},"region":{"startLine":369}}}],"partialFingerprints":{"codehealthFindingId/v1":"6e49bc58425b66cc4c4be025f549302e51917e6a3f11db934fed1ecc12b3041d"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: core/runtime_hooks.py: FileTooLong \u2014 868 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 368 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":"backend/core/runtime_hooks.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"45102b8466e97bc89cdca44ed6f418717a0157fe4da5e128746117501e3df800"}},{"ruleId":"D3","level":"warning","message":{"text":"FunctionTooLong: EvalDashboard.ContextHealthTab: FunctionTooLong \u2014 ContextHealthTab runs 173 significant lines (blank, comment-only and punctuation-only lines excluded) in one body. The bar is 100 significant lines; this is 73 over it, 1.73\u00D7 the bar. This is length, not branching: a long straight-line body scores low on complexity and is still read whole to change any part of it, so the complexity numbers beside this row neither confirm nor excuse it. To reduce it, extract each cohesive step of the body \u2014 the runs of statements that work on the same values and would earn the same name \u2014 into its own named unit, and have this one call them in order."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/pages/EvalDashboard.tsx"},"region":{"startLine":1084}}}],"partialFingerprints":{"codehealthFindingId/v1":"315b915c2d557780db7f1cc3ba485a6b2d568d930017a89b8ae6aeea6de72028"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: routers/chat.py: FileTooLong \u2014 857 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 357 over it, 1.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":"backend/routers/chat.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"a05f798c813b52ffad8ae4d236c5d85be73faf1da275e3e698a666bcee1036a0"}},{"ruleId":"D3","level":"warning","message":{"text":"FunctionTooLong: useVoiceConversation.useVoiceConversation: FunctionTooLong \u2014 useVoiceConversation runs 171 significant lines (blank, comment-only and punctuation-only lines excluded) in one body. The bar is 100 significant lines; this is 71 over it, 1.71\u00D7 the bar. This is length, not branching: a long straight-line body scores low on complexity and is still read whole to change any part of it, so the complexity numbers beside this row neither confirm nor excuse it. To reduce it, extract each cohesive step of the body \u2014 the runs of statements that work on the same values and would earn the same name \u2014 into its own named unit, and have this one call them in order."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/hooks/useVoiceConversation.ts"},"region":{"startLine":75}}}],"partialFingerprints":{"codehealthFindingId/v1":"bd8d842850d752e35a645fb4886ddf33a566d676df7dd12bc17f1a3c5feeb0db"}},{"ruleId":"D3","level":"warning","message":{"text":"TooManyMethods: EvalService: TooManyMethods \u2014 51 methods. The bar is 30 methods; this is 21 over it, 1.70\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":"backend/core/eval_service.py"},"region":{"startLine":37}}}],"partialFingerprints":{"codehealthFindingId/v1":"05e25e86c7452be2a78333434fc56f54c219ba27315474e081fbde2ec5406e83"}},{"ruleId":"D3","level":"warning","message":{"text":"FunctionTooLong: PipelineOverlay.PipelineContent: FunctionTooLong \u2014 PipelineContent runs 170 significant lines (blank, comment-only and punctuation-only lines excluded) in one body. The bar is 100 significant lines; this is 70 over it, 1.70\u00D7 the bar. This is length, not branching: a long straight-line body scores low on complexity and is still read whole to change any part of it, so the complexity numbers beside this row neither confirm nor excuse it. To reduce it, extract each cohesive step of the body \u2014 the runs of statements that work on the same values and would earn the same name \u2014 into its own named unit, and have this one call them in order."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/layout/PipelineOverlay.tsx"},"region":{"startLine":89}}}],"partialFingerprints":{"codehealthFindingId/v1":"d455146f7611b4fdb161dc95ad18a67bb447b76de169491fadeb2a9c9d45d4fb"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: routers/workspace_api.py: FileTooLong \u2014 849 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 349 over it, 1.70\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":"backend/routers/workspace_api.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"060bfc0a41d793035732f98572f87c7984a3d9b41040f0c6e00477b7bf8dc86d"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: scripts/design_system.py: FileTooLong \u2014 848 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 348 over it, 1.70\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":"backend/skills/s_frontend-design/scripts/design_system.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"0ae6fe51e9ba82fa5709483f84eb5ec72ff4353b25a2cbfb2044711d63a500f5"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: core/context_injector.py: FileTooLong \u2014 815 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 315 over it, 1.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":"backend/core/context_injector.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"0dcb7e6d6657240a2e7606fb64b88f3a2d1ee880bd64031cee0d73b7780e086d"}},{"ruleId":"D3","level":"warning","message":{"text":"FunctionTooLong: PollinateOverlay.AssetDrawer: FunctionTooLong \u2014 AssetDrawer runs 163 significant lines (blank, comment-only and punctuation-only lines excluded) in one body. The bar is 100 significant lines; this is 63 over it, 1.63\u00D7 the bar. This is length, not branching: a long straight-line body scores low on complexity and is still read whole to change any part of it, so the complexity numbers beside this row neither confirm nor excuse it. To reduce it, extract each cohesive step of the body \u2014 the runs of statements that work on the same values and would earn the same name \u2014 into its own named unit, and have this one call them in order."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/layout/PollinateOverlay.tsx"},"region":{"startLine":494}}}],"partialFingerprints":{"codehealthFindingId/v1":"96e0f74b6f8d7d940aaa02b25bbeec14b026aa1efb77333b886eec6de7ec9290"}},{"ruleId":"D3","level":"warning","message":{"text":"FunctionTooLong: OverlayHost.OverlayHost: FunctionTooLong \u2014 OverlayHost runs 161 significant lines (blank, comment-only and punctuation-only lines excluded) in one body. The bar is 100 significant lines; this is 61 over it, 1.61\u00D7 the bar. This is length, not branching: a long straight-line body scores low on complexity and is still read whole to change any part of it, so the complexity numbers beside this row neither confirm nor excuse it. To reduce it, extract each cohesive step of the body \u2014 the runs of statements that work on the same values and would earn the same name \u2014 into its own named unit, and have this one call them in order."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/layout/OverlayHost.tsx"},"region":{"startLine":58}}}],"partialFingerprints":{"codehealthFindingId/v1":"4edf69b83d30adfefa541b1c5a70a2a749ba88a4e05b9fd3478dad67b9c3d29e"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: types/index.ts: FileTooLong \u2014 802 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 302 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":"desktop/src/types/index.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"5723e2602c8c90ede4c1fe0dd8790283773038e307b981ecc587f5a1b087da38"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: pages/SkillsPage.tsx: FileTooLong \u2014 799 significant lines (blank, comment-only and punctuation-only lines excluded), about 63% of them inside a single declaration: GenerateSkillForm (327-1009). The bar is 500 significant lines; this is 299 over it, 1.60\u00D7 the bar. Moving the declarations that sit BESIDE it into sibling files will not shorten this file. Extract from INSIDE that declaration instead: lift each cohesive group of its body \u2014 the parts that share the same inputs and are named together \u2014 into its own unit in a sibling file, and have the original call them."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/pages/SkillsPage.tsx"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"5fca54171e0853139c3f99fef4a8f907a38d85919e41a17cd45b1a48c71dd978"}},{"ruleId":"D3","level":"warning","message":{"text":"FunctionTooLong: swarmai::spawn_daemon_health_watchdog: FunctionTooLong \u2014 swarmai::spawn_daemon_health_watchdog runs 159 significant lines (blank, comment-only and punctuation-only lines excluded, and inline test code \u2014 #[cfg(test)] modules and bare #[test] functions \u2014 not counted) in one body. The bar is 100 significant lines; this is 59 over it, 1.59\u00D7 the bar. This is length, not branching: a long straight-line body scores low on complexity and is still read whole to change any part of it, so the complexity numbers beside this row neither confirm nor excuse it. To reduce it, extract each cohesive step of the body \u2014 the runs of statements that work on the same values and would earn the same name \u2014 into its own named unit, and have this one call them in order."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src-tauri/src/lib.rs"},"region":{"startLine":1856}}}],"partialFingerprints":{"codehealthFindingId/v1":"85a9efc591747a29b44006e5007b6f33bf9c4e00db391fcbec5a15e3cc0e6baf"}},{"ruleId":"D3","level":"warning","message":{"text":"FunctionTooLong: EvalDashboard.CaseDetailDrawer: FunctionTooLong \u2014 CaseDetailDrawer runs 159 significant lines (blank, comment-only and punctuation-only lines excluded) in one body. The bar is 100 significant lines; this is 59 over it, 1.59\u00D7 the bar. This is length, not branching: a long straight-line body scores low on complexity and is still read whole to change any part of it, so the complexity numbers beside this row neither confirm nor excuse it. To reduce it, extract each cohesive step of the body \u2014 the runs of statements that work on the same values and would earn the same name \u2014 into its own named unit, and have this one call them in order."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/pages/EvalDashboard.tsx"},"region":{"startLine":2191}}}],"partialFingerprints":{"codehealthFindingId/v1":"25b7006bdd45faac5619fc3f8111c9d2bc89a334d2c5e48e72428611e2390a1d"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: routers/system.py: FileTooLong \u2014 785 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 285 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":"backend/routers/system.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"9f291677530da38c9ab72bf563d8cc4c7786f21cbb19f3542f387706dd879721"}},{"ruleId":"D3","level":"warning","message":{"text":"TooManyMethods: ContextHealthHook: 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":"backend/hooks/context_health_hook.py"},"region":{"startLine":128}}}],"partialFingerprints":{"codehealthFindingId/v1":"bd7e3d766a87f2e5b89f59b20ac6d786e23c97b8d8ff20b8f423eae90a0b028f"}},{"ruleId":"D3","level":"warning","message":{"text":"FunctionTooLong: HistoryView.HistoryView: FunctionTooLong \u2014 HistoryView runs 154 significant lines (blank, comment-only and punctuation-only lines excluded) in one body. The bar is 100 significant lines; this is 54 over it, 1.54\u00D7 the bar. This is length, not branching: a long straight-line body scores low on complexity and is still read whole to change any part of it, so the complexity numbers beside this row neither confirm nor excuse it. To reduce it, extract each cohesive step of the body \u2014 the runs of statements that work on the same values and would earn the same name \u2014 into its own named unit, and have this one call them in order."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/pages/chat/components/RightSidebar/HistoryView.tsx"},"region":{"startLine":34}}}],"partialFingerprints":{"codehealthFindingId/v1":"2acc544c24f08f54566ebe988b3cb4611f613a296f6509fc03e82ff23f90fd8d"}},{"ruleId":"D3","level":"warning","message":{"text":"FunctionTooLong: FilePreviewModal.FilePreviewModal: FunctionTooLong \u2014 FilePreviewModal runs 149 significant lines (blank, comment-only and punctuation-only lines excluded) in one body. The bar is 100 significant lines; this is 49 over it, 1.49\u00D7 the bar. This is length, not branching: a long straight-line body scores low on complexity and is still read whole to change any part of it, so the complexity numbers beside this row neither confirm nor excuse it. To reduce it, extract each cohesive step of the body \u2014 the runs of statements that work on the same values and would earn the same name \u2014 into its own named unit, and have this one call them in order."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/workspace/FilePreviewModal.tsx"},"region":{"startLine":48}}}],"partialFingerprints":{"codehealthFindingId/v1":"7764fc052194634100cdc854a4226ff16e84d54dcc1038bf43819d123e042c56"}},{"ruleId":"D3","level":"warning","message":{"text":"FunctionTooLong: AboutTab.AboutTab: FunctionTooLong \u2014 AboutTab runs 148 significant lines (blank, comment-only and punctuation-only lines excluded) in one body. The bar is 100 significant lines; this is 48 over it, 1.48\u00D7 the bar. This is length, not branching: a long straight-line body scores low on complexity and is still read whole to change any part of it, so the complexity numbers beside this row neither confirm nor excuse it. To reduce it, extract each cohesive step of the body \u2014 the runs of statements that work on the same values and would earn the same name \u2014 into its own named unit, and have this one call them in order."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/settings/AboutTab.tsx"},"region":{"startLine":26}}}],"partialFingerprints":{"codehealthFindingId/v1":"56cec1449e886fe3e59e91a22f6f4b086cd5bf124014698fe41b877667be51c2"}},{"ruleId":"D3","level":"warning","message":{"text":"TooManyMethods: SwarmWorkspaceManager: TooManyMethods \u2014 44 methods. The bar is 30 methods; this is 14 over it, 1.47\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":"backend/core/swarm_workspace_manager.py"},"region":{"startLine":873}}}],"partialFingerprints":{"codehealthFindingId/v1":"3ec24bcb140c12fb9a72b46a725e786104afc8f33587f273d8edfd5b8c8c4986"}},{"ruleId":"D3","level":"warning","message":{"text":"FunctionTooLong: CodeGraph.CodeGraph: FunctionTooLong \u2014 CodeGraph runs 145 significant lines (blank, comment-only and punctuation-only lines excluded) in one body. The bar is 100 significant lines; this is 45 over it, 1.45\u00D7 the bar. This is length, not branching: a long straight-line body scores low on complexity and is still read whole to change any part of it, so the complexity numbers beside this row neither confirm nor excuse it. To reduce it, extract each cohesive step of the body \u2014 the runs of statements that work on the same values and would earn the same name \u2014 into its own named unit, and have this one call them in order."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/code-intel/CodeGraph.tsx"},"region":{"startLine":76}}}],"partialFingerprints":{"codehealthFindingId/v1":"b25bca8e8e1f717f991d35e503389f13fb81eab76a27c7b39508be0cb06cac33"}},{"ruleId":"D3","level":"warning","message":{"text":"FunctionTooLong: UpdateNotification.UpdateNotification: FunctionTooLong \u2014 UpdateNotification runs 145 significant lines (blank, comment-only and punctuation-only lines excluded) in one body. The bar is 100 significant lines; this is 45 over it, 1.45\u00D7 the bar. This is length, not branching: a long straight-line body scores low on complexity and is still read whole to change any part of it, so the complexity numbers beside this row neither confirm nor excuse it. To reduce it, extract each cohesive step of the body \u2014 the runs of statements that work on the same values and would earn the same name \u2014 into its own named unit, and have this one call them in order."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/common/UpdateNotification.tsx"},"region":{"startLine":16}}}],"partialFingerprints":{"codehealthFindingId/v1":"4fa537b69526f26a5d21cd17625b667704c93ddad33de1cef7047479d118ece9"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: components/ChatInput.tsx: FileTooLong \u2014 724 significant lines (blank, comment-only and punctuation-only lines excluded), about 90% of them inside a single declaration: MAX_ROWS (150-1111). The bar is 500 significant lines; this is 224 over it, 1.45\u00D7 the bar. Moving the declarations that sit BESIDE it into sibling files will not shorten this file. Extract from INSIDE that declaration instead: lift each cohesive group of its body \u2014 the parts that share the same inputs and are named together \u2014 into its own unit in a sibling file, and have the original call them."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/pages/chat/components/ChatInput.tsx"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"1b4105756b5809b8823c6ff2a2e467a46806f6f41545240cc92b5dfd23de7b83"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: handlers/memory_health.py: FileTooLong \u2014 712 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 212 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":"backend/jobs/handlers/memory_health.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"603f69fc57cc497d09d58a8dc679b8c2ba431b7417b63987ef172b7c706028d9"}},{"ruleId":"D3","level":"warning","message":{"text":"FunctionTooLong: CommentPopover.CommentPopover: FunctionTooLong \u2014 CommentPopover runs 142 significant lines (blank, comment-only and punctuation-only lines excluded) in one body. The bar is 100 significant lines; this is 42 over it, 1.42\u00D7 the bar. This is length, not branching: a long straight-line body scores low on complexity and is still read whole to change any part of it, so the complexity numbers beside this row neither confirm nor excuse it. To reduce it, extract each cohesive step of the body \u2014 the runs of statements that work on the same values and would earn the same name \u2014 into its own named unit, and have this one call them in order."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/common/CommentPopover.tsx"},"region":{"startLine":34}}}],"partialFingerprints":{"codehealthFindingId/v1":"199e2cc299a2aa3a8c5e5208b4ec4bced047b93f79735145fc07cc23eae442a3"}},{"ruleId":"D3","level":"warning","message":{"text":"FunctionTooLong: HtmlRenderer.HtmlRenderer: FunctionTooLong \u2014 HtmlRenderer runs 140 significant lines (blank, comment-only and punctuation-only lines excluded) in one body. The bar is 100 significant lines; this is 40 over it, 1.40\u00D7 the bar. This is length, not branching: a long straight-line body scores low on complexity and is still read whole to change any part of it, so the complexity numbers beside this row neither confirm nor excuse it. To reduce it, extract each cohesive step of the body \u2014 the runs of statements that work on the same values and would earn the same name \u2014 into its own named unit, and have this one call them in order."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/file-viewer/renderers/HtmlRenderer.tsx"},"region":{"startLine":94}}}],"partialFingerprints":{"codehealthFindingId/v1":"0f60ac0e0b6c91e4e1c1c0cf13b1b01cdd735ebeb82a6ffd88c284bc24cc6ae7"}},{"ruleId":"D3","level":"warning","message":{"text":"FunctionTooLong: FileBrowser.FileBrowser: FunctionTooLong \u2014 FileBrowser runs 138 significant lines (blank, comment-only and punctuation-only lines excluded) in one body. The bar is 100 significant lines; this is 38 over it, 1.38\u00D7 the bar. This is length, not branching: a long straight-line body scores low on complexity and is still read whole to change any part of it, so the complexity numbers beside this row neither confirm nor excuse it. To reduce it, extract each cohesive step of the body \u2014 the runs of statements that work on the same values and would earn the same name \u2014 into its own named unit, and have this one call them in order."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/workspace/FileBrowser.tsx"},"region":{"startLine":99}}}],"partialFingerprints":{"codehealthFindingId/v1":"d4aec543149ecdfa1c3e878b908c9024cf9ef9c5681e3d0e775df21ed8a52723"}},{"ruleId":"D3","level":"warning","message":{"text":"TooManyMethods: LifecycleManager: TooManyMethods \u2014 41 methods. The bar is 30 methods; this is 11 over it, 1.37\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":"backend/core/lifecycle_manager.py"},"region":{"startLine":46}}}],"partialFingerprints":{"codehealthFindingId/v1":"3e50a5440c74f3d0cb5dcf0e195652f943a6aff2a31940c0c56b4eac58d7da41"}},{"ruleId":"D3","level":"warning","message":{"text":"FunctionTooLong: ImageRenderer.ImageRenderer: FunctionTooLong \u2014 ImageRenderer runs 136 significant lines (blank, comment-only and punctuation-only lines excluded) in one body. The bar is 100 significant lines; this is 36 over it, 1.36\u00D7 the bar. This is length, not branching: a long straight-line body scores low on complexity and is still read whole to change any part of it, so the complexity numbers beside this row neither confirm nor excuse it. To reduce it, extract each cohesive step of the body \u2014 the runs of statements that work on the same values and would earn the same name \u2014 into its own named unit, and have this one call them in order."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/file-viewer/renderers/ImageRenderer.tsx"},"region":{"startLine":30}}}],"partialFingerprints":{"codehealthFindingId/v1":"5124ff3813e6c0b2ad3acd3f64d6d9f82a6afb5dff7d070eee7fa0a3899b3df8"}},{"ruleId":"D3","level":"warning","message":{"text":"FunctionTooLong: useCanvasHost.useCanvasHost: FunctionTooLong \u2014 useCanvasHost runs 136 significant lines (blank, comment-only and punctuation-only lines excluded) in one body. The bar is 100 significant lines; this is 36 over it, 1.36\u00D7 the bar. This is length, not branching: a long straight-line body scores low on complexity and is still read whole to change any part of it, so the complexity numbers beside this row neither confirm nor excuse it. To reduce it, extract each cohesive step of the body \u2014 the runs of statements that work on the same values and would earn the same name \u2014 into its own named unit, and have this one call them in order."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/hooks/useCanvasHost.ts"},"region":{"startLine":148}}}],"partialFingerprints":{"codehealthFindingId/v1":"0e7cc285a53450ae2bd6e69df0718dbb224ea8b6edfe188002755398fd66d342"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: scripts/document.py: FileTooLong \u2014 672 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 172 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":"backend/skills/s_docx/scripts/document.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"ce7447c4401cfbefe15a39e93fcef5c0ac144a96b566aad4a1f4b4365a439581"}},{"ruleId":"D3","level":"warning","message":{"text":"TooManyMethods: SlackChannelAdapter: 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":"backend/channels/adapters/slack.py"},"region":{"startLine":399}}}],"partialFingerprints":{"codehealthFindingId/v1":"efcdbde7694a5657ba29f41a7f837aa5345744d38a7c071f721b65a6540ac0d2"}},{"ruleId":"D3","level":"warning","message":{"text":"TooManyMethods: GraphStore: 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":"backend/core/code_intel/graph_store.py"},"region":{"startLine":271}}}],"partialFingerprints":{"codehealthFindingId/v1":"e19178e5ee764ea8c9655f0425043ea28f34ca61cf823b36f8e203079d21d4f9"}},{"ruleId":"D3","level":"warning","message":{"text":"ClassTooLong: MessageStore: ClassTooLong \u2014 533 significant lines (blank, comment-only and punctuation-only lines excluded), 39 methods. The bar is 400 significant lines; this is 133 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":"desktop/src/stores/MessageStore.ts"},"region":{"startLine":64}}}],"partialFingerprints":{"codehealthFindingId/v1":"f7b27960b8239587b5b3c28acd805c9665c80ceff9553fdebd414fdaf256c5da"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: core/plugin_manager.py: FileTooLong \u2014 661 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 161 over it, 1.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":"backend/core/plugin_manager.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"f09b5913ab8f9da85034abe120573c0b74d44373f5b6b522fc48ddfb4e665172"}},{"ruleId":"D3","level":"warning","message":{"text":"FunctionTooLong: UnsupportedRenderer.UnsupportedRenderer: FunctionTooLong \u2014 UnsupportedRenderer runs 131 significant lines (blank, comment-only and punctuation-only lines excluded) in one body. The bar is 100 significant lines; this is 31 over it, 1.31\u00D7 the bar. This is length, not branching: a long straight-line body scores low on complexity and is still read whole to change any part of it, so the complexity numbers beside this row neither confirm nor excuse it. To reduce it, extract each cohesive step of the body \u2014 the runs of statements that work on the same values and would earn the same name \u2014 into its own named unit, and have this one call them in order."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/file-viewer/renderers/UnsupportedRenderer.tsx"},"region":{"startLine":115}}}],"partialFingerprints":{"codehealthFindingId/v1":"1a42d113b69a94a8c77a95c1974c8224c398c98735bc262be83afeea97ac3eef"}},{"ruleId":"D3","level":"warning","message":{"text":"TooManyMethods: MessageStore: TooManyMethods \u2014 39 methods. The bar is 30 methods; this is 9 over it, 1.30\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":"desktop/src/stores/MessageStore.ts"},"region":{"startLine":64}}}],"partialFingerprints":{"codehealthFindingId/v1":"d9f53b47b2415765a1bab3b91495ace048fb235fbbe4bcd67254e1627949d5fe"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: handlers/swarmai_monthly_report.py: FileTooLong \u2014 643 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 143 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":"backend/jobs/handlers/swarmai_monthly_report.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"d978fe042e96c0cb5e909992c6036cb0b9fa52f5a6f51ee1708ef8e81c92b390"}},{"ruleId":"D3","level":"warning","message":{"text":"FunctionTooLong: Dropdown.Dropdown: FunctionTooLong \u2014 Dropdown runs 128 significant lines (blank, comment-only and punctuation-only lines excluded) in one body. The bar is 100 significant lines; this is 28 over it, 1.28\u00D7 the bar. This is length, not branching: a long straight-line body scores low on complexity and is still read whole to change any part of it, so the complexity numbers beside this row neither confirm nor excuse it. To reduce it, extract each cohesive step of the body \u2014 the runs of statements that work on the same values and would earn the same name \u2014 into its own named unit, and have this one call them in order."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/common/Dropdown.tsx"},"region":{"startLine":22}}}],"partialFingerprints":{"codehealthFindingId/v1":"eb661da23b98188d223eb35743289ac776b5409c6709284cba220c897b7bc27d"}},{"ruleId":"D3","level":"warning","message":{"text":"FunctionTooLong: MergedToolBlock.MergedToolBlock: FunctionTooLong \u2014 MergedToolBlock runs 127 significant lines (blank, comment-only and punctuation-only lines excluded) in one body. The bar is 100 significant lines; this is 27 over it, 1.27\u00D7 the bar. This is length, not branching: a long straight-line body scores low on complexity and is still read whole to change any part of it, so the complexity numbers beside this row neither confirm nor excuse it. To reduce it, extract each cohesive step of the body \u2014 the runs of statements that work on the same values and would earn the same name \u2014 into its own named unit, and have this one call them in order."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/pages/chat/components/MergedToolBlock.tsx"},"region":{"startLine":122}}}],"partialFingerprints":{"codehealthFindingId/v1":"202fd63455266f666b91b869b89b49f7077410de3a34757bee50e1449490fd38"}},{"ruleId":"D3","level":"warning","message":{"text":"TooManyMethods: DistillationTriggerHook: 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":"backend/hooks/distillation_hook.py"},"region":{"startLine":275}}}],"partialFingerprints":{"codehealthFindingId/v1":"eb9cc468c2a180b5b4217594724e26dad421e1dbb46f0771a558728d75d402d2"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: layout/ThreeColumnLayout.tsx: FileTooLong \u2014 629 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 129 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":"desktop/src/components/layout/ThreeColumnLayout.tsx"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"fbfcb169429c559ddd772a84a47b80c56e786815cfd5e3c21f88ea58192443a3"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: workspace-explorer/VirtualizedTree.tsx: 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":"desktop/src/components/workspace-explorer/VirtualizedTree.tsx"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"c53056604f29461844878d354c53fc3f43ac6896070e5a21e0befb9ea8a13245"}},{"ruleId":"D3","level":"warning","message":{"text":"FunctionTooLong: PipelineOverlay.RunDetailDrawer: FunctionTooLong \u2014 RunDetailDrawer runs 125 significant lines (blank, comment-only and punctuation-only lines excluded) in one body. The bar is 100 significant lines; this is 25 over it, 1.25\u00D7 the bar. This is length, not branching: a long straight-line body scores low on complexity and is still read whole to change any part of it, so the complexity numbers beside this row neither confirm nor excuse it. To reduce it, extract each cohesive step of the body \u2014 the runs of statements that work on the same values and would earn the same name \u2014 into its own named unit, and have this one call them in order."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/layout/PipelineOverlay.tsx"},"region":{"startLine":447}}}],"partialFingerprints":{"codehealthFindingId/v1":"a91d6d90a6f7eb16778e9bd63f9136f63d74633f47d98844b4b83b5a6db444a9"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: code_intel/graph_store.py: FileTooLong \u2014 624 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 124 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":"backend/core/code_intel/graph_store.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"c181349985df4b479d14ea8800dc83bede52fd8238b614ba0e37addfe30b2cee"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: hooks/evolution_maintenance_hook.py: FileTooLong \u2014 622 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 122 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":"backend/hooks/evolution_maintenance_hook.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"fb530382060c23ab41108527e070d151f8d46dc914d65b90bd23eb9be6c64c43"}},{"ruleId":"D3","level":"warning","message":{"text":"FunctionTooLong: HistoryOverlay.HistoryContent: FunctionTooLong \u2014 HistoryContent runs 124 significant lines (blank, comment-only and punctuation-only lines excluded) in one body. The bar is 100 significant lines; this is 24 over it, 1.24\u00D7 the bar. This is length, not branching: a long straight-line body scores low on complexity and is still read whole to change any part of it, so the complexity numbers beside this row neither confirm nor excuse it. To reduce it, extract each cohesive step of the body \u2014 the runs of statements that work on the same values and would earn the same name \u2014 into its own named unit, and have this one call them in order."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/layout/HistoryOverlay.tsx"},"region":{"startLine":59}}}],"partialFingerprints":{"codehealthFindingId/v1":"d0e1a4b6adecefd7f314a2270914f57f525544d9fb85690deca3ec7e0831bf40"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: common/MarkdownRenderer.tsx: FileTooLong \u2014 617 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 117 over it, 1.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":"desktop/src/components/common/MarkdownRenderer.tsx"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"da5733fa2bbf7ad23a5474e63313285daa0fd713bfb62d959f81291e592fc8a3"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: layout/PollinateOverlay.tsx: FileTooLong \u2014 614 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 114 over it, 1.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":"desktop/src/components/layout/PollinateOverlay.tsx"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"97c071a4761187557e275e9414f7556ffa83ac1e15a86f29a7ef2574c9f0a9ec"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: core/recall_multi.py: FileTooLong \u2014 613 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 113 over it, 1.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":"backend/core/recall_multi.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"1caedf0fec6e41227f2b91937af99f4924e9e5de6e3afa37fe9e4fab05ef1de3"}},{"ruleId":"D3","level":"warning","message":{"text":"FunctionTooLong: swarmai::sync_daemon_version: FunctionTooLong \u2014 swarmai::sync_daemon_version runs 122 significant lines (blank, comment-only and punctuation-only lines excluded, and inline test code \u2014 #[cfg(test)] modules and bare #[test] functions \u2014 not counted) in one body. The bar is 100 significant lines; this is 22 over it, 1.22\u00D7 the bar. This is length, not branching: a long straight-line body scores low on complexity and is still read whole to change any part of it, so the complexity numbers beside this row neither confirm nor excuse it. To reduce it, extract each cohesive step of the body \u2014 the runs of statements that work on the same values and would earn the same name \u2014 into its own named unit, and have this one call them in order."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src-tauri/src/lib.rs"},"region":{"startLine":1130}}}],"partialFingerprints":{"codehealthFindingId/v1":"b3a1e29a23a4c0cf042fed8cc1429bba5bbef3efc4e9923542bb0cb38d0ae06d"}},{"ruleId":"D3","level":"warning","message":{"text":"FunctionTooLong: ToolSelector.ToolSelector: FunctionTooLong \u2014 ToolSelector runs 122 significant lines (blank, comment-only and punctuation-only lines excluded) in one body. The bar is 100 significant lines; this is 22 over it, 1.22\u00D7 the bar. This is length, not branching: a long straight-line body scores low on complexity and is still read whole to change any part of it, so the complexity numbers beside this row neither confirm nor excuse it. To reduce it, extract each cohesive step of the body \u2014 the runs of statements that work on the same values and would earn the same name \u2014 into its own named unit, and have this one call them in order."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/common/ToolSelector.tsx"},"region":{"startLine":112}}}],"partialFingerprints":{"codehealthFindingId/v1":"dcd06c4f85aa3a07ef6b9c381bb9405027f19b0024ff4913db64196dff5e8961"}},{"ruleId":"D3","level":"warning","message":{"text":"FunctionTooLong: ToDoOverlay.DetailDrawer: FunctionTooLong \u2014 DetailDrawer runs 122 significant lines (blank, comment-only and punctuation-only lines excluded) in one body. The bar is 100 significant lines; this is 22 over it, 1.22\u00D7 the bar. This is length, not branching: a long straight-line body scores low on complexity and is still read whole to change any part of it, so the complexity numbers beside this row neither confirm nor excuse it. To reduce it, extract each cohesive step of the body \u2014 the runs of statements that work on the same values and would earn the same name \u2014 into its own named unit, and have this one call them in order."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/layout/ToDoOverlay.tsx"},"region":{"startLine":779}}}],"partialFingerprints":{"codehealthFindingId/v1":"37e7db7430aa44c66989ac22c768525d12e8787d8e22d15b7117f69684edf711"}},{"ruleId":"D3","level":"warning","message":{"text":"FunctionTooLong: OnboardingPage.StepRestore: FunctionTooLong \u2014 StepRestore runs 122 significant lines (blank, comment-only and punctuation-only lines excluded) in one body. The bar is 100 significant lines; this is 22 over it, 1.22\u00D7 the bar. This is length, not branching: a long straight-line body scores low on complexity and is still read whole to change any part of it, so the complexity numbers beside this row neither confirm nor excuse it. To reduce it, extract each cohesive step of the body \u2014 the runs of statements that work on the same values and would earn the same name \u2014 into its own named unit, and have this one call them in order."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/pages/OnboardingPage.tsx"},"region":{"startLine":354}}}],"partialFingerprints":{"codehealthFindingId/v1":"a394dceae68a5fbb75ec109b079e30c4170d66ed47299b484e38cb370958e117"}},{"ruleId":"D3","level":"warning","message":{"text":"FunctionTooLong: InlinePermissionRequest.InlinePermissionRequest: FunctionTooLong \u2014 InlinePermissionRequest runs 122 significant lines (blank, comment-only and punctuation-only lines excluded) in one body. The bar is 100 significant lines; this is 22 over it, 1.22\u00D7 the bar. This is length, not branching: a long straight-line body scores low on complexity and is still read whole to change any part of it, so the complexity numbers beside this row neither confirm nor excuse it. To reduce it, extract each cohesive step of the body \u2014 the runs of statements that work on the same values and would earn the same name \u2014 into its own named unit, and have this one call them in order."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/pages/chat/components/InlinePermissionRequest.tsx"},"region":{"startLine":40}}}],"partialFingerprints":{"codehealthFindingId/v1":"7e81d81831a00f8617ccf9f6bdf0ee2d471c9f44ba9da4a853cf5737e905124a"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: layout/CommunityOverlay.tsx: FileTooLong \u2014 608 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 108 over it, 1.22\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":"desktop/src/components/layout/CommunityOverlay.tsx"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"c75d0420af88e9eaab30e4d41ea60f73ffe3fb4189989095b37022e51a1cf301"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: validation/base.py: FileTooLong \u2014 605 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 105 over it, 1.21\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":"backend/skills/s_pptx/ooxml/scripts/validation/base.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"d0e2b0f851eb44a7f2453bd4914641cb9ecd31943356405845d5237f55b85d71"}},{"ruleId":"D3","level":"warning","message":{"text":"FunctionTooLong: SkillsTab.SkillsTab: FunctionTooLong \u2014 SkillsTab runs 121 significant lines (blank, comment-only and punctuation-only lines excluded) in one body. The bar is 100 significant lines; this is 21 over it, 1.21\u00D7 the bar. This is length, not branching: a long straight-line body scores low on complexity and is still read whole to change any part of it, so the complexity numbers beside this row neither confirm nor excuse it. To reduce it, extract each cohesive step of the body \u2014 the runs of statements that work on the same values and would earn the same name \u2014 into its own named unit, and have this one call them in order."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/workspace-settings/SkillsTab.tsx"},"region":{"startLine":25}}}],"partialFingerprints":{"codehealthFindingId/v1":"165b94bc48eab238f8347cfcbe073fdcd838b038c171c3c480b37eca38c83376"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: scripts/html2pptx.js: FileTooLong \u2014 604 significant lines (blank, comment-only and punctuation-only lines excluded), about 67% of them inside a single declaration: extractSlideData (244-894). The bar is 500 significant lines; this is 104 over it, 1.21\u00D7 the bar. Moving the declarations that sit BESIDE it into sibling files will not shorten this file. Extract from INSIDE that declaration instead: lift each cohesive group of its body \u2014 the parts that share the same inputs and are named together \u2014 into its own unit in a sibling file, and have the original call them."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/skills/s_pptx/scripts/html2pptx.js"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"e3fb49bc2fc762d7e416fa6c9a4f2eb28610eb4ef1121ac308a0ffd4ef1434d2"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: validation/base.py: FileTooLong \u2014 603 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 103 over it, 1.21\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":"backend/skills/s_docx/ooxml/scripts/validation/base.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"d4890fa3ef60489e3385b1134652943e28295959216a7f9636e3cde83d7b2956"}},{"ruleId":"D3","level":"warning","message":{"text":"FunctionTooLong: useReviewMode.useReviewMode: FunctionTooLong \u2014 useReviewMode runs 120 significant lines (blank, comment-only and punctuation-only lines excluded) in one body. The bar is 100 significant lines; this is 20 over it, 1.20\u00D7 the bar. This is length, not branching: a long straight-line body scores low on complexity and is still read whole to change any part of it, so the complexity numbers beside this row neither confirm nor excuse it. To reduce it, extract each cohesive step of the body \u2014 the runs of statements that work on the same values and would earn the same name \u2014 into its own named unit, and have this one call them in order."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/hooks/useReviewMode.ts"},"region":{"startLine":75}}}],"partialFingerprints":{"codehealthFindingId/v1":"bfac6fde2dfaf1f855dca47ad53211fe15eea04c0fd6acada08c29bb4ee74884"}},{"ruleId":"D3","level":"warning","message":{"text":"FunctionTooLong: CommunityOverlay.SourcesTab: FunctionTooLong \u2014 SourcesTab runs 119 significant lines (blank, comment-only and punctuation-only lines excluded) in one body. The bar is 100 significant lines; this is 19 over it, 1.19\u00D7 the bar. This is length, not branching: a long straight-line body scores low on complexity and is still read whole to change any part of it, so the complexity numbers beside this row neither confirm nor excuse it. To reduce it, extract each cohesive step of the body \u2014 the runs of statements that work on the same values and would earn the same name \u2014 into its own named unit, and have this one call them in order."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/layout/CommunityOverlay.tsx"},"region":{"startLine":374}}}],"partialFingerprints":{"codehealthFindingId/v1":"fea11d17b363f2ad510be944dc61ec25b7d63b997e0fa0238375756f4007f19e"}},{"ruleId":"D3","level":"warning","message":{"text":"FunctionTooLong: ChannelsTab.ChannelsTab: FunctionTooLong \u2014 ChannelsTab runs 119 significant lines (blank, comment-only and punctuation-only lines excluded) in one body. The bar is 100 significant lines; this is 19 over it, 1.19\u00D7 the bar. This is length, not branching: a long straight-line body scores low on complexity and is still read whole to change any part of it, so the complexity numbers beside this row neither confirm nor excuse it. To reduce it, extract each cohesive step of the body \u2014 the runs of statements that work on the same values and would earn the same name \u2014 into its own named unit, and have this one call them in order."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/settings/ChannelsTab.tsx"},"region":{"startLine":13}}}],"partialFingerprints":{"codehealthFindingId/v1":"29be8d7c13986f12bdf4b806df56cfd6dcb4c3400f9bbbfa76fb4b82b6c81697"}},{"ruleId":"D3","level":"warning","message":{"text":"FunctionTooLong: EvalDashboard.OverviewTab: FunctionTooLong \u2014 OverviewTab runs 119 significant lines (blank, comment-only and punctuation-only lines excluded) in one body. The bar is 100 significant lines; this is 19 over it, 1.19\u00D7 the bar. This is length, not branching: a long straight-line body scores low on complexity and is still read whole to change any part of it, so the complexity numbers beside this row neither confirm nor excuse it. To reduce it, extract each cohesive step of the body \u2014 the runs of statements that work on the same values and would earn the same name \u2014 into its own named unit, and have this one call them in order."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/pages/EvalDashboard.tsx"},"region":{"startLine":289}}}],"partialFingerprints":{"codehealthFindingId/v1":"84537d4e7929b916dfe4cce9913209978cdc6b42cb11a333d8e92e46cf062145"}},{"ruleId":"D3","level":"warning","message":{"text":"FunctionTooLong: ReviewModeGutter.ReviewModeGutter: FunctionTooLong \u2014 ReviewModeGutter runs 118 significant lines (blank, comment-only and punctuation-only lines excluded) in one body. The bar is 100 significant lines; this is 18 over it, 1.18\u00D7 the bar. This is length, not branching: a long straight-line body scores low on complexity and is still read whole to change any part of it, so the complexity numbers beside this row neither confirm nor excuse it. To reduce it, extract each cohesive step of the body \u2014 the runs of statements that work on the same values and would earn the same name \u2014 into its own named unit, and have this one call them in order."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/common/ReviewModeGutter.tsx"},"region":{"startLine":42}}}],"partialFingerprints":{"codehealthFindingId/v1":"d5390203cc6250cc4d75f185142ca68a80abe1b788714a3fd94d83c868833353"}},{"ruleId":"D3","level":"warning","message":{"text":"FunctionTooLong: browser-agent.compressDOM: FunctionTooLong \u2014 compressDOM runs 117 significant lines (blank, comment-only and punctuation-only lines excluded) in one body. The bar is 100 significant lines; this is 17 over it, 1.17\u00D7 the bar. This is length, not branching: a long straight-line body scores low on complexity and is still read whole to change any part of it, so the complexity numbers beside this row neither confirm nor excuse it. To reduce it, extract each cohesive step of the body \u2014 the runs of statements that work on the same values and would earn the same name \u2014 into its own named unit, and have this one call them in order."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/skills/s_browser-agent/browser-agent.mjs"},"region":{"startLine":127}}}],"partialFingerprints":{"codehealthFindingId/v1":"09dd9456c5acebc67fb714fed2a84d104b060446918303b521965c61da76512b"}},{"ruleId":"D3","level":"warning","message":{"text":"FunctionTooLong: EvalDashboard.AddCaseModal: FunctionTooLong \u2014 AddCaseModal runs 116 significant lines (blank, comment-only and punctuation-only lines excluded) in one body. The bar is 100 significant lines; this is 16 over it, 1.16\u00D7 the bar. This is length, not branching: a long straight-line body scores low on complexity and is still read whole to change any part of it, so the complexity numbers beside this row neither confirm nor excuse it. To reduce it, extract each cohesive step of the body \u2014 the runs of statements that work on the same values and would earn the same name \u2014 into its own named unit, and have this one call them in order."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/pages/EvalDashboard.tsx"},"region":{"startLine":2391}}}],"partialFingerprints":{"codehealthFindingId/v1":"5e2d6d91d37115199332e2e52267d42a386a85e7e90ff638cb5f94877703c16f"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: stores/MessageStore.ts: FileTooLong \u2014 577 significant lines (blank, comment-only and punctuation-only lines excluded), about 92% of them inside a single declaration: MessageStore (64-1260). The bar is 500 significant lines; this is 77 over it, 1.15\u00D7 the bar. Moving the declarations that sit BESIDE it into sibling files will not shorten this file. Extract from INSIDE that declaration instead: lift each cohesive group of its body \u2014 the parts that share the same inputs and are named together \u2014 into its own unit in a sibling file, and have the original call them."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/stores/MessageStore.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"5a19e0c279b70ee98833cbc33794601db88f4231e4cf4d64e7ec9226f546e5e6"}},{"ruleId":"D3","level":"warning","message":{"text":"FunctionTooLong: SessionTabBar.SessionTabBar: FunctionTooLong \u2014 SessionTabBar runs 115 significant lines (blank, comment-only and punctuation-only lines excluded) in one body. The bar is 100 significant lines; this is 15 over it, 1.15\u00D7 the bar. This is length, not branching: a long straight-line body scores low on complexity and is still read whole to change any part of it, so the complexity numbers beside this row neither confirm nor excuse it. To reduce it, extract each cohesive step of the body \u2014 the runs of statements that work on the same values and would earn the same name \u2014 into its own named unit, and have this one call them in order."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/pages/chat/components/SessionTabBar.tsx"},"region":{"startLine":27}}}],"partialFingerprints":{"codehealthFindingId/v1":"87adf5cae043244ba945589a7e329a89a76b240ed7da420b4d2679ca568a13c7"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: scripts/inventory.py: FileTooLong \u2014 561 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 61 over it, 1.12\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":"backend/skills/s_pptx/scripts/inventory.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"ec620de06f3e7708a8eee4c037e0af3c1f5e993d3dad0b9b9904129178ab65f1"}},{"ruleId":"D3","level":"warning","message":{"text":"FunctionTooLong: OnboardingPage.OnboardingPage: FunctionTooLong \u2014 OnboardingPage runs 112 significant lines (blank, comment-only and punctuation-only lines excluded) in one body. The bar is 100 significant lines; this is 12 over it, 1.12\u00D7 the bar. This is length, not branching: a long straight-line body scores low on complexity and is still read whole to change any part of it, so the complexity numbers beside this row neither confirm nor excuse it. To reduce it, extract each cohesive step of the body \u2014 the runs of statements that work on the same values and would earn the same name \u2014 into its own named unit, and have this one call them in order."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/pages/OnboardingPage.tsx"},"region":{"startLine":40}}}],"partialFingerprints":{"codehealthFindingId/v1":"3c84213beb8bdd34afeaf75e4d230eb3074af5566e818980c3f75a35c7c0a5f4"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: scripts/pipeline_analytics.py: FileTooLong \u2014 559 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 59 over it, 1.12\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":"backend/scripts/pipeline_analytics.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"db3408d105aeadc6743862f9ee1590671be782071fa896cd2b69b49413d7784b"}},{"ruleId":"D3","level":"warning","message":{"text":"FunctionTooLong: LibraryTree.LibraryTree: FunctionTooLong \u2014 LibraryTree runs 111 significant lines (blank, comment-only and punctuation-only lines excluded) in one body. The bar is 100 significant lines; this is 11 over it, 1.11\u00D7 the bar. This is length, not branching: a long straight-line body scores low on complexity and is still read whole to change any part of it, so the complexity numbers beside this row neither confirm nor excuse it. To reduce it, extract each cohesive step of the body \u2014 the runs of statements that work on the same values and would earn the same name \u2014 into its own named unit, and have this one call them in order."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/layout/LibraryTree.tsx"},"region":{"startLine":218}}}],"partialFingerprints":{"codehealthFindingId/v1":"36e1524020be19e91f1c7f7a75b6e02a6750328a2b3063b6f00a44b8f3ad805c"}},{"ruleId":"D3","level":"warning","message":{"text":"FunctionTooLong: TSCCSnapshotCard.TSCCSnapshotCard: FunctionTooLong \u2014 TSCCSnapshotCard runs 111 significant lines (blank, comment-only and punctuation-only lines excluded) in one body. The bar is 100 significant lines; this is 11 over it, 1.11\u00D7 the bar. This is length, not branching: a long straight-line body scores low on complexity and is still read whole to change any part of it, so the complexity numbers beside this row neither confirm nor excuse it. To reduce it, extract each cohesive step of the body \u2014 the runs of statements that work on the same values and would earn the same name \u2014 into its own named unit, and have this one call them in order."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/pages/chat/components/TSCCSnapshotCard.tsx"},"region":{"startLine":41}}}],"partialFingerprints":{"codehealthFindingId/v1":"104b4d4a85c2a5362f7eb71c627d4be46a16c7d4fa3733b53fc9ce7cb73de514"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: components/TSCCModules.tsx: FileTooLong \u2014 551 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 51 over it, 1.10\u00D7 the bar. To reduce it, split the file along the responsibilities already in it: move each cohesive group of declarations into its own sibling file in the same module or package, so no one file has to be read whole to change one of them."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/pages/chat/components/TSCCModules.tsx"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"2f289cd73c41c121fb957a62ed5467d214c3899fd0518aa731d5e9433a313817"}},{"ruleId":"D3","level":"warning","message":{"text":"FunctionTooLong: CMBrainOverlay.CMBrainContent: FunctionTooLong \u2014 CMBrainContent runs 110 significant lines (blank, comment-only and punctuation-only lines excluded) in one body. The bar is 100 significant lines; this is 10 over it, 1.10\u00D7 the bar. This is length, not branching: a long straight-line body scores low on complexity and is still read whole to change any part of it, so the complexity numbers beside this row neither confirm nor excuse it. To reduce it, extract each cohesive step of the body \u2014 the runs of statements that work on the same values and would earn the same name \u2014 into its own named unit, and have this one call them in order."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/layout/CMBrainOverlay.tsx"},"region":{"startLine":167}}}],"partialFingerprints":{"codehealthFindingId/v1":"018295c31bac32891b956fe9969147c505d2fe56a39f422f330ef389e3bf95a8"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: components/SectionLayouts.tsx: FileTooLong \u2014 546 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 46 over it, 1.09\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":"backend/skills/s_pollinate/templates/remotion/components/SectionLayouts.tsx"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"4462f6e574f598161b81274c9132203400541d98ad143212715ba32bf7e5ec77"}},{"ruleId":"D3","level":"warning","message":{"text":"FunctionTooLong: CMBrainOverlay.ContextTab: FunctionTooLong \u2014 ContextTab runs 109 significant lines (blank, comment-only and punctuation-only lines excluded) in one body. The bar is 100 significant lines; this is 9 over it, 1.09\u00D7 the bar. This is length, not branching: a long straight-line body scores low on complexity and is still read whole to change any part of it, so the complexity numbers beside this row neither confirm nor excuse it. To reduce it, extract each cohesive step of the body \u2014 the runs of statements that work on the same values and would earn the same name \u2014 into its own named unit, and have this one call them in order."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/layout/CMBrainOverlay.tsx"},"region":{"startLine":520}}}],"partialFingerprints":{"codehealthFindingId/v1":"9e6735a24f8bfa0c9495e239d33d954cb8625a08b3c58206c9910c3d53c76f50"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: core/ddd_orchestrator.py: FileTooLong \u2014 541 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 41 over it, 1.08\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":"backend/core/ddd_orchestrator.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"37f920905e9d93b0c1d78153bccb7c96d8265e4a2c9afc225c2f5a3c982741dc"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: core/summarization.py: FileTooLong \u2014 537 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 37 over it, 1.07\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":"backend/core/summarization.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"bbd59ca14b7e4cc021e83ba4fe6cccec7e503f7ea9a1c3e90070e15c0f59cc13"}},{"ruleId":"D3","level":"warning","message":{"text":"FunctionTooLong: TSCCPopoverButton.TSCCPopoverButton: FunctionTooLong \u2014 TSCCPopoverButton runs 107 significant lines (blank, comment-only and punctuation-only lines excluded) in one body. The bar is 100 significant lines; this is 7 over it, 1.07\u00D7 the bar. This is length, not branching: a long straight-line body scores low on complexity and is still read whole to change any part of it, so the complexity numbers beside this row neither confirm nor excuse it. To reduce it, extract each cohesive step of the body \u2014 the runs of statements that work on the same values and would earn the same name \u2014 into its own named unit, and have this one call them in order."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/pages/chat/components/TSCCPopoverButton.tsx"},"region":{"startLine":62}}}],"partialFingerprints":{"codehealthFindingId/v1":"d74c9ef5bff4782790148282c7bb4915a641a871703ce785149149645c86228a"}},{"ruleId":"D3","level":"warning","message":{"text":"FunctionTooLong: SystemTab.SystemTab: FunctionTooLong \u2014 SystemTab runs 106 significant lines (blank, comment-only and punctuation-only lines excluded) in one body. The bar is 100 significant lines; this is 6 over it, 1.06\u00D7 the bar. This is length, not branching: a long straight-line body scores low on complexity and is still read whole to change any part of it, so the complexity numbers beside this row neither confirm nor excuse it. To reduce it, extract each cohesive step of the body \u2014 the runs of statements that work on the same values and would earn the same name \u2014 into its own named unit, and have this one call them in order."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/settings/SystemTab.tsx"},"region":{"startLine":26}}}],"partialFingerprints":{"codehealthFindingId/v1":"d1d39cbc833941d085530ce5811198ecb78c19ee63d7096a10501ffc50718fe7"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: core/skill_manager.py: FileTooLong \u2014 525 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 25 over it, 1.05\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":"backend/core/skill_manager.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"1241f4aec4574f6207a3cf8087c468030a1d3568886b59717a4035b200afb5c0"}},{"ruleId":"D3","level":"warning","message":{"text":"ClassTooLong: AuthConfigPanel: ClassTooLong \u2014 415 significant lines (blank, comment-only and punctuation-only lines excluded), 1 methods. The bar is 400 significant lines; this is 15 over it, 1.04\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":"desktop/src/components/settings/AuthConfigPanel.tsx"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"63b0a198cb4ea9f588b4c59c99d3d61731f2a2610b2c194439ac15531e8b67d1"}},{"ruleId":"D3","level":"warning","message":{"text":"TooManyMethods: SessionRouter: TooManyMethods \u2014 31 methods. The bar is 30 methods; this is 1 over it, 1.03\u00D7 the bar. To reduce it, group the members that share the same data into a smaller type of their own and delegate to it, so no single type carries every responsibility."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/core/session_router.py"},"region":{"startLine":1679}}}],"partialFingerprints":{"codehealthFindingId/v1":"34f1348a5df560783129b5aa26b1d1eb60f7493e1b2416c7ecc1bf35d6734833"}},{"ruleId":"D3","level":"warning","message":{"text":"FunctionTooLong: TerminalTab.TerminalTab: FunctionTooLong \u2014 TerminalTab runs 102 significant lines (blank, comment-only and punctuation-only lines excluded) in one body. The bar is 100 significant lines; this is 2 over it, 1.02\u00D7 the bar. This is length, not branching: a long straight-line body scores low on complexity and is still read whole to change any part of it, so the complexity numbers beside this row neither confirm nor excuse it. To reduce it, extract each cohesive step of the body \u2014 the runs of statements that work on the same values and would earn the same name \u2014 into its own named unit, and have this one call them in order."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/terminal/TerminalTab.tsx"},"region":{"startLine":61}}}],"partialFingerprints":{"codehealthFindingId/v1":"00fcd9b2aba01db80ac5fea15c92a2a1d125ba42fb654bf07ddfc542fbb9183b"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: settings/hiveComponents.tsx: FileTooLong \u2014 503 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 3 over it, 1.01\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":"desktop/src/components/settings/hiveComponents.tsx"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"1bab1a1dcfe750e27f36a82b26702191d4c2c1d97b3e8f087adf2cf5c967db72"}},{"ruleId":"D4","level":"warning","message":{"text":"Near-duplicate member family (6 members, 65 shared lines): backend/scripts/locked_write.py:417-512 | backend/scripts/locked_write.py:519-675 | backend/skills/s_persist/scripts/locked_write.py:417-512 | backend/skills/s_persist/scripts/locked_write.py:519-675 | backend/templates/ddd-skills/s_ddd-persist/scripts/locked_write.py:417-512 | backend/templates/ddd-skills/s_ddd-persist/scripts/locked_write.py:519-647 \u2014 These 6 members are variants of one another: a block of 65 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 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":"backend/scripts/locked_write.py"},"region":{"startLine":417}}}],"partialFingerprints":{"codehealthFindingId/v1":"a80c630c683a3d5a3b73492f13474df9f26179e3a8323338769cd81f124b7762"}},{"ruleId":"D4","level":"warning","message":{"text":"Near-duplicate member family (3 members, 43 shared lines): backend/scripts/locked_write.py:341-406 | backend/skills/s_persist/scripts/locked_write.py:341-406 | backend/templates/ddd-skills/s_ddd-persist/scripts/locked_write.py:341-406 \u2014 These 3 members are variants of one another: a block of 43 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":"backend/scripts/locked_write.py"},"region":{"startLine":341}}}],"partialFingerprints":{"codehealthFindingId/v1":"a7d5754525a6a4ba78e2bb72f04574b02e56c124e8b148bd37b0366938887c39"}},{"ruleId":"D4","level":"warning","message":{"text":"Near-duplicate member family (3 members, 35 shared lines): backend/scripts/locked_write.py:280-335 | backend/skills/s_persist/scripts/locked_write.py:280-335 | backend/templates/ddd-skills/s_ddd-persist/scripts/locked_write.py:280-335 \u2014 These 3 members are variants of one another: a block of 35 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":"backend/scripts/locked_write.py"},"region":{"startLine":280}}}],"partialFingerprints":{"codehealthFindingId/v1":"0f3416cdef1bcfe45f737ba547bebe9ad97afbcdfb97663928ad07161cd0837e"}},{"ruleId":"D4","level":"warning","message":{"text":"Near-duplicate member pair (109 shared lines): backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:2747-2857 | backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:2400-2510 \u2014 These two members are variants of one another: 109 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":"backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py"},"region":{"startLine":2747}}}],"partialFingerprints":{"codehealthFindingId/v1":"d22466e07db8cee0b8fcc274078c337f756435ac9edb50a0a8296ecef0cdea1d"}},{"ruleId":"D4","level":"warning","message":{"text":"Near-duplicate member pair (54 shared lines): backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:1569-1628 | backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:1226-1292 \u2014 These two members are variants of one another: 54 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":"backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py"},"region":{"startLine":1569}}}],"partialFingerprints":{"codehealthFindingId/v1":"8275a0fb2c6c43879d0d28163cba6d3bea7b911ded65a816146d9dfa7a383a34"}},{"ruleId":"D4","level":"warning","message":{"text":"Near-duplicate member pair (28 shared lines): backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:214-247 | backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:213-246 \u2014 These two members are variants of one another: 28 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":"backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py"},"region":{"startLine":214}}}],"partialFingerprints":{"codehealthFindingId/v1":"3007ac1df0b387a58a53addd8dff04d964c6b0e0e71f4555114051fce03a2b1d"}},{"ruleId":"D4","level":"warning","message":{"text":"Edited copy of a member (28 corresponding lines): backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:1484-1511 | backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:1195-1222 \u2014 These two members are one piece of code written twice and then edited apart: 28 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":"backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py"},"region":{"startLine":1484}}}],"partialFingerprints":{"codehealthFindingId/v1":"0d1730ed891dc3f24e254ba3299b9cebddfa3d213cdaf8d0e2b24724e4dddfdc"}},{"ruleId":"D4","level":"warning","message":{"text":"Edited copy of a member (27 corresponding lines): backend/core/ddd_job_registry.py:234-260 | backend/core/ddd_skill_registry.py:299-327 \u2014 These two members are one piece of code written twice and then edited apart: 27 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":"backend/core/ddd_job_registry.py"},"region":{"startLine":234}}}],"partialFingerprints":{"codehealthFindingId/v1":"2fcac0cc3d06fb425abceafe3bd505ad6f12ff3a4c2f5521239b3e1f81c003ae"}},{"ruleId":"D4","level":"warning","message":{"text":"Members sharing a duplicated core (12 members, 50\u002B identical tokens): backend/skills/s_docx/ooxml/scripts/validation/base.py:187-275 | backend/skills/s_docx/ooxml/scripts/validation/docx.py:73-122 | backend/skills/s_docx/ooxml/scripts/validation/docx.py:125-171 | backend/skills/s_docx/ooxml/scripts/validation/docx.py:217-261 | backend/skills/s_docx/ooxml/scripts/validation/pptx.py:78-119 | backend/skills/s_docx/ooxml/scripts/validation/pptx.py:129-201 | backend/skills/s_pptx/ooxml/scripts/validation/base.py:187-278 | backend/skills/s_pptx/ooxml/scripts/validation/docx.py:73-122 | backend/skills/s_pptx/ooxml/scripts/validation/docx.py:125-171 | backend/skills/s_pptx/ooxml/scripts/validation/docx.py:217-261 | backend/skills/s_pptx/ooxml/scripts/validation/pptx.py:78-119 | backend/skills/s_pptx/ooxml/scripts/validation/pptx.py:129-201 \u2014 These 12 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 12 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 12 times."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/skills/s_docx/ooxml/scripts/validation/base.py"},"region":{"startLine":187}}}],"partialFingerprints":{"codehealthFindingId/v1":"db7306859d393a118981ec645ac1aef0966644afc9b8d5af0a12655c215e6095"}},{"ruleId":"D4","level":"warning","message":{"text":"Members sharing a duplicated core (11 members, 50\u002B identical tokens): backend/database/sqlite.py:975-983 | backend/database/sqlite.py:1091-1099 | backend/database/sqlite.py:1192-1200 | backend/database/sqlite.py:1309-1317 | backend/database/sqlite.py:1361-1369 | backend/database/sqlite.py:1397-1405 | backend/database/sqlite.py:1486-1494 | backend/database/sqlite.py:1497-1508 | backend/database/sqlite.py:1606-1614 | backend/database/sqlite.py:1617-1625 | backend/database/sqlite.py:1718-1726 \u2014 These 11 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 11 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 11 times."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/database/sqlite.py"},"region":{"startLine":975}}}],"partialFingerprints":{"codehealthFindingId/v1":"2a3831a912922f4782faaccf456bfc7d8ea4c858c472601d4a47d31fae02a8c5"}},{"ruleId":"D4","level":"warning","message":{"text":"Members sharing a duplicated core (7 members, 50\u002B identical tokens): backend/core/conversation_extract.py:120-155 | backend/core/memory_extractor.py:255-297 | backend/core/session_harvest.py:105-132 | backend/core/summarization.py:824-889 | backend/jobs/handlers/ddd_refresh.py:235-262 | backend/jobs/handlers/memory_health.py:458-487 | backend/jobs/handlers/skill_proposer.py:275-319 \u2014 These 7 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 7 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 7 times."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/core/conversation_extract.py"},"region":{"startLine":120}}}],"partialFingerprints":{"codehealthFindingId/v1":"b820fd2cc986350996f7954d40231fb64868f4dfee52d18c934f1b87c04b49b7"}},{"ruleId":"D4","level":"warning","message":{"text":"Members sharing a duplicated core (5 members, 50\u002B identical tokens): backend/skills/s_frontend-design/scripts/design_system.py:423-528 | backend/skills/s_frontend-design/scripts/design_system.py:613-883 | backend/skills/s_frontend-design/scripts/design_system.py:887-992 | backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:2271-2370 | backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:1923-2023 \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":"backend/skills/s_frontend-design/scripts/design_system.py"},"region":{"startLine":423}}}],"partialFingerprints":{"codehealthFindingId/v1":"0870361cfdf3ddc53fa73dedafa5a4dbd4ae9e92259aa16cb62d378eeb6c30a7"}},{"ruleId":"D4","level":"warning","message":{"text":"Members sharing a duplicated core (4 members, 50\u002B identical tokens): backend/core/memory_extractor.py:96-138 | backend/core/session_miner.py:136-160 | backend/core/summarization.py:684-720 | backend/core/transcript_indexer.py:46-99 \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":"backend/core/memory_extractor.py"},"region":{"startLine":96}}}],"partialFingerprints":{"codehealthFindingId/v1":"1ca6e5806f1a414a517cd65b4383c09c2d6c2724855ebdeab52c0086a38aa8ce"}},{"ruleId":"D4","level":"warning","message":{"text":"Members sharing a duplicated core (4 members, 50\u002B identical tokens): backend/database/sqlite.py:500-522 | backend/database/sqlite.py:1416-1430 | backend/database/sqlite.py:1636-1668 | backend/database/sqlite.py:1699-1715 \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":"backend/database/sqlite.py"},"region":{"startLine":500}}}],"partialFingerprints":{"codehealthFindingId/v1":"4744eea0f99095af94e160a590f474065aa78f19d6b96f82c5d75a7e651a95e8"}},{"ruleId":"D4","level":"warning","message":{"text":"Members sharing a duplicated core (4 members, 50\u002B identical tokens): backend/hooks/context_health_hook.py:3507-3594 | backend/hooks/distillation_hook.py:1932-1961 | backend/hooks/distillation_hook.py:2058-2114 | backend/hooks/evolution_maintenance_hook.py:364-489 \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":"backend/hooks/context_health_hook.py"},"region":{"startLine":3507}}}],"partialFingerprints":{"codehealthFindingId/v1":"cf42438e031eeea275b8800c5aa53c1d3a186d8d55558bff59265f903f91e24f"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (161 lines \u00D7 2): backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:2389-2549 | backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:2042-2202 \u2014 before extracting anything, compare \u0060backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py\u0060 and \u0060backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py\u0060 as WHOLE FILES: this scan already matched 79 separate duplicated blocks between them, totalling at least 2758 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":"backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py"},"region":{"startLine":2389}}}],"partialFingerprints":{"codehealthFindingId/v1":"8b9530c94f9baec3b83fa376e3c9ac2adefc94a010a74b27e85574126fd501d1"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (121\u2013122 lines \u00D7 2): backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:2953-3073 | backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:2606-2727 \u2014 before extracting anything, compare \u0060backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py\u0060 and \u0060backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py\u0060 as WHOLE FILES: this scan already matched 79 separate duplicated blocks between them, totalling at least 2758 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":"backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py"},"region":{"startLine":2953}}}],"partialFingerprints":{"codehealthFindingId/v1":"1c1e8e6f36165fb76e3e5a56f3b94428bd4dc69e7cabd0d3923ac59f140bc234"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (117 lines \u00D7 2): backend/skills/s_docx/ooxml/scripts/validation/base.py:523-639 | backend/skills/s_pptx/ooxml/scripts/validation/base.py:526-642 \u2014 before extracting anything, compare \u0060backend/skills/s_docx/ooxml/scripts/validation/base.py\u0060 and \u0060backend/skills/s_pptx/ooxml/scripts/validation/base.py\u0060 as WHOLE FILES: this scan already matched 20 separate duplicated blocks between them, totalling at least 820 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/skills/s_docx/ooxml/scripts/validation/base.py"},"region":{"startLine":523}}}],"partialFingerprints":{"codehealthFindingId/v1":"0e1645a5430ddf0a509d3aad4fe6c0a57afa66ebf34d3ebe7e1f19af75c52dd8"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (109 lines \u00D7 2): backend/skills/s_docx/ooxml/scripts/validation/base.py:278-386 | backend/skills/s_pptx/ooxml/scripts/validation/base.py:281-389 \u2014 before extracting anything, compare \u0060backend/skills/s_docx/ooxml/scripts/validation/base.py\u0060 and \u0060backend/skills/s_pptx/ooxml/scripts/validation/base.py\u0060 as WHOLE FILES: this scan already matched 20 separate duplicated blocks between them, totalling at least 820 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/skills/s_docx/ooxml/scripts/validation/base.py"},"region":{"startLine":278}}}],"partialFingerprints":{"codehealthFindingId/v1":"94b7cb94d6582378193c1bee5644a9bb2505e737c461e8e42bfda775f89e13ef"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (96 lines \u00D7 2): backend/skills/s_docx/ooxml/scripts/validation/base.py:389-484 | backend/skills/s_pptx/ooxml/scripts/validation/base.py:392-487 \u2014 before extracting anything, compare \u0060backend/skills/s_docx/ooxml/scripts/validation/base.py\u0060 and \u0060backend/skills/s_pptx/ooxml/scripts/validation/base.py\u0060 as WHOLE FILES: this scan already matched 20 separate duplicated blocks between them, totalling at least 820 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/skills/s_docx/ooxml/scripts/validation/base.py"},"region":{"startLine":389}}}],"partialFingerprints":{"codehealthFindingId/v1":"90819b7d09e28f3a71da20241c7f22f586bb04ac27d6402e159532a6e6632a27"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (94 lines \u00D7 3): backend/scripts/locked_write.py:679-772 | backend/skills/s_persist/scripts/locked_write.py:679-772 | backend/templates/ddd-skills/s_ddd-persist/scripts/locked_write.py:651-744 \u2014 before extracting anything, compare \u0060backend/scripts/locked_write.py\u0060 and \u0060backend/skills/s_persist/scripts/locked_write.py\u0060 as WHOLE FILES: this scan already matched 10 separate duplicated blocks between them, totalling at least 456 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/scripts/locked_write.py"},"region":{"startLine":679}}}],"partialFingerprints":{"codehealthFindingId/v1":"fd5df4b966e59b5099321d064e796a821792827407924eb59f7091b23810643d"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (92 lines \u00D7 2): backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:114-205 | backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:114-205 \u2014 before extracting anything, compare \u0060backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py\u0060 and \u0060backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py\u0060 as WHOLE FILES: this scan already matched 79 separate duplicated blocks between them, totalling at least 2758 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it. \u2605 These copies have DRIFTED, and that is worth reading before extracting anything: just after the matched lines, \u0060backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:206\u0060 calls \u0060extend\u0060, \u0060check_business_rule_anchor_files\u0060 and \u0060backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:206\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":"backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py"},"region":{"startLine":114}}}],"partialFingerprints":{"codehealthFindingId/v1":"55c643e25191a999516f9893a86eca213798dd9a567c79e1803f907a6a73a825"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (90 lines \u00D7 2): backend/skills/s_docx/ooxml/scripts/validation/redlining.py:23-112 | backend/skills/s_pptx/ooxml/scripts/validation/redlining.py:23-112 \u2014 before extracting anything, compare \u0060backend/skills/s_docx/ooxml/scripts/validation/redlining.py\u0060 and \u0060backend/skills/s_pptx/ooxml/scripts/validation/redlining.py\u0060 as WHOLE FILES: this scan already matched 5 separate duplicated blocks between them, totalling at least 245 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/skills/s_docx/ooxml/scripts/validation/redlining.py"},"region":{"startLine":23}}}],"partialFingerprints":{"codehealthFindingId/v1":"93475d2e2f2a3a9c91bf0ffe8035502404794f2e755d1c79fcb5322aba3aebb1"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (81 lines \u00D7 2): backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:2625-2705 | backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:2278-2358 \u2014 before extracting anything, compare \u0060backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py\u0060 and \u0060backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py\u0060 as WHOLE FILES: this scan already matched 79 separate duplicated blocks between them, totalling at least 2758 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py"},"region":{"startLine":2625}}}],"partialFingerprints":{"codehealthFindingId/v1":"66824851734ebfb0b2f34addc1d1026cea88dcb2046042c357e469489271667e"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (81 lines \u00D7 2): backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:2863-2943 | backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:2516-2596 \u2014 before extracting anything, compare \u0060backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py\u0060 and \u0060backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py\u0060 as WHOLE FILES: this scan already matched 79 separate duplicated blocks between them, totalling at least 2758 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py"},"region":{"startLine":2863}}}],"partialFingerprints":{"codehealthFindingId/v1":"f272092d8f79f38e39d2df25f3db1bbcdb4b0b3e17fe3a2078545d71ca02b1ef"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (76 lines \u00D7 2): backend/skills/s_docx/ooxml/scripts/validation/redlining.py:140-215 | backend/skills/s_pptx/ooxml/scripts/validation/redlining.py:140-215 \u2014 before extracting anything, compare \u0060backend/skills/s_docx/ooxml/scripts/validation/redlining.py\u0060 and \u0060backend/skills/s_pptx/ooxml/scripts/validation/redlining.py\u0060 as WHOLE FILES: this scan already matched 5 separate duplicated blocks between them, totalling at least 245 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/skills/s_docx/ooxml/scripts/validation/redlining.py"},"region":{"startLine":140}}}],"partialFingerprints":{"codehealthFindingId/v1":"8579e2f8096ec870c89b103215642098c3f8e7d351e4725d07b28b4b4208934e"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (75 lines \u00D7 2): backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:1904-1978 | backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:1568-1642 \u2014 before extracting anything, compare \u0060backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py\u0060 and \u0060backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py\u0060 as WHOLE FILES: this scan already matched 79 separate duplicated blocks between them, totalling at least 2758 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py"},"region":{"startLine":1904}}}],"partialFingerprints":{"codehealthFindingId/v1":"0a97749731b0022a4dd2470e0e29f0c6840e74fdfad259e3dbeb76dd2aa3922c"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (75 lines \u00D7 2): backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:2747-2821 | backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:2400-2474 \u2014 before extracting anything, compare \u0060backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py\u0060 and \u0060backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py\u0060 as WHOLE FILES: this scan already matched 79 separate duplicated blocks between them, totalling at least 2758 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py"},"region":{"startLine":2747}}}],"partialFingerprints":{"codehealthFindingId/v1":"4527e9085d7fca4313cab7d321c48881465ffdb00508d476c3e2634d8c7e805c"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (74 lines \u00D7 2): backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:3174-3247 | backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:2827-2900 \u2014 before extracting anything, compare \u0060backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py\u0060 and \u0060backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py\u0060 as WHOLE FILES: this scan already matched 79 separate duplicated blocks between them, totalling at least 2758 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py"},"region":{"startLine":3174}}}],"partialFingerprints":{"codehealthFindingId/v1":"db6b7aaf619d1a55d4af592bc5b170c4d682dae4b64b816bbaae42f508b46f3d"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (73 lines \u00D7 2): backend/skills/s_docx/ooxml/scripts/validation/pptx.py:129-201 | backend/skills/s_pptx/ooxml/scripts/validation/pptx.py:129-201 \u2014 before extracting anything, compare \u0060backend/skills/s_docx/ooxml/scripts/validation/pptx.py\u0060 and \u0060backend/skills/s_pptx/ooxml/scripts/validation/pptx.py\u0060 as WHOLE FILES: this scan already matched 9 separate duplicated blocks between them, totalling at least 298 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/skills/s_docx/ooxml/scripts/validation/pptx.py"},"region":{"startLine":129}}}],"partialFingerprints":{"codehealthFindingId/v1":"36ce351cd1cbdec2a889c1b40c79e5c13328152216cecfde00cf72dbeb94b61e"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (73 lines \u00D7 2): backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:420-492 | backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:420-492 \u2014 before extracting anything, compare \u0060backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py\u0060 and \u0060backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py\u0060 as WHOLE FILES: this scan already matched 79 separate duplicated blocks between them, totalling at least 2758 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":"backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py"},"region":{"startLine":420}}}],"partialFingerprints":{"codehealthFindingId/v1":"000b168b7a1ed25b80a7fb989a2f74238026a231b39a78aa9db02bf6c4c642bf"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (70 lines \u00D7 2): backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:2301-2370 | backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:1954-2023 \u2014 before extracting anything, compare \u0060backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py\u0060 and \u0060backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py\u0060 as WHOLE FILES: this scan already matched 79 separate duplicated blocks between them, totalling at least 2758 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py"},"region":{"startLine":2301}}}],"partialFingerprints":{"codehealthFindingId/v1":"1b1deb3fca8b766c49b478acc88a3b0a14020699934117bc32aa139259e50a2f"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (69 lines \u00D7 2): backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:774-842 | backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:688-756 \u2014 before extracting anything, compare \u0060backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py\u0060 and \u0060backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py\u0060 as WHOLE FILES: this scan already matched 79 separate duplicated blocks between them, totalling at least 2758 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py"},"region":{"startLine":774}}}],"partialFingerprints":{"codehealthFindingId/v1":"35e72dd92724887447ad666f6fcdda9da7cf4462d9420f2e565107581b73ba73"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (68 lines \u00D7 2): backend/skills/s_docx/ooxml/scripts/validation/pptx.py:244-311 | backend/skills/s_pptx/ooxml/scripts/validation/pptx.py:244-311 \u2014 before extracting anything, compare \u0060backend/skills/s_docx/ooxml/scripts/validation/pptx.py\u0060 and \u0060backend/skills/s_pptx/ooxml/scripts/validation/pptx.py\u0060 as WHOLE FILES: this scan already matched 9 separate duplicated blocks between them, totalling at least 298 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/skills/s_docx/ooxml/scripts/validation/pptx.py"},"region":{"startLine":244}}}],"partialFingerprints":{"codehealthFindingId/v1":"d431350a461d55192b5028e881b1dad287841a3f8eca612b35edd76b98d55da3"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (68 lines \u00D7 2): backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:1375-1442 | backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:1092-1159 \u2014 before extracting anything, compare \u0060backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py\u0060 and \u0060backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py\u0060 as WHOLE FILES: this scan already matched 79 separate duplicated blocks between them, totalling at least 2758 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py"},"region":{"startLine":1375}}}],"partialFingerprints":{"codehealthFindingId/v1":"c3823c53ff233c33cbfcb05147dd2f45eec522b471769e59c2fce6e26075537c"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (68 lines \u00D7 2): backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:3756-3823 | backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:3387-3454 \u2014 before extracting anything, compare \u0060backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py\u0060 and \u0060backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py\u0060 as WHOLE FILES: this scan already matched 79 separate duplicated blocks between them, totalling at least 2758 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 \u0060backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:3756\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":"backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py"},"region":{"startLine":3756}}}],"partialFingerprints":{"codehealthFindingId/v1":"d9795c52debd637b5c2b2f039de7302d026e071ecaed8a26e8f9fa07221bf633"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (64 lines \u00D7 2): backend/skills/s_docx/ooxml/scripts/validation/base.py:206-269 | backend/skills/s_pptx/ooxml/scripts/validation/base.py:209-272 \u2014 before extracting anything, compare \u0060backend/skills/s_docx/ooxml/scripts/validation/base.py\u0060 and \u0060backend/skills/s_pptx/ooxml/scripts/validation/base.py\u0060 as WHOLE FILES: this scan already matched 20 separate duplicated blocks between them, totalling at least 820 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it. \u2605 These copies have DRIFTED, and that is worth reading before extracting anything: just before the matched lines, \u0060backend/skills/s_pptx/ooxml/scripts/validation/base.py:207\u0060 calls \u0060isinstance\u0060 and \u0060backend/skills/s_docx/ooxml/scripts/validation/base.py:204\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":"backend/skills/s_docx/ooxml/scripts/validation/base.py"},"region":{"startLine":206}}}],"partialFingerprints":{"codehealthFindingId/v1":"8e25b3037cbfdc22815696fa2ded325fd0b6c5c25c0467ce2d03f7622b00f332"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (61 lines \u00D7 2): backend/core/daemon_guard.py:414-474 | desktop/resources/daemon/daemon_guard.py:414-474 \u2014 before extracting anything, compare \u0060backend/core/daemon_guard.py\u0060 and \u0060desktop/resources/daemon/daemon_guard.py\u0060 as WHOLE FILES: this scan already matched 11 separate duplicated blocks between them, totalling at least 280 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/core/daemon_guard.py"},"region":{"startLine":414}}}],"partialFingerprints":{"codehealthFindingId/v1":"d7f1deb846ae189386b6dc43df78e2a9b9e26d04ff93359edc218d80e10cbb89"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (59 lines \u00D7 2): backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:1180-1238 | backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:917-975 \u2014 before extracting anything, compare \u0060backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py\u0060 and \u0060backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py\u0060 as WHOLE FILES: this scan already matched 79 separate duplicated blocks between them, totalling at least 2758 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":"backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py"},"region":{"startLine":1180}}}],"partialFingerprints":{"codehealthFindingId/v1":"06d9f29dc1a84d775bc7b0c05d92c750587bb72c425efe2f628bd435f68a1517"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (57\u201358 lines \u00D7 2): backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:326-382 | backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:325-382 \u2014 before extracting anything, compare \u0060backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py\u0060 and \u0060backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py\u0060 as WHOLE FILES: this scan already matched 79 separate duplicated blocks between them, totalling at least 2758 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 \u0060backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:326\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":"backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py"},"region":{"startLine":326}}}],"partialFingerprints":{"codehealthFindingId/v1":"4c68589f605c0f06aba19b25d8eb2e43505eb3fedacde312fe8a1e705d2586df"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (57 lines \u00D7 2): backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:3083-3139 | backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:2736-2792 \u2014 before extracting anything, compare \u0060backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py\u0060 and \u0060backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py\u0060 as WHOLE FILES: this scan already matched 79 separate duplicated blocks between them, totalling at least 2758 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The \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":"backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py"},"region":{"startLine":3083}}}],"partialFingerprints":{"codehealthFindingId/v1":"9ba6f75486e970909b5ff1260136b58231fe75dd7c5547d10c30a19090ddd6da"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (52\u201357 lines \u00D7 2): backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:3253-3309 | backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:2906-2957 \u2014 before extracting anything, compare \u0060backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py\u0060 and \u0060backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py\u0060 as WHOLE FILES: this scan already matched 79 separate duplicated blocks between them, totalling at least 2758 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it. \u2605 These copies have DRIFTED, and that is worth reading before extracting anything: just after the matched lines, \u0060backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:3310\u0060 calls \u0060set\u0060 and \u0060backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:2958\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":"backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py"},"region":{"startLine":3253}}}],"partialFingerprints":{"codehealthFindingId/v1":"b01b7b5214ccf4fc097bfac1581f76f13e4f9dc836d82cd3d224548ced33b952"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (43\u201357 lines \u00D7 2): backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:3426-3482 | backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:3076-3118 \u2014 before extracting anything, compare \u0060backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py\u0060 and \u0060backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py\u0060 as WHOLE FILES: this scan already matched 79 separate duplicated blocks between them, totalling at least 2758 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py"},"region":{"startLine":3426}}}],"partialFingerprints":{"codehealthFindingId/v1":"4e94dcb0edb4f2eee3b40f165eeb5b1ea1aac40325fa131ed5f3faf2d0c17faa"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (56 lines \u00D7 3): backend/scripts/locked_write.py:171-226 | backend/skills/s_persist/scripts/locked_write.py:171-226 | backend/templates/ddd-skills/s_ddd-persist/scripts/locked_write.py:171-226 \u2014 before extracting anything, compare \u0060backend/scripts/locked_write.py\u0060 and \u0060backend/skills/s_persist/scripts/locked_write.py\u0060 as WHOLE FILES: this scan already matched 10 separate duplicated blocks between them, totalling at least 456 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/scripts/locked_write.py"},"region":{"startLine":171}}}],"partialFingerprints":{"codehealthFindingId/v1":"8bb54b7446298b3005b7d0bf75d3b7977e3af22308da474a193312f6c3f6bd8c"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (53\u201355 lines \u00D7 6): backend/scripts/locked_write.py:433-485 | backend/scripts/locked_write.py:547-599 | backend/skills/s_persist/scripts/locked_write.py:433-485 | backend/skills/s_persist/scripts/locked_write.py:547-599 | backend/templates/ddd-skills/s_ddd-persist/scripts/locked_write.py:433-485 | backend/templates/ddd-skills/s_ddd-persist/scripts/locked_write.py:540-594 \u2014 before extracting anything, compare \u0060backend/scripts/locked_write.py\u0060 and \u0060backend/skills/s_persist/scripts/locked_write.py\u0060 as WHOLE FILES: this scan already matched 10 separate duplicated blocks between them, totalling at least 456 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/scripts/locked_write.py"},"region":{"startLine":433}}}],"partialFingerprints":{"codehealthFindingId/v1":"0c476f94d6b955ffc01c1e690e7037ea51a523789982806f5974dfb09dc2ecb8"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (55 lines \u00D7 2): backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:1653-1707 | backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:1317-1371 \u2014 before extracting anything, compare \u0060backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py\u0060 and \u0060backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py\u0060 as WHOLE FILES: this scan already matched 79 separate duplicated blocks between them, totalling at least 2758 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":"backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py"},"region":{"startLine":1653}}}],"partialFingerprints":{"codehealthFindingId/v1":"7015aea2fd111e553c04cf0462077476991ca65fd2662612663065d8505c292f"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (51\u201354 lines \u00D7 2): backend/core/streaming_orchestrator.py:1456-1506 | backend/core/streaming_orchestrator.py:1629-1682 \u2014 both copies are in the same file, so extract the block 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 \u0060backend/core/streaming_orchestrator.py:1456\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":"backend/core/streaming_orchestrator.py"},"region":{"startLine":1456}}}],"partialFingerprints":{"codehealthFindingId/v1":"455a27f57af5feef1a750f207160c07c11ffc4e6f58508def2ae80b7993b00d8"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (44\u201351 lines \u00D7 2): backend/core/knowledge_store.py:574-624 | backend/core/transcript_indexer.py:631-674 \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 \u0060backend/core/knowledge_store.py:574\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":"backend/core/knowledge_store.py"},"region":{"startLine":574}}}],"partialFingerprints":{"codehealthFindingId/v1":"1c49171f9a3eed0826e08dc164ba89e17e4f1589207b5a5c0ca290e31ff67ec1"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (51 lines \u00D7 2): backend/skills/s_docx/ooxml/scripts/validation/base.py:689-739 | backend/skills/s_pptx/ooxml/scripts/validation/base.py:692-742 \u2014 before extracting anything, compare \u0060backend/skills/s_docx/ooxml/scripts/validation/base.py\u0060 and \u0060backend/skills/s_pptx/ooxml/scripts/validation/base.py\u0060 as WHOLE FILES: this scan already matched 20 separate duplicated blocks between them, totalling at least 820 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/skills/s_docx/ooxml/scripts/validation/base.py"},"region":{"startLine":689}}}],"partialFingerprints":{"codehealthFindingId/v1":"9840f1e9346591448e0905a7ad848c667f21b4919722c001c1a7a701bba0bf64"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (50 lines \u00D7 2): backend/scripts/locked_write.py:621-670 | backend/skills/s_persist/scripts/locked_write.py:621-670 \u2014 before extracting anything, compare \u0060backend/scripts/locked_write.py\u0060 and \u0060backend/skills/s_persist/scripts/locked_write.py\u0060 as WHOLE FILES: this scan already matched 10 separate duplicated blocks between them, totalling at least 456 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/scripts/locked_write.py"},"region":{"startLine":621}}}],"partialFingerprints":{"codehealthFindingId/v1":"8313ee5768fe7d5e765d5af394244314fb671c5e80cfcc59ff1f63a93b5ff0b5"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (50 lines \u00D7 2): backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:3370-3419 | backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:3020-3069 \u2014 before extracting anything, compare \u0060backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py\u0060 and \u0060backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py\u0060 as WHOLE FILES: this scan already matched 79 separate duplicated blocks between them, totalling at least 2758 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":"backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py"},"region":{"startLine":3370}}}],"partialFingerprints":{"codehealthFindingId/v1":"7adc9fb42e038488ae44fec16ac25de22dea0b2ac951bc80706eb111c588aff0"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (49 lines \u00D7 2): backend/skills/s_docx/ooxml/scripts/validate.py:17-65 | backend/skills/s_pptx/ooxml/scripts/validate.py:17-65 \u2014 before extracting anything, compare \u0060backend/skills/s_docx/ooxml/scripts/validate.py\u0060 and \u0060backend/skills/s_pptx/ooxml/scripts/validate.py\u0060 as WHOLE FILES: 100% 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 1 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."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/skills/s_docx/ooxml/scripts/validate.py"},"region":{"startLine":17}}}],"partialFingerprints":{"codehealthFindingId/v1":"41efd3ad6cd5a1ddfed9cd6d30f093a6c0bf3bd37f1a08475a71b4c4d41eb028"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (48 lines \u00D7 2): backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:649-696 | backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:563-610 \u2014 before extracting anything, compare \u0060backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py\u0060 and \u0060backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py\u0060 as WHOLE FILES: this scan already matched 79 separate duplicated blocks between them, totalling at least 2758 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py"},"region":{"startLine":649}}}],"partialFingerprints":{"codehealthFindingId/v1":"f955f7746bd5d2eb8f69c2b33518487e7b9e36319e9a0476b4f951a644f8ed03"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (47 lines \u00D7 2): backend/skills/s_docx/ooxml/scripts/validation/pptx.py:29-75 | backend/skills/s_pptx/ooxml/scripts/validation/pptx.py:29-75 \u2014 before extracting anything, compare \u0060backend/skills/s_docx/ooxml/scripts/validation/pptx.py\u0060 and \u0060backend/skills/s_pptx/ooxml/scripts/validation/pptx.py\u0060 as WHOLE FILES: this scan already matched 9 separate duplicated blocks between them, totalling at least 298 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/skills/s_docx/ooxml/scripts/validation/pptx.py"},"region":{"startLine":29}}}],"partialFingerprints":{"codehealthFindingId/v1":"ec8a0fc54691c947b9d547096e6a0f1c8dd915ba545f075ea75ea6114efdf277"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (47 lines \u00D7 2): backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:1822-1868 | backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:1486-1532 \u2014 before extracting anything, compare \u0060backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py\u0060 and \u0060backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py\u0060 as WHOLE FILES: this scan already matched 79 separate duplicated blocks between them, totalling at least 2758 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":"backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py"},"region":{"startLine":1822}}}],"partialFingerprints":{"codehealthFindingId/v1":"bb0e66f8f1644388e928c1ed4f739e3c145cbba5cbd81c8cb402fe03672941bb"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (46 lines \u00D7 2): backend/core/knowledge_store.py:290-335 | backend/core/transcript_indexer.py:344-389 \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":"backend/core/knowledge_store.py"},"region":{"startLine":290}}}],"partialFingerprints":{"codehealthFindingId/v1":"d161716d62d9067c2632550b1818d43b14fbb03bbf0185982f51341c359b6300"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (46 lines \u00D7 2): backend/skills/s_docx/ooxml/scripts/validation/docx.py:25-70 | backend/skills/s_pptx/ooxml/scripts/validation/docx.py:25-70 \u2014 before extracting anything, compare \u0060backend/skills/s_docx/ooxml/scripts/validation/docx.py\u0060 and \u0060backend/skills/s_pptx/ooxml/scripts/validation/docx.py\u0060 as WHOLE FILES: this scan already matched 11 separate duplicated blocks between them, totalling at least 244 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/skills/s_docx/ooxml/scripts/validation/docx.py"},"region":{"startLine":25}}}],"partialFingerprints":{"codehealthFindingId/v1":"3c269f2a6017d44916924687fa013e8d4b4ea11d4076427d956b38f4ec1f3275"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (45 lines \u00D7 3): backend/scripts/locked_write.py:83-127 | backend/skills/s_persist/scripts/locked_write.py:83-127 | backend/templates/ddd-skills/s_ddd-persist/scripts/locked_write.py:83-127 \u2014 before extracting anything, compare \u0060backend/scripts/locked_write.py\u0060 and \u0060backend/skills/s_persist/scripts/locked_write.py\u0060 as WHOLE FILES: this scan already matched 10 separate duplicated blocks between them, totalling at least 456 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/scripts/locked_write.py"},"region":{"startLine":83}}}],"partialFingerprints":{"codehealthFindingId/v1":"91ab4a10a58590af19284eac319cf20c5a2ea0ad6c3bbac8038beab8b124cfdd"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (45 lines \u00D7 2): backend/skills/s_docx/ooxml/scripts/validation/base.py:642-686 | backend/skills/s_pptx/ooxml/scripts/validation/base.py:645-689 \u2014 before extracting anything, compare \u0060backend/skills/s_docx/ooxml/scripts/validation/base.py\u0060 and \u0060backend/skills/s_pptx/ooxml/scripts/validation/base.py\u0060 as WHOLE FILES: this scan already matched 20 separate duplicated blocks between them, totalling at least 820 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/skills/s_docx/ooxml/scripts/validation/base.py"},"region":{"startLine":642}}}],"partialFingerprints":{"codehealthFindingId/v1":"2cb2295da56d91e4a039dd3d2bd4e64089ba12280ad2ea63041ef40e6db5caca"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (43\u201344 lines \u00D7 2): backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:1043-1085 | backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:779-822 \u2014 before extracting anything, compare \u0060backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py\u0060 and \u0060backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py\u0060 as WHOLE FILES: this scan already matched 79 separate duplicated blocks between them, totalling at least 2758 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":"backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py"},"region":{"startLine":1043}}}],"partialFingerprints":{"codehealthFindingId/v1":"9c7b9513409cf9a746cc036db8d229fcfa6b1414b7023b945dd18c9e9ce2ab51"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (44 lines \u00D7 2): backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:1712-1755 | backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:1376-1419 \u2014 before extracting anything, compare \u0060backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py\u0060 and \u0060backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py\u0060 as WHOLE FILES: this scan already matched 79 separate duplicated blocks between them, totalling at least 2758 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py"},"region":{"startLine":1712}}}],"partialFingerprints":{"codehealthFindingId/v1":"4f90dd3076c0291b1aaaba177a7dd79c065854ab3300c1e35db8fff7e7d1bbbf"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (44 lines \u00D7 2): backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:2177-2220 | backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:1829-1872 \u2014 before extracting anything, compare \u0060backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py\u0060 and \u0060backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py\u0060 as WHOLE FILES: this scan already matched 79 separate duplicated blocks between them, totalling at least 2758 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The \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":"backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py"},"region":{"startLine":2177}}}],"partialFingerprints":{"codehealthFindingId/v1":"a03aaf161b01bbc151400bde3587aa4db395c9ac973dd9b454a57d643b65ef22"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (35\u201343 lines \u00D7 6): backend/scripts/locked_write.py:280-314 | backend/scripts/locked_write.py:341-383 | backend/skills/s_persist/scripts/locked_write.py:280-314 | backend/skills/s_persist/scripts/locked_write.py:341-383 | backend/templates/ddd-skills/s_ddd-persist/scripts/locked_write.py:280-314 | backend/templates/ddd-skills/s_ddd-persist/scripts/locked_write.py:341-383 \u2014 before extracting anything, compare \u0060backend/scripts/locked_write.py\u0060 and \u0060backend/skills/s_persist/scripts/locked_write.py\u0060 as WHOLE FILES: this scan already matched 10 separate duplicated blocks between them, totalling at least 456 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. \u2605 These copies have DRIFTED, and that is worth reading before extracting anything: just after the matched lines, \u0060backend/scripts/locked_write.py:386\u0060 calls \u0060match\u0060 and \u0060backend/scripts/locked_write.py:315\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":"backend/scripts/locked_write.py"},"region":{"startLine":280}}}],"partialFingerprints":{"codehealthFindingId/v1":"b03b32f879c775881b10d256fc2ab9210e78b304998ab7a57b69432d03424aa8"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (35\u201343 lines \u00D7 3): backend/core/streaming_orchestrator.py:1470-1504 | backend/core/streaming_orchestrator.py:1644-1678 | backend/core/streaming_orchestrator.py:1802-1844 \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 \u0060backend/core/streaming_orchestrator.py:1470\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":"backend/core/streaming_orchestrator.py"},"region":{"startLine":1470}}}],"partialFingerprints":{"codehealthFindingId/v1":"feeca1c8e85994c77ae3622fcc5ac1221d1b73f7b5eaa442094e64630d581b42"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (43 lines \u00D7 3): backend/scripts/locked_write.py:232-274 | backend/skills/s_persist/scripts/locked_write.py:232-274 | backend/templates/ddd-skills/s_ddd-persist/scripts/locked_write.py:232-274 \u2014 before extracting anything, compare \u0060backend/scripts/locked_write.py\u0060 and \u0060backend/skills/s_persist/scripts/locked_write.py\u0060 as WHOLE FILES: this scan already matched 10 separate duplicated blocks between them, totalling at least 456 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/scripts/locked_write.py"},"region":{"startLine":232}}}],"partialFingerprints":{"codehealthFindingId/v1":"81896d8ceaa31517a2bd35520ece8cf8c42a3cfa12a2d6831672f2087e2cf32c"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (43 lines \u00D7 2): backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:1128-1170 | backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:865-907 \u2014 before extracting anything, compare \u0060backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py\u0060 and \u0060backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py\u0060 as WHOLE FILES: this scan already matched 79 separate duplicated blocks between them, totalling at least 2758 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py"},"region":{"startLine":1128}}}],"partialFingerprints":{"codehealthFindingId/v1":"23933e60339b4ba2dc9eec5157f7aa72bc54860343a7e838944892ba714aa740"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (43 lines \u00D7 2): backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:1242-1284 | backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:979-1021 \u2014 before extracting anything, compare \u0060backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py\u0060 and \u0060backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py\u0060 as WHOLE FILES: this scan already matched 79 separate duplicated blocks between them, totalling at least 2758 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py"},"region":{"startLine":1242}}}],"partialFingerprints":{"codehealthFindingId/v1":"f8b7a272db436050a6ae4ed77d7b68002ce5f25342fa3118d13ea47291d5258d"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (42 lines \u00D7 2): backend/skills/s_docx/ooxml/scripts/pack.py:46-87 | backend/skills/s_pptx/ooxml/scripts/pack.py:46-87 \u2014 before extracting anything, compare \u0060backend/skills/s_docx/ooxml/scripts/pack.py\u0060 and \u0060backend/skills/s_pptx/ooxml/scripts/pack.py\u0060 as WHOLE FILES: this scan already matched 4 separate duplicated blocks between them, totalling at least 127 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/skills/s_docx/ooxml/scripts/pack.py"},"region":{"startLine":46}}}],"partialFingerprints":{"codehealthFindingId/v1":"17de5659dab1f032ee91077cd8890955b4babc609cc1386377569583c6d14e9b"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (41 lines \u00D7 2): backend/skills/s_docx/ooxml/scripts/validation/base.py:827-867 | backend/skills/s_pptx/ooxml/scripts/validation/base.py:830-870 \u2014 before extracting anything, compare \u0060backend/skills/s_docx/ooxml/scripts/validation/base.py\u0060 and \u0060backend/skills/s_pptx/ooxml/scripts/validation/base.py\u0060 as WHOLE FILES: this scan already matched 20 separate duplicated blocks between them, totalling at least 820 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/skills/s_docx/ooxml/scripts/validation/base.py"},"region":{"startLine":827}}}],"partialFingerprints":{"codehealthFindingId/v1":"c0524b2f76706e972055b4477813c2a6f86024567dbf322a7fd20e4b8f4b3475"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (41 lines \u00D7 2): backend/skills/s_docx/ooxml/scripts/validation/base.py:907-947 | backend/skills/s_pptx/ooxml/scripts/validation/base.py:910-950 \u2014 before extracting anything, compare \u0060backend/skills/s_docx/ooxml/scripts/validation/base.py\u0060 and \u0060backend/skills/s_pptx/ooxml/scripts/validation/base.py\u0060 as WHOLE FILES: this scan already matched 20 separate duplicated blocks between them, totalling at least 820 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":"backend/skills/s_docx/ooxml/scripts/validation/base.py"},"region":{"startLine":907}}}],"partialFingerprints":{"codehealthFindingId/v1":"095daa36d685bb101b03beae1c3f075ab60bd458c3dd2ad74912f835ef791255"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (41 lines \u00D7 2): backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:1982-2022 | backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:1646-1686 \u2014 before extracting anything, compare \u0060backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py\u0060 and \u0060backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py\u0060 as WHOLE FILES: this scan already matched 79 separate duplicated blocks between them, totalling at least 2758 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py"},"region":{"startLine":1982}}}],"partialFingerprints":{"codehealthFindingId/v1":"a2677f3b5c736464971595bf3cad2c59861cc9e1f7fca81b79b3106d745866c7"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (40 lines \u00D7 2): backend/routers/chat.py:768-807 | backend/routers/chat.py:1478-1517 \u2014 both copies are in the same file, so extract the block 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 \u0060backend/routers/chat.py:768\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":"backend/routers/chat.py"},"region":{"startLine":768}}}],"partialFingerprints":{"codehealthFindingId/v1":"f620fe43108cdfa014297b4ed6ee9ea568392444b84f02d57c46bc870bc4c8e9"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (40 lines \u00D7 2): backend/skills/s_docx/ooxml/scripts/pack.py:91-130 | backend/skills/s_pptx/ooxml/scripts/pack.py:91-130 \u2014 before extracting anything, compare \u0060backend/skills/s_docx/ooxml/scripts/pack.py\u0060 and \u0060backend/skills/s_pptx/ooxml/scripts/pack.py\u0060 as WHOLE FILES: this scan already matched 4 separate duplicated blocks between them, totalling at least 127 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/skills/s_docx/ooxml/scripts/pack.py"},"region":{"startLine":91}}}],"partialFingerprints":{"codehealthFindingId/v1":"4cea0734074d4f8a6b38e73f1a5f8fb440fe558f7cb799d7104dd596c21e5ed1"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (33\u201339 lines \u00D7 2): backend/core/skill_manager.py:920-958 | backend/core/skill_manager.py:1017-1049 \u2014 both copies are in the same file, so extract the block 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":"backend/core/skill_manager.py"},"region":{"startLine":920}}}],"partialFingerprints":{"codehealthFindingId/v1":"2fcc904624aa6c8aea94b60c8ea78d92b3f220bd0566758a378cc5ce055be0e3"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (32\u201339 lines \u00D7 2): backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:1569-1600 | backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:1226-1264 \u2014 before extracting anything, compare \u0060backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py\u0060 and \u0060backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py\u0060 as WHOLE FILES: this scan already matched 79 separate duplicated blocks between them, totalling at least 2758 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":"backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py"},"region":{"startLine":1569}}}],"partialFingerprints":{"codehealthFindingId/v1":"7a4e3f78242244d9ab2dc6a4871de2b6105a1ca26d2b94ceb607ba1028eed191"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (23\u201338 lines \u00D7 2): backend/core/library_mounts.py:523-545 | backend/core/library_mounts.py:580-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. 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":"backend/core/library_mounts.py"},"region":{"startLine":523}}}],"partialFingerprints":{"codehealthFindingId/v1":"c94820bd8777dcea5801eadd724ca642d7b89cf4374bddd385e24600ebe988e4"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (38 lines \u00D7 2): backend/skills/s_docx/ooxml/scripts/validation/docx.py:73-110 | backend/skills/s_pptx/ooxml/scripts/validation/docx.py:73-110 \u2014 before extracting anything, compare \u0060backend/skills/s_docx/ooxml/scripts/validation/docx.py\u0060 and \u0060backend/skills/s_pptx/ooxml/scripts/validation/docx.py\u0060 as WHOLE FILES: this scan already matched 11 separate duplicated blocks between them, totalling at least 244 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 \u0060backend/skills/s_docx/ooxml/scripts/validation/docx.py:73\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":"backend/skills/s_docx/ooxml/scripts/validation/docx.py"},"region":{"startLine":73}}}],"partialFingerprints":{"codehealthFindingId/v1":"74e0be29ce82dfc0be533e0ba892fc44a2d7d270f1426424f24baae653b8af6c"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (38 lines \u00D7 2): backend/skills/s_docx/ooxml/scripts/validation/pptx.py:204-241 | backend/skills/s_pptx/ooxml/scripts/validation/pptx.py:204-241 \u2014 before extracting anything, compare \u0060backend/skills/s_docx/ooxml/scripts/validation/pptx.py\u0060 and \u0060backend/skills/s_pptx/ooxml/scripts/validation/pptx.py\u0060 as WHOLE FILES: this scan already matched 9 separate duplicated blocks between them, totalling at least 298 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/skills/s_docx/ooxml/scripts/validation/pptx.py"},"region":{"startLine":204}}}],"partialFingerprints":{"codehealthFindingId/v1":"58a2b81c685ab6e161faf56d34f14bdfd004035cc6190747f3fac4e593573d67"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (37 lines \u00D7 3): backend/scripts/locked_write.py:131-167 | backend/skills/s_persist/scripts/locked_write.py:131-167 | backend/templates/ddd-skills/s_ddd-persist/scripts/locked_write.py:131-167 \u2014 before extracting anything, compare \u0060backend/scripts/locked_write.py\u0060 and \u0060backend/skills/s_persist/scripts/locked_write.py\u0060 as WHOLE FILES: this scan already matched 10 separate duplicated blocks between them, totalling at least 456 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":"backend/scripts/locked_write.py"},"region":{"startLine":131}}}],"partialFingerprints":{"codehealthFindingId/v1":"4d954590876769f3efd4480ee054aed97ad531870ec7d2ca4705e0ea3dc1a032"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (33\u201337 lines \u00D7 2): backend/core/knowledge_store.py:338-374 | backend/core/transcript_indexer.py:392-424 \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 \u0060backend/core/knowledge_store.py:338\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":"backend/core/knowledge_store.py"},"region":{"startLine":338}}}],"partialFingerprints":{"codehealthFindingId/v1":"fd85bf69d345a243708f9f0c27494906c60fb4cb62a8c89a33193dff2e7e6e67"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (33\u201337 lines \u00D7 2): backend/core/knowledge_store.py:535-571 | backend/core/transcript_indexer.py:596-628 \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":"backend/core/knowledge_store.py"},"region":{"startLine":535}}}],"partialFingerprints":{"codehealthFindingId/v1":"bc9c8306df8eb9ebc26d2c1ffb391859e890ad3c50d7c059dc821db9e4d8e7e4"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (26\u201337 lines \u00D7 2): backend/core/proactive_intelligence.py:1438-1474 | backend/core/proactive_intelligence.py:1917-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."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/core/proactive_intelligence.py"},"region":{"startLine":1438}}}],"partialFingerprints":{"codehealthFindingId/v1":"3b3f2aee6f898d792c7d30e96690823c6b56d50a8dfa1c7a2def429f07818d44"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (36 lines \u00D7 2): backend/core/daemon_guard.py:372-407 | desktop/resources/daemon/daemon_guard.py:372-407 \u2014 before extracting anything, compare \u0060backend/core/daemon_guard.py\u0060 and \u0060desktop/resources/daemon/daemon_guard.py\u0060 as WHOLE FILES: this scan already matched 11 separate duplicated blocks between them, totalling at least 280 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/core/daemon_guard.py"},"region":{"startLine":372}}}],"partialFingerprints":{"codehealthFindingId/v1":"f2bd310f45c102598f2021c685752aca8cf1472721a071663aeaa7eff1a0430a"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (19\u201335 lines \u00D7 2): backend/core/ddd_cultivation.py:513-547 | backend/core/ingestion_gate.py:89-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. 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":"backend/core/ddd_cultivation.py"},"region":{"startLine":513}}}],"partialFingerprints":{"codehealthFindingId/v1":"55d3506b39ac04098e5a7eb8d4002b7345fdc16bfec9aa5711f66c19d1163833"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (30\u201335 lines \u00D7 2): backend/hooks/distillation_hook.py:1614-1643 | backend/hooks/distillation_hook.py:1693-1727 \u2014 both copies are in the same file, so extract the block 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":"backend/hooks/distillation_hook.py"},"region":{"startLine":1614}}}],"partialFingerprints":{"codehealthFindingId/v1":"6869f3fdc557ff6ea7ede047bee6cd4e287fd7e597b43ce09762f675c931971e"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (35 lines \u00D7 2): backend/skills/s_docx/ooxml/scripts/validation/base.py:870-904 | backend/skills/s_pptx/ooxml/scripts/validation/base.py:873-907 \u2014 before extracting anything, compare \u0060backend/skills/s_docx/ooxml/scripts/validation/base.py\u0060 and \u0060backend/skills/s_pptx/ooxml/scripts/validation/base.py\u0060 as WHOLE FILES: this scan already matched 20 separate duplicated blocks between them, totalling at least 820 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/skills/s_docx/ooxml/scripts/validation/base.py"},"region":{"startLine":870}}}],"partialFingerprints":{"codehealthFindingId/v1":"d6c87b7b3a48c445d6ad88e3b5721de4fd47e1418151c852ece0e783970da178"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (35 lines \u00D7 2): backend/skills/s_docx/ooxml/scripts/validation/docx.py:125-159 | backend/skills/s_pptx/ooxml/scripts/validation/docx.py:125-159 \u2014 before extracting anything, compare \u0060backend/skills/s_docx/ooxml/scripts/validation/docx.py\u0060 and \u0060backend/skills/s_pptx/ooxml/scripts/validation/docx.py\u0060 as WHOLE FILES: this scan already matched 11 separate duplicated blocks between them, totalling at least 244 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 \u0060backend/skills/s_docx/ooxml/scripts/validation/docx.py:125\u0060 it does not close everything it opens, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that. 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":"backend/skills/s_docx/ooxml/scripts/validation/docx.py"},"region":{"startLine":125}}}],"partialFingerprints":{"codehealthFindingId/v1":"e9965543accbf32a27dfdaaa3ae612109da754ad2eda9eee5aa98dcef1b98d97"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (35 lines \u00D7 2): backend/skills/s_docx/ooxml/scripts/validation/pptx.py:78-112 | backend/skills/s_pptx/ooxml/scripts/validation/pptx.py:78-112 \u2014 before extracting anything, compare \u0060backend/skills/s_docx/ooxml/scripts/validation/pptx.py\u0060 and \u0060backend/skills/s_pptx/ooxml/scripts/validation/pptx.py\u0060 as WHOLE FILES: this scan already matched 9 separate duplicated blocks between them, totalling at least 298 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":"backend/skills/s_docx/ooxml/scripts/validation/pptx.py"},"region":{"startLine":78}}}],"partialFingerprints":{"codehealthFindingId/v1":"93259b54803e1b8d16901491ee68f3a857f68056bc589f4ec450f1ca45610062"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (35 lines \u00D7 2): backend/skills/s_docx/ooxml/scripts/validation/redlining.py:218-252 | backend/skills/s_pptx/ooxml/scripts/validation/redlining.py:218-252 \u2014 before extracting anything, compare \u0060backend/skills/s_docx/ooxml/scripts/validation/redlining.py\u0060 and \u0060backend/skills/s_pptx/ooxml/scripts/validation/redlining.py\u0060 as WHOLE FILES: this scan already matched 5 separate duplicated blocks between them, totalling at least 245 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":"backend/skills/s_docx/ooxml/scripts/validation/redlining.py"},"region":{"startLine":218}}}],"partialFingerprints":{"codehealthFindingId/v1":"92a7e1d6d2962d23e8014c577e94149c3d5259ed7a87e3e128f3b855da9b187c"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (27\u201335 lines \u00D7 2): backend/skills/s_estimate-tokens/scripts/estimate_tokens.py:44-78 | backend/skills/s_library/scripts/library.py:26-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. 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":"backend/skills/s_estimate-tokens/scripts/estimate_tokens.py"},"region":{"startLine":44}}}],"partialFingerprints":{"codehealthFindingId/v1":"802aaa097dd465ee4abb42a64d0f9016ec1e978e82730057d24c18e659474edc"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (35 lines \u00D7 2): backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:1088-1122 | backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:825-859 \u2014 before extracting anything, compare \u0060backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py\u0060 and \u0060backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py\u0060 as WHOLE FILES: this scan already matched 79 separate duplicated blocks between them, totalling at least 2758 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":"backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py"},"region":{"startLine":1088}}}],"partialFingerprints":{"codehealthFindingId/v1":"7640b14ee705c828fffd40d87b77a6020a9cf2203cdc300be84a0f39f2550ecd"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (34 lines \u00D7 2): backend/core/daemon_guard.py:330-363 | desktop/resources/daemon/daemon_guard.py:330-363 \u2014 before extracting anything, compare \u0060backend/core/daemon_guard.py\u0060 and \u0060desktop/resources/daemon/daemon_guard.py\u0060 as WHOLE FILES: this scan already matched 11 separate duplicated blocks between them, totalling at least 280 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/core/daemon_guard.py"},"region":{"startLine":330}}}],"partialFingerprints":{"codehealthFindingId/v1":"d618c1a683445f7d1252018d375adcabbc84cabf509c373cfa9ec1c1d6e83e26"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (34 lines \u00D7 2): backend/core/knowledge_store.py:243-276 | backend/core/transcript_indexer.py:297-330 \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":"backend/core/knowledge_store.py"},"region":{"startLine":243}}}],"partialFingerprints":{"codehealthFindingId/v1":"ca41e0f40526bb59fcdfd7c1bc61d8cca4cdfed6bd5c4231e7dcb3de26b17427"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (34 lines \u00D7 2): backend/skills/s_docx/ooxml/scripts/validation/base.py:487-520 | backend/skills/s_pptx/ooxml/scripts/validation/base.py:490-523 \u2014 before extracting anything, compare \u0060backend/skills/s_docx/ooxml/scripts/validation/base.py\u0060 and \u0060backend/skills/s_pptx/ooxml/scripts/validation/base.py\u0060 as WHOLE FILES: this scan already matched 20 separate duplicated blocks between them, totalling at least 820 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/skills/s_docx/ooxml/scripts/validation/base.py"},"region":{"startLine":487}}}],"partialFingerprints":{"codehealthFindingId/v1":"1c7f2e39822734443fcd645f547fe5151031e3a17739da65c2dec1bf8dc0c048"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (13\u201333 lines \u00D7 2): backend/core/security_hooks.py:611-643 | backend/core/security_hooks.py:1626-1638 \u2014 both copies are in the same file, so extract the block 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":"backend/core/security_hooks.py"},"region":{"startLine":611}}}],"partialFingerprints":{"codehealthFindingId/v1":"ff002f9ad5056136a6b7924d496c10564a0fd5d04cd0af3d07e09c8b5079e95e"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (33 lines \u00D7 2): backend/skills/s_docx/ooxml/scripts/validation/docx.py:217-249 | backend/skills/s_pptx/ooxml/scripts/validation/docx.py:217-249 \u2014 before extracting anything, compare \u0060backend/skills/s_docx/ooxml/scripts/validation/docx.py\u0060 and \u0060backend/skills/s_pptx/ooxml/scripts/validation/docx.py\u0060 as WHOLE FILES: this scan already matched 11 separate duplicated blocks between them, totalling at least 244 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 \u0060backend/skills/s_docx/ooxml/scripts/validation/docx.py:217\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":"backend/skills/s_docx/ooxml/scripts/validation/docx.py"},"region":{"startLine":217}}}],"partialFingerprints":{"codehealthFindingId/v1":"273df68e7fde9c9c66a4a26f5be774df43aa1234a72f2f6254cb175342d85772"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (32 lines \u00D7 2): backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:264-295 | backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:263-294 \u2014 before extracting anything, compare \u0060backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py\u0060 and \u0060backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py\u0060 as WHOLE FILES: this scan already matched 79 separate duplicated blocks between them, totalling at least 2758 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":"backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py"},"region":{"startLine":264}}}],"partialFingerprints":{"codehealthFindingId/v1":"e7d9eb92947bbf7c3fed5aa8e6b94d186be96d0eafd31299a5a925935e81e27b"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (32 lines \u00D7 2): backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:2559-2590 | backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:2212-2243 \u2014 before extracting anything, compare \u0060backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py\u0060 and \u0060backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py\u0060 as WHOLE FILES: this scan already matched 79 separate duplicated blocks between them, totalling at least 2758 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py"},"region":{"startLine":2559}}}],"partialFingerprints":{"codehealthFindingId/v1":"9065da2a761b40528195f9524bc750425e0e4015c8a850dbbb67ca072f3070f4"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (31 lines \u00D7 2): backend/core/chat_thread_manager.py:475-505 | backend/core/chat_thread_manager.py:549-581 \u2014 both copies are in the same file, so extract the block 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 first that the copies are not typed on the same thing: the declarations holding them bind \u0060data\u0060 to \u0060ChatMessageCreate\u0060 in one and \u0060ThreadSummaryCreate\u0060 in another, and the duplicated lines use it. The extracted unit therefore needs a parameter type that fits BOTH \u2014 their common supertype where they have one, or a new abstraction over them where they do not \u2014 and settling that is the step that comes BEFORE the extraction above. Where the two types are deliberately unrelated, the duplication is the price of that separation and the honest resolution is to record the decision rather than to extract."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/core/chat_thread_manager.py"},"region":{"startLine":475}}}],"partialFingerprints":{"codehealthFindingId/v1":"012ebf39a87b29c27116a86c6f275410ed326e09a7fb622e8b38cc4bfbb90284"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (30\u201331 lines \u00D7 2): backend/core/retry_manager.py:91-121 | backend/core/retry_manager.py:207-236 \u2014 both copies are in the same file, so extract the block 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 \u0060backend/core/retry_manager.py:91\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 first that the copies are not typed on the same thing: \u0060SessionState\u0060 names \u0060.session_unit\u0060 in one and \u0060core.session_unit\u0060 in another \u2014 different types that share a simple name, which is why the text matched. A single extracted unit cannot be given a parameter type that fits both, so unifying those types (or introducing a shared abstraction over them) is the step that has to come BEFORE the extraction above; if they are deliberately separate, the duplication is the price of that separation and the honest resolution is to record the decision rather than to extract."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/core/retry_manager.py"},"region":{"startLine":91}}}],"partialFingerprints":{"codehealthFindingId/v1":"a20253f0c9b6425e4cddc48772b5cba07febf746de00820cf039f6231ac23dc3"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (31 lines \u00D7 2): backend/core/retry_manager.py:128-158 | backend/core/retry_manager.py:233-263 \u2014 both copies are in the same file, so extract the block 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 \u0060backend/core/retry_manager.py:128\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":"backend/core/retry_manager.py"},"region":{"startLine":128}}}],"partialFingerprints":{"codehealthFindingId/v1":"6e1e2e67984210c6a898e4149b42795846092c93c56d1d548518931b996d50df"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (26\u201331 lines \u00D7 2): backend/routers/workspace.py:465-495 | backend/routers/workspace.py:570-595 \u2014 both copies are in the same file, so extract the block 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":"backend/routers/workspace.py"},"region":{"startLine":465}}}],"partialFingerprints":{"codehealthFindingId/v1":"d14821dbd3fd40c65bb0ff1d5f2552097e55069f2ad6f8c47ff5341de83f14c4"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (30 lines \u00D7 2): backend/core/plugin_manager.py:208-237 | backend/core/plugin_manager.py:974-1003 \u2014 both copies are in the same file, so extract the block 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":"backend/core/plugin_manager.py"},"region":{"startLine":208}}}],"partialFingerprints":{"codehealthFindingId/v1":"39be5759f94e4f855ea4b8118aaf7e3d249a239e4ab79e14e378ebe1a14898fc"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (30 lines \u00D7 2): backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:31-60 | backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:31-60 \u2014 before extracting anything, compare \u0060backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py\u0060 and \u0060backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py\u0060 as WHOLE FILES: this scan already matched 79 separate duplicated blocks between them, totalling at least 2758 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py"},"region":{"startLine":31}}}],"partialFingerprints":{"codehealthFindingId/v1":"d3f63d353a4fbe4b794d836f26261f1014be3efad24d586e117dd1891f4db957"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (30 lines \u00D7 2): backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:2099-2128 | backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:1748-1777 \u2014 before extracting anything, compare \u0060backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py\u0060 and \u0060backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py\u0060 as WHOLE FILES: this scan already matched 79 separate duplicated blocks between them, totalling at least 2758 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py"},"region":{"startLine":2099}}}],"partialFingerprints":{"codehealthFindingId/v1":"6d903f8d6addd244abd230565f2c59a65a5f9ce8d975d2fda21467f3b760f1e6"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (29\u201330 lines \u00D7 2): backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:2271-2299 | backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:1923-1952 \u2014 before extracting anything, compare \u0060backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py\u0060 and \u0060backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py\u0060 as WHOLE FILES: this scan already matched 79 separate duplicated blocks between them, totalling at least 2758 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":"backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py"},"region":{"startLine":2271}}}],"partialFingerprints":{"codehealthFindingId/v1":"b15358199ba7b038630b42b54a594d40b3078b1c68ab3f48902560befc2b9191"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (26\u201329 lines \u00D7 2): backend/channels/adapters/slack.py:1107-1132 | backend/channels/adapters/slack.py:1229-1257 \u2014 both copies are in the same file, so extract the block 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":"backend/channels/adapters/slack.py"},"region":{"startLine":1107}}}],"partialFingerprints":{"codehealthFindingId/v1":"522f9b28dbeb7b0dd7d5ff126a4735578e5bed4eb946bc317626c11744a2c1e2"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (29 lines \u00D7 2): backend/core/session_hooks.py:522-550 | backend/core/session_hooks.py:577-605 \u2014 both copies are in the same file, so extract the block 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":"backend/core/session_hooks.py"},"region":{"startLine":522}}}],"partialFingerprints":{"codehealthFindingId/v1":"3f461387555faad9b657832313d50e264ef33f0aa898bad54ebe067bce606718"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (25\u201329 lines \u00D7 2): backend/scripts/eval_runner.py:566-594 | backend/scripts/eval_runner.py:700-724 \u2014 both copies are in the same file, so extract the block 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":"backend/scripts/eval_runner.py"},"region":{"startLine":566}}}],"partialFingerprints":{"codehealthFindingId/v1":"6e3b91c3dbbf5a10a774bcbb113cef1f02bac9089cc3fb277a4e7635f7f4c5a8"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (27\u201329 lines \u00D7 2): backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:1288-1314 | backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:1025-1053 \u2014 before extracting anything, compare \u0060backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py\u0060 and \u0060backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py\u0060 as WHOLE FILES: this scan already matched 79 separate duplicated blocks between them, totalling at least 2758 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":"backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py"},"region":{"startLine":1288}}}],"partialFingerprints":{"codehealthFindingId/v1":"ba8a8b9aad01c7d365ede3312218e7814d5f502c4a46f9edc25c13db860fd078"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (29 lines \u00D7 2): backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:3724-3752 | backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:3355-3383 \u2014 before extracting anything, compare \u0060backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py\u0060 and \u0060backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py\u0060 as WHOLE FILES: this scan already matched 79 separate duplicated blocks between them, totalling at least 2758 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py"},"region":{"startLine":3724}}}],"partialFingerprints":{"codehealthFindingId/v1":"25051e3fdca8f17be7b60d7329da300333885061f5035c89a9e2e49b57e80d15"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (28 lines \u00D7 2): backend/skills/s_docx/ooxml/scripts/validation/base.py:157-184 | backend/skills/s_pptx/ooxml/scripts/validation/base.py:157-184 \u2014 before extracting anything, compare \u0060backend/skills/s_docx/ooxml/scripts/validation/base.py\u0060 and \u0060backend/skills/s_pptx/ooxml/scripts/validation/base.py\u0060 as WHOLE FILES: this scan already matched 20 separate duplicated blocks between them, totalling at least 820 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/skills/s_docx/ooxml/scripts/validation/base.py"},"region":{"startLine":157}}}],"partialFingerprints":{"codehealthFindingId/v1":"ea0285375f7b8a678b5bdd439aa3d7d528d2d38056be3050ebe478f0d21d8a1c"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (28 lines \u00D7 2): backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:1773-1800 | backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:1437-1464 \u2014 before extracting anything, compare \u0060backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py\u0060 and \u0060backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py\u0060 as WHOLE FILES: this scan already matched 79 separate duplicated blocks between them, totalling at least 2758 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py"},"region":{"startLine":1773}}}],"partialFingerprints":{"codehealthFindingId/v1":"95a584ad7c68a82abbae1cab73574ad28f895355debd3e667d71acbe48ccfbc4"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (14\u201327 lines \u00D7 2): backend/channels/gateway.py:1920-1946 | backend/channels/gateway.py:2044-2057 \u2014 both copies are in the same file, so extract the block 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 \u0060backend/channels/gateway.py:1920\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":"backend/channels/gateway.py"},"region":{"startLine":1920}}}],"partialFingerprints":{"codehealthFindingId/v1":"21557a24bd3e36e10951c58e52cea153ebef1db8e180b44bc7367bc3a92e7927"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (22\u201327 lines \u00D7 2): backend/database/sqlite.py:2997-3023 | backend/database/sqlite.py:3046-3067 \u2014 both copies are in the same file, so extract the block 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, \u0060backend/database/sqlite.py:3068\u0060 calls \u0060fetchone\u0060, \u0060execute\u0060 and \u0060backend/database/sqlite.py:3024\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":"backend/database/sqlite.py"},"region":{"startLine":2997}}}],"partialFingerprints":{"codehealthFindingId/v1":"1767324fffed95fe93cdfbe43cf2098c35e734c535f49da22aa035a64c7f036e"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (20\u201327 lines \u00D7 2): backend/jobs/handlers/memory_health.py:888-914 | backend/jobs/handlers/memory_health.py:1006-1025 \u2014 both copies are in the same file, so extract the block 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":"backend/jobs/handlers/memory_health.py"},"region":{"startLine":888}}}],"partialFingerprints":{"codehealthFindingId/v1":"0ec90da6f961e19fadc9aaa9a67c59f452cb10c8e793764b1d9d696ceb3db8f3"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (27 lines \u00D7 2): backend/skills/s_docx/ooxml/scripts/validation/base.py:128-154 | backend/skills/s_pptx/ooxml/scripts/validation/base.py:128-154 \u2014 before extracting anything, compare \u0060backend/skills/s_docx/ooxml/scripts/validation/base.py\u0060 and \u0060backend/skills/s_pptx/ooxml/scripts/validation/base.py\u0060 as WHOLE FILES: this scan already matched 20 separate duplicated blocks between them, totalling at least 820 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/skills/s_docx/ooxml/scripts/validation/base.py"},"region":{"startLine":128}}}],"partialFingerprints":{"codehealthFindingId/v1":"12d9b1e6ebb8be2b1f150dddd9139b7d9e615c3cc13f6a503e0625d691f32a19"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (14\u201326 lines \u00D7 3): backend/core/evolution/correction_tracker.py:287-312 | backend/core/evolution/correction_tracker.py:350-370 | backend/core/evolution/correction_tracker.py:404-417 \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":"backend/core/evolution/correction_tracker.py"},"region":{"startLine":287}}}],"partialFingerprints":{"codehealthFindingId/v1":"ddacfb46b5aefb92643445e1b13ee52c8907fac557d40938ffdfda318b12097a"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (23\u201326 lines \u00D7 2): backend/core/session_pending.py:431-456 | backend/core/session_pending.py:460-482 \u2014 both copies are in the same file, so extract the block 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":"backend/core/session_pending.py"},"region":{"startLine":431}}}],"partialFingerprints":{"codehealthFindingId/v1":"975ee4b8768f220ae998344c087bdbed1ddcef96884097b333049a9093a03c6f"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (26 lines \u00D7 2): backend/jobs/adapters/eastmoney_market.py:99-124 | backend/jobs/adapters/eastmoney_market.py:156-181 \u2014 both copies are in the same file, so extract the block 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":"backend/jobs/adapters/eastmoney_market.py"},"region":{"startLine":99}}}],"partialFingerprints":{"codehealthFindingId/v1":"f26e531232da3a7745494d0b0131b3f00b842ecc916e29a1cbf5e1ffd67b8326"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (26 lines \u00D7 2): backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:3143-3168 | backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:2796-2821 \u2014 before extracting anything, compare \u0060backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py\u0060 and \u0060backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py\u0060 as WHOLE FILES: this scan already matched 79 separate duplicated blocks between them, totalling at least 2758 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py"},"region":{"startLine":3143}}}],"partialFingerprints":{"codehealthFindingId/v1":"cd8324d37a40252d6fd90ed2ba587953e0ce580e7bdd8f9e2a688df1ebe0848a"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (24\u201325 lines \u00D7 2): backend/core/ddd_job_registry.py:234-257 | backend/core/ddd_skill_registry.py:299-323 \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 \u0060backend/core/ddd_job_registry.py:234\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. \u2605 These copies have DRIFTED, and that is worth reading before extracting anything: just after the matched lines, \u0060backend/core/ddd_skill_registry.py:324\u0060 calls \u0060isinstance\u0060, \u0060get\u0060 and \u0060backend/core/ddd_job_registry.py:258\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":"backend/core/ddd_job_registry.py"},"region":{"startLine":234}}}],"partialFingerprints":{"codehealthFindingId/v1":"6e998a9cbd9c7996eb444930b7d26cff93a5bdefffb9f336abd3027390050450"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (25 lines \u00D7 2): backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:392-416 | backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:392-416 \u2014 before extracting anything, compare \u0060backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py\u0060 and \u0060backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py\u0060 as WHOLE FILES: this scan already matched 79 separate duplicated blocks between them, totalling at least 2758 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":"backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py"},"region":{"startLine":392}}}],"partialFingerprints":{"codehealthFindingId/v1":"47a8d0359f6f10211f94738c9855fe7b408c65a01d37ae5454050378e9f44ec8"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (25 lines \u00D7 2): backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:3572-3596 | backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:3203-3227 \u2014 before extracting anything, compare \u0060backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py\u0060 and \u0060backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py\u0060 as WHOLE FILES: this scan already matched 79 separate duplicated blocks between them, totalling at least 2758 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py"},"region":{"startLine":3572}}}],"partialFingerprints":{"codehealthFindingId/v1":"c25acf8d4370ccfad57c9fc898a28f1555e18b441ee2ccd9ac5bd6a1097a55ea"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (25 lines \u00D7 2): backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:3827-3851 | backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:3458-3482 \u2014 before extracting anything, compare \u0060backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py\u0060 and \u0060backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py\u0060 as WHOLE FILES: this scan already matched 79 separate duplicated blocks between them, totalling at least 2758 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The \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":"backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py"},"region":{"startLine":3827}}}],"partialFingerprints":{"codehealthFindingId/v1":"2941cf093213b8a19b91713cf83bec9afe3fc884b45f4ada61b3c23d4988c6fa"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (11\u201324 lines \u00D7 2): backend/core/ddd_cultivation.py:2437-2460 | backend/core/ddd_cultivation.py:2547-2557 \u2014 both copies are in the same file, so extract the block 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":"backend/core/ddd_cultivation.py"},"region":{"startLine":2437}}}],"partialFingerprints":{"codehealthFindingId/v1":"da16637425b583e21445966f66d73970e8317c600a65ef3dfc807a3c68f78e53"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (17\u201324 lines \u00D7 2): backend/core/security_hooks.py:247-270 | backend/core/security_hooks.py:1634-1650 \u2014 both copies are in the same file, so extract the block 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":"backend/core/security_hooks.py"},"region":{"startLine":247}}}],"partialFingerprints":{"codehealthFindingId/v1":"c6473f3dcd8368060ce8cf53995f7e8fa435e5b246cf825f047a11a9d580612b"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (20\u201324 lines \u00D7 2): backend/hooks/daily_activity_hook.py:56-75 | backend/hooks/todo_lifecycle_hook.py:53-76 \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. 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. Note first that the copies are not typed on the same thing: the declarations holding them bind \u0060max_commits\u0060 to \u0060int = 15\u0060 in one and \u0060int = 50\u0060 in another, and the duplicated lines use it. The extracted unit therefore needs a parameter type that fits BOTH \u2014 their common supertype where they have one, or a new abstraction over them where they do not \u2014 and settling that is the step that comes BEFORE the extraction above. Where the two types are deliberately unrelated, the duplication is the price of that separation and the honest resolution is to record the decision rather than to extract."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/hooks/daily_activity_hook.py"},"region":{"startLine":56}}}],"partialFingerprints":{"codehealthFindingId/v1":"07d8c603f469e7d9ecc2afd3da15e2dbfb05a015610b1390e1706f767a021e7c"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (24 lines \u00D7 2): backend/skills/s_docx/ooxml/scripts/validation/base.py:766-789 | backend/skills/s_pptx/ooxml/scripts/validation/base.py:769-792 \u2014 before extracting anything, compare \u0060backend/skills/s_docx/ooxml/scripts/validation/base.py\u0060 and \u0060backend/skills/s_pptx/ooxml/scripts/validation/base.py\u0060 as WHOLE FILES: this scan already matched 20 separate duplicated blocks between them, totalling at least 820 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The \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":"backend/skills/s_docx/ooxml/scripts/validation/base.py"},"region":{"startLine":766}}}],"partialFingerprints":{"codehealthFindingId/v1":"27045f9c9c80328380212614e411819c91afb2528ddc71f822fe603d5b8c14bc"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (20\u201323 lines \u00D7 2): backend/channels/gateway.py:1954-1976 | backend/channels/gateway.py:2058-2077 \u2014 both copies are in the same file, so extract the block 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":"backend/channels/gateway.py"},"region":{"startLine":1954}}}],"partialFingerprints":{"codehealthFindingId/v1":"b44f85baa896ff3cdedb19d18c2ff3d9977901453e58ffa29761fcde71841516"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (23 lines \u00D7 2): backend/core/daemon_guard.py:296-318 | desktop/resources/daemon/daemon_guard.py:296-318 \u2014 before extracting anything, compare \u0060backend/core/daemon_guard.py\u0060 and \u0060desktop/resources/daemon/daemon_guard.py\u0060 as WHOLE FILES: this scan already matched 11 separate duplicated blocks between them, totalling at least 280 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/core/daemon_guard.py"},"region":{"startLine":296}}}],"partialFingerprints":{"codehealthFindingId/v1":"0a1182fba739632ef35bd5d8fd7f1ed4f6548cd1123150e76d10787269ab061b"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (19\u201323 lines \u00D7 2): backend/core/proactive_intelligence.py:991-1009 | backend/core/proactive_intelligence.py:1114-1136 \u2014 both copies are in the same file, so extract the block 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":"backend/core/proactive_intelligence.py"},"region":{"startLine":991}}}],"partialFingerprints":{"codehealthFindingId/v1":"5abd10df43a1141e1bf8f9dcd8dfc5eefef3bd32fc22bfb6dc019c687296a7db"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (20\u201323 lines \u00D7 2): backend/core/task_manager.py:271-293 | backend/core/task_manager.py:358-377 \u2014 both copies are in the same file, so extract the block 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, \u0060backend/core/task_manager.py:266\u0060 calls \u0060get\u0060, \u0060update\u0060 and \u0060backend/core/task_manager.py:357\u0060 does not \u2014 after which the two agree again for 2 more lines. One of those two behaviours is the intended one and the other is what a copy-paste left behind, so decide which BEFORE unifying them: extracting the shared part will silently settle it, and if the copy that skips the call is the wrong one, that bug is already live."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/core/task_manager.py"},"region":{"startLine":271}}}],"partialFingerprints":{"codehealthFindingId/v1":"c522db06869ee18e0ab2dd52d50ffd4bb36f974e0da1af18f5bbcfca45803d5b"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (15\u201323 lines \u00D7 2): backend/database/sqlite.py:2934-2956 | backend/database/sqlite.py:3028-3042 \u2014 both copies are in the same file, so extract the block 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":"backend/database/sqlite.py"},"region":{"startLine":2934}}}],"partialFingerprints":{"codehealthFindingId/v1":"0aa9f8e52c63f044c53472170e1bbbe3c5ac28f813e056db5c073d9ed3587b64"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (23 lines \u00D7 2): backend/skills/s_docx/ooxml/scripts/pack.py:20-42 | backend/skills/s_pptx/ooxml/scripts/pack.py:20-42 \u2014 before extracting anything, compare \u0060backend/skills/s_docx/ooxml/scripts/pack.py\u0060 and \u0060backend/skills/s_pptx/ooxml/scripts/pack.py\u0060 as WHOLE FILES: this scan already matched 4 separate duplicated blocks between them, totalling at least 127 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":"backend/skills/s_docx/ooxml/scripts/pack.py"},"region":{"startLine":20}}}],"partialFingerprints":{"codehealthFindingId/v1":"a8d87a0ce1fd7cbb379edf04bcc44f67fcde95f4d6c3addf96f30ee64734b782"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (23 lines \u00D7 2): backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:64-86 | backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:64-86 \u2014 before extracting anything, compare \u0060backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py\u0060 and \u0060backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py\u0060 as WHOLE FILES: this scan already matched 79 separate duplicated blocks between them, totalling at least 2758 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py"},"region":{"startLine":64}}}],"partialFingerprints":{"codehealthFindingId/v1":"07953cdd558653c16dfa458b6b3a7cbde82f245276dec40e4840b967aeb956d8"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (23 lines \u00D7 2): backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:734-756 | backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:648-670 \u2014 before extracting anything, compare \u0060backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py\u0060 and \u0060backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py\u0060 as WHOLE FILES: this scan already matched 79 separate duplicated blocks between them, totalling at least 2758 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 \u0060backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.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. 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":"backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py"},"region":{"startLine":734}}}],"partialFingerprints":{"codehealthFindingId/v1":"a3e6980b72fdb90a127dd1b497c9af5f7398aca2a1defa34939055d90c478ca9"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (23 lines \u00D7 2): backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:2151-2173 | backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:1803-1825 \u2014 before extracting anything, compare \u0060backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py\u0060 and \u0060backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py\u0060 as WHOLE FILES: this scan already matched 79 separate duplicated blocks between them, totalling at least 2758 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py"},"region":{"startLine":2151}}}],"partialFingerprints":{"codehealthFindingId/v1":"05eb8b32ce85dd3acf58ae0968310d1e5d9b6cd1beafa00d4491e5ecc76dc190"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (23 lines \u00D7 2): backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:2835-2857 | backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:2488-2510 \u2014 before extracting anything, compare \u0060backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py\u0060 and \u0060backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py\u0060 as WHOLE FILES: this scan already matched 79 separate duplicated blocks between them, totalling at least 2758 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 \u0060backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:2835\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":"backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py"},"region":{"startLine":2835}}}],"partialFingerprints":{"codehealthFindingId/v1":"509b3da608d43300c0b59d79f9e8ec0fb82ecbc47fa29f8ac8b7219a08ff6ecc"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (22 lines \u00D7 2): backend/core/context_injector.py:325-346 | backend/core/context_injector.py:363-384 \u2014 both copies are in the same file, so extract the block 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":"backend/core/context_injector.py"},"region":{"startLine":325}}}],"partialFingerprints":{"codehealthFindingId/v1":"2df5337ce567a301d3f5a260c4306c5229f8921a19e7185a0862a7611a518487"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (18\u201322 lines \u00D7 2): backend/hooks/distillation_hook.py:1208-1225 | backend/hooks/distillation_hook.py:1238-1259 \u2014 both copies are in the same file, so extract the block 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":"backend/hooks/distillation_hook.py"},"region":{"startLine":1208}}}],"partialFingerprints":{"codehealthFindingId/v1":"e2be1854212612bf8c91bf207611aaf333b0347f4b4b58aa983f08a09cbe0149"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (17\u201322 lines \u00D7 2): backend/jobs/handlers/memory_health.py:660-681 | backend/jobs/handlers/memory_health.py:743-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."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/jobs/handlers/memory_health.py"},"region":{"startLine":660}}}],"partialFingerprints":{"codehealthFindingId/v1":"5a875c17c9fb5f8fde5f50ba48e68f1cbe3d3e9ae604672ee260a3bd050e1cd7"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (22 lines \u00D7 2): backend/skills/s_docx/ooxml/scripts/pack.py:134-155 | backend/skills/s_pptx/ooxml/scripts/pack.py:134-155 \u2014 before extracting anything, compare \u0060backend/skills/s_docx/ooxml/scripts/pack.py\u0060 and \u0060backend/skills/s_pptx/ooxml/scripts/pack.py\u0060 as WHOLE FILES: this scan already matched 4 separate duplicated blocks between them, totalling at least 127 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/skills/s_docx/ooxml/scripts/pack.py"},"region":{"startLine":134}}}],"partialFingerprints":{"codehealthFindingId/v1":"b6ac4c464b542985167d8e8f56cb36de49dd3d0741fe6d92c41e9cbcfdafc6cb"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (22 lines \u00D7 2): backend/skills/s_docx/ooxml/scripts/validation/base.py:742-763 | backend/skills/s_pptx/ooxml/scripts/validation/base.py:745-766 \u2014 before extracting anything, compare \u0060backend/skills/s_docx/ooxml/scripts/validation/base.py\u0060 and \u0060backend/skills/s_pptx/ooxml/scripts/validation/base.py\u0060 as WHOLE FILES: this scan already matched 20 separate duplicated blocks between them, totalling at least 820 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/skills/s_docx/ooxml/scripts/validation/base.py"},"region":{"startLine":742}}}],"partialFingerprints":{"codehealthFindingId/v1":"df031cb76a840e80bbf44a7f2cdf0c6ffd6b22d30231b37b99385128dcef2280"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (22 lines \u00D7 2): backend/skills/s_docx/ooxml/scripts/validation/base.py:792-813 | backend/skills/s_pptx/ooxml/scripts/validation/base.py:795-816 \u2014 before extracting anything, compare \u0060backend/skills/s_docx/ooxml/scripts/validation/base.py\u0060 and \u0060backend/skills/s_pptx/ooxml/scripts/validation/base.py\u0060 as WHOLE FILES: this scan already matched 20 separate duplicated blocks between them, totalling at least 820 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/skills/s_docx/ooxml/scripts/validation/base.py"},"region":{"startLine":792}}}],"partialFingerprints":{"codehealthFindingId/v1":"f14d3f2cb1e7a00601690093f9e368f5d62249b8f0291e7243df74e2d6a099de"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (22 lines \u00D7 2): backend/skills/s_docx/ooxml/scripts/validation/docx.py:193-214 | backend/skills/s_pptx/ooxml/scripts/validation/docx.py:193-214 \u2014 before extracting anything, compare \u0060backend/skills/s_docx/ooxml/scripts/validation/docx.py\u0060 and \u0060backend/skills/s_pptx/ooxml/scripts/validation/docx.py\u0060 as WHOLE FILES: this scan already matched 11 separate duplicated blocks between them, totalling at least 244 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The \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":"backend/skills/s_docx/ooxml/scripts/validation/docx.py"},"region":{"startLine":193}}}],"partialFingerprints":{"codehealthFindingId/v1":"4e3288627d960217ae96867e9c8960065936cb4db076b06f00841eb477db4d02"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (22 lines \u00D7 2): backend/skills/s_frontend-design/scripts/core.py:127-148 | backend/skills/s_web-design-review/scripts/core.py:127-148 \u2014 before extracting anything, compare \u0060backend/skills/s_frontend-design/scripts/core.py\u0060 and \u0060backend/skills/s_web-design-review/scripts/core.py\u0060 as WHOLE FILES: this scan already matched 7 separate duplicated blocks between them, totalling at least 126 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":"backend/skills/s_frontend-design/scripts/core.py"},"region":{"startLine":127}}}],"partialFingerprints":{"codehealthFindingId/v1":"aa511abd83e5ad7d88b5ba76f49aba3311fa2f8053256968d45bb72570146e3c"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (22 lines \u00D7 2): backend/skills/s_frontend-design/scripts/core.py:159-180 | backend/skills/s_web-design-review/scripts/core.py:159-180 \u2014 before extracting anything, compare \u0060backend/skills/s_frontend-design/scripts/core.py\u0060 and \u0060backend/skills/s_web-design-review/scripts/core.py\u0060 as WHOLE FILES: this scan already matched 7 separate duplicated blocks between them, totalling at least 126 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/skills/s_frontend-design/scripts/core.py"},"region":{"startLine":159}}}],"partialFingerprints":{"codehealthFindingId/v1":"018f8be15119a3cb6faf931cc0cc205077d7ff89a2279d179bc3acdbe394c5fa"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (20\u201322 lines \u00D7 2): backend/skills/s_frontend-design/scripts/design_system.py:461-482 | backend/skills/s_frontend-design/scripts/design_system.py:647-666 \u2014 both copies are in the same file, so extract the block 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":"backend/skills/s_frontend-design/scripts/design_system.py"},"region":{"startLine":461}}}],"partialFingerprints":{"codehealthFindingId/v1":"8f943d6338573209ddf3c585f2cc72a50340e7cdc4e8f3167c72cd9392904055"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (22 lines \u00D7 2): backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:604-625 | backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:518-539 \u2014 before extracting anything, compare \u0060backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py\u0060 and \u0060backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py\u0060 as WHOLE FILES: this scan already matched 79 separate duplicated blocks between them, totalling at least 2758 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py"},"region":{"startLine":604}}}],"partialFingerprints":{"codehealthFindingId/v1":"7204be0b9c49a66bcd12c6119461bbb847f9c80bff2f6dadd61650b512c28bc9"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (21 lines \u00D7 3): backend/scripts/locked_write.py:59-79 | backend/skills/s_persist/scripts/locked_write.py:59-79 | backend/templates/ddd-skills/s_ddd-persist/scripts/locked_write.py:59-79 \u2014 before extracting anything, compare \u0060backend/scripts/locked_write.py\u0060 and \u0060backend/skills/s_persist/scripts/locked_write.py\u0060 as WHOLE FILES: this scan already matched 10 separate duplicated blocks between them, totalling at least 456 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/scripts/locked_write.py"},"region":{"startLine":59}}}],"partialFingerprints":{"codehealthFindingId/v1":"592d9ae36071f1d3b2f50a7178a5a4bf7b6d0d8b649f84394a301a022f11254e"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (13\u201321 lines \u00D7 3): backend/skills/s_notify/notify.py:94-114 | backend/skills/s_notify/notify.py:118-130 | backend/skills/s_notify/notify.py:134-146 \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":"backend/skills/s_notify/notify.py"},"region":{"startLine":94}}}],"partialFingerprints":{"codehealthFindingId/v1":"5447f6aecf63004ef22ef9befa63e3cf048e89b17e26c4e1ac1cfa9625eede39"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (12\u201321 lines \u00D7 2): backend/core/chat_thread_manager.py:90-101 | backend/core/todo_manager.py:519-539 \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":"backend/core/chat_thread_manager.py"},"region":{"startLine":90}}}],"partialFingerprints":{"codehealthFindingId/v1":"6368965413f59e299cef2a3b51cde95f3fd4c2caa829d42c20c13614ac9e9c38"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (21 lines \u00D7 2): backend/core/daemon_guard.py:104-124 | desktop/resources/daemon/daemon_guard.py:104-124 \u2014 before extracting anything, compare \u0060backend/core/daemon_guard.py\u0060 and \u0060desktop/resources/daemon/daemon_guard.py\u0060 as WHOLE FILES: this scan already matched 11 separate duplicated blocks between them, totalling at least 280 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/core/daemon_guard.py"},"region":{"startLine":104}}}],"partialFingerprints":{"codehealthFindingId/v1":"ffa8b0167a23e45aaffe97f7ecab7fc1e192a6a7ff987062dc798a6035421151"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (19\u201321 lines \u00D7 2): backend/core/proactive_intelligence.py:511-529 | backend/core/proactive_scoring.py:84-104 \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":"backend/core/proactive_intelligence.py"},"region":{"startLine":511}}}],"partialFingerprints":{"codehealthFindingId/v1":"499fa45cb367c9c642d3ac4b02583481e80d7c625a06543bf689ebb5a125e5bd"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (17\u201321 lines \u00D7 2): backend/core/recall_multi.py:753-773 | backend/core/recall_multi.py:788-804 \u2014 both copies are in the same file, so extract the block 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":"backend/core/recall_multi.py"},"region":{"startLine":753}}}],"partialFingerprints":{"codehealthFindingId/v1":"ab95b631d60879144d920ac37b9c1f407a132d862fd962698ae101eb51b519f9"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (21 lines \u00D7 2): backend/core/search_manager.py:228-248 | backend/core/search_manager.py:307-327 \u2014 both copies are in the same file, so extract the block into one function there and call it from each site \u2014 the copies drift apart the first time only one of them is edited. Read the line range as the matched WINDOW rather than a finished unit: at \u0060backend/core/search_manager.py:228\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":"backend/core/search_manager.py"},"region":{"startLine":228}}}],"partialFingerprints":{"codehealthFindingId/v1":"2d346d71e043cafc209c0930da865e6e9e8c355d5f3f6845d542feb522997217"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (21 lines \u00D7 2): backend/skills/s_docx/ooxml/scripts/validation/redlining.py:255-275 | backend/skills/s_pptx/ooxml/scripts/validation/redlining.py:255-275 \u2014 before extracting anything, compare \u0060backend/skills/s_docx/ooxml/scripts/validation/redlining.py\u0060 and \u0060backend/skills/s_pptx/ooxml/scripts/validation/redlining.py\u0060 as WHOLE FILES: this scan already matched 5 separate duplicated blocks between them, totalling at least 245 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The \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":"backend/skills/s_docx/ooxml/scripts/validation/redlining.py"},"region":{"startLine":255}}}],"partialFingerprints":{"codehealthFindingId/v1":"3f3e2ab7f929267e76a832d27548625cd426e47c028433910ccea7cdf67bffe6"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (16\u201320 lines \u00D7 3): backend/core/security_hooks.py:260-279 | backend/core/security_hooks.py:648-664 | backend/core/security_hooks.py:1644-1659 \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":"backend/core/security_hooks.py"},"region":{"startLine":260}}}],"partialFingerprints":{"codehealthFindingId/v1":"6bb6e386a39cf09544b7d84acf02ff353090778a08768b9fcb4377bf9595c7a4"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (18\u201320 lines \u00D7 2): backend/core/ddd_entry_lifecycle.py:1827-1846 | backend/core/ddd_entry_lifecycle.py:1879-1896 \u2014 both copies are in the same file, so extract the block 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":"backend/core/ddd_entry_lifecycle.py"},"region":{"startLine":1827}}}],"partialFingerprints":{"codehealthFindingId/v1":"ba8ea44e516d68146d7ed253b53393688bfed4dce7b9d285ceb7ee501e3111ef"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (19\u201320 lines \u00D7 2): backend/core/engine_metrics.py:279-298 | backend/jobs/handlers/ddd_refresh.py:384-402 \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":"backend/core/engine_metrics.py"},"region":{"startLine":279}}}],"partialFingerprints":{"codehealthFindingId/v1":"6d39344ff62d268aa7bb6a1b29d69319ee96381b9cc713fdc52aecc23c9b9307"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (18\u201320 lines \u00D7 2): backend/core/session_unit.py:2456-2475 | backend/core/session_unit.py:4774-4791 \u2014 both copies are in the same file, so extract the block 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 \u0060backend/core/session_unit.py:2456\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":"backend/core/session_unit.py"},"region":{"startLine":2456}}}],"partialFingerprints":{"codehealthFindingId/v1":"75bf095d7f0ce9afcbd7823b65b96d0a396f76b018da95da55c45fd33a45d1bb"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (20 lines \u00D7 2): backend/routers/workspace.py:326-345 | backend/routers/workspace.py:415-434 \u2014 both copies are in the same file, so extract the block 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":"backend/routers/workspace.py"},"region":{"startLine":326}}}],"partialFingerprints":{"codehealthFindingId/v1":"b362c946cba3c3992f254cd2a00d60509331964710d5b11f2dd877a1e2354fda"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9\u201320 lines \u00D7 2): backend/scripts/pipeline_analytics.py:809-828 | backend/scripts/pipeline_analytics.py:891-899 \u2014 both copies are in the same file, so extract the block 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":"backend/scripts/pipeline_analytics.py"},"region":{"startLine":809}}}],"partialFingerprints":{"codehealthFindingId/v1":"7211fd02a62c8d900428ba17b644242d894e7423e0b41fe089d318b9ef66dee0"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (19 lines \u00D7 2): backend/core/ddd_cultivation.py:2487-2505 | backend/core/ddd_cultivation.py:2573-2591 \u2014 both copies are in the same file, so extract the block 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":"backend/core/ddd_cultivation.py"},"region":{"startLine":2487}}}],"partialFingerprints":{"codehealthFindingId/v1":"ef0acc68f6f6acb5fadfc3ceedee1b5eba7bf8c9341517f0029e78f7e7673673"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (19 lines \u00D7 2): backend/core/memory_extractor.py:208-226 | backend/core/summarization.py:787-805 \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":"backend/core/memory_extractor.py"},"region":{"startLine":208}}}],"partialFingerprints":{"codehealthFindingId/v1":"fd04ccbde8eb70e2d17598565619a22f82167182d6bbbf08cb3e181ec9bef5d1"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (19 lines \u00D7 2): backend/core/proactive_intelligence.py:277-295 | backend/hooks/distillation_hook.py:2071-2089 \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":"backend/core/proactive_intelligence.py"},"region":{"startLine":277}}}],"partialFingerprints":{"codehealthFindingId/v1":"6259f0e146efd53822872b852e7d5a5a72245d293cf7d5ab45cafd9d7c103ea8"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (11\u201319 lines \u00D7 2): backend/core/resource_monitor.py:470-480 | backend/core/resource_monitor.py:587-605 \u2014 both copies are in the same file, so extract the block 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":"backend/core/resource_monitor.py"},"region":{"startLine":470}}}],"partialFingerprints":{"codehealthFindingId/v1":"fa88afc366ac3fd5028a8a68db8c5ff278d26ba45c9743c7e1b6ec1d271e1686"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (16\u201319 lines \u00D7 2): backend/hooks/code_change_feed.py:125-143 | backend/hooks/code_change_feed.py:265-280 \u2014 both copies are in the same file, so extract the block 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":"backend/hooks/code_change_feed.py"},"region":{"startLine":125}}}],"partialFingerprints":{"codehealthFindingId/v1":"9aa972655d82fc10951aa1725c2da4600d5f0c12daea736f379a361366559072"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (17\u201319 lines \u00D7 2): backend/scripts/pipeline_validator.py:1719-1737 | backend/scripts/pipeline_validator.py:1746-1762 \u2014 both copies are in the same file, so extract the block 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":"backend/scripts/pipeline_validator.py"},"region":{"startLine":1719}}}],"partialFingerprints":{"codehealthFindingId/v1":"3ef0cbadc14f430ad77b4ddc6def1f2a17a3b2bcbfce8586eebf34f776a5a6f5"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (19 lines \u00D7 2): backend/skills/s_frontend-design/scripts/core.py:184-202 | backend/skills/s_web-design-review/scripts/core.py:184-202 \u2014 before extracting anything, compare \u0060backend/skills/s_frontend-design/scripts/core.py\u0060 and \u0060backend/skills/s_web-design-review/scripts/core.py\u0060 as WHOLE FILES: this scan already matched 7 separate duplicated blocks between them, totalling at least 126 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":"backend/skills/s_frontend-design/scripts/core.py"},"region":{"startLine":184}}}],"partialFingerprints":{"codehealthFindingId/v1":"9f822c92fecfd2972b41e30b1f5a95a46ea22eef734c35f65c1d8b4af4af2942"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (19 lines \u00D7 2): backend/skills/s_frontend-design/scripts/core.py:207-225 | backend/skills/s_web-design-review/scripts/core.py:207-225 \u2014 before extracting anything, compare \u0060backend/skills/s_frontend-design/scripts/core.py\u0060 and \u0060backend/skills/s_web-design-review/scripts/core.py\u0060 as WHOLE FILES: this scan already matched 7 separate duplicated blocks between them, totalling at least 126 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/skills/s_frontend-design/scripts/core.py"},"region":{"startLine":207}}}],"partialFingerprints":{"codehealthFindingId/v1":"117e28cc53dc2ecdc69d1beef33d23674b4762bd2e39251022c39f30bddaf8d3"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (19 lines \u00D7 2): backend/skills/s_frontend-design/scripts/core.py:229-247 | backend/skills/s_web-design-review/scripts/core.py:229-247 \u2014 before extracting anything, compare \u0060backend/skills/s_frontend-design/scripts/core.py\u0060 and \u0060backend/skills/s_web-design-review/scripts/core.py\u0060 as WHOLE FILES: this scan already matched 7 separate duplicated blocks between them, totalling at least 126 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/skills/s_frontend-design/scripts/core.py"},"region":{"startLine":229}}}],"partialFingerprints":{"codehealthFindingId/v1":"5e69138f16985b599a5b83ee50ca0e47c08247d5575ebff4b1d0c2a53351be7f"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (19 lines \u00D7 2): backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:1353-1371 | backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:1070-1088 \u2014 before extracting anything, compare \u0060backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py\u0060 and \u0060backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py\u0060 as WHOLE FILES: this scan already matched 79 separate duplicated blocks between them, totalling at least 2758 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 \u0060backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:1353\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":"backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py"},"region":{"startLine":1353}}}],"partialFingerprints":{"codehealthFindingId/v1":"412a10cd5a9cb36050060afaeb1764c7cac6fd538878e27b7acfa5cbbc7d2caa"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (19 lines \u00D7 2): backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:3679-3697 | backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:3310-3328 \u2014 before extracting anything, compare \u0060backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py\u0060 and \u0060backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py\u0060 as WHOLE FILES: this scan already matched 79 separate duplicated blocks between them, totalling at least 2758 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py"},"region":{"startLine":3679}}}],"partialFingerprints":{"codehealthFindingId/v1":"288386c212a9cceeb6a859326719c7ffcb9ef153f251e0707eb02180a7011c82"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (18 lines \u00D7 2): backend/core/daemon_guard.py:162-179 | desktop/resources/daemon/daemon_guard.py:162-179 \u2014 before extracting anything, compare \u0060backend/core/daemon_guard.py\u0060 and \u0060desktop/resources/daemon/daemon_guard.py\u0060 as WHOLE FILES: this scan already matched 11 separate duplicated blocks between them, totalling at least 280 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/core/daemon_guard.py"},"region":{"startLine":162}}}],"partialFingerprints":{"codehealthFindingId/v1":"5f3a3b141608871d7427a0a0257bfcd91555e5ec44c34eaec6fa56cc95875b56"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (18 lines \u00D7 2): backend/core/evolution/governance_router.py:94-111 | backend/core/evolution/governance_router.py:304-321 \u2014 both copies are in the same file, so extract the block 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":"backend/core/evolution/governance_router.py"},"region":{"startLine":94}}}],"partialFingerprints":{"codehealthFindingId/v1":"227c5647f045c6b8a783a9233dde8aa4cfc18eaec5bdc9b87ff76aedd9e924b9"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (18 lines \u00D7 2): backend/skills/s_docx/ooxml/scripts/validation/base.py:187-204 | backend/skills/s_pptx/ooxml/scripts/validation/base.py:187-204 \u2014 before extracting anything, compare \u0060backend/skills/s_docx/ooxml/scripts/validation/base.py\u0060 and \u0060backend/skills/s_pptx/ooxml/scripts/validation/base.py\u0060 as WHOLE FILES: this scan already matched 20 separate duplicated blocks between them, totalling at least 820 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. \u2605 These copies have DRIFTED, and that is worth reading before extracting anything: just after the matched lines, \u0060backend/skills/s_pptx/ooxml/scripts/validation/base.py:207\u0060 calls \u0060isinstance\u0060 and \u0060backend/skills/s_docx/ooxml/scripts/validation/base.py:206\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":"backend/skills/s_docx/ooxml/scripts/validation/base.py"},"region":{"startLine":187}}}],"partialFingerprints":{"codehealthFindingId/v1":"23cf2b4a5c45e43a467633bc8e82f9324b570c28868a15ee99a27d187210bb56"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (18 lines \u00D7 2): backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:1460-1477 | backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:1171-1188 \u2014 before extracting anything, compare \u0060backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py\u0060 and \u0060backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py\u0060 as WHOLE FILES: this scan already matched 79 separate duplicated blocks between them, totalling at least 2758 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":"backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py"},"region":{"startLine":1460}}}],"partialFingerprints":{"codehealthFindingId/v1":"4b4197e3ad40f09bbc9ae58caaefe90dfda3b7f21689e2e2b8aa4d35decca407"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (18 lines \u00D7 2): backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:1804-1821 | backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:1468-1485 \u2014 before extracting anything, compare \u0060backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py\u0060 and \u0060backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py\u0060 as WHOLE FILES: this scan already matched 79 separate duplicated blocks between them, totalling at least 2758 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":"backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py"},"region":{"startLine":1804}}}],"partialFingerprints":{"codehealthFindingId/v1":"6d64d7931c7f8b2f9232b311fe26e3a7f615e013c99f8248d6c3a6f0c4d83dae"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (12\u201317 lines \u00D7 3): backend/routers/hive.py:528-539 | backend/routers/hive.py:575-586 | backend/routers/hive.py:669-685 \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":"backend/routers/hive.py"},"region":{"startLine":528}}}],"partialFingerprints":{"codehealthFindingId/v1":"3362fbcafdaffc5ed8c295adb56d28cd1a53279567e0a65037c8d86b2a6e86ae"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (15\u201317 lines \u00D7 3): backend/skills/s_frontend-design/scripts/design_system.py:718-732 | backend/skills/s_frontend-design/scripts/design_system.py:751-765 | backend/skills/s_frontend-design/scripts/design_system.py:781-797 \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":"backend/skills/s_frontend-design/scripts/design_system.py"},"region":{"startLine":718}}}],"partialFingerprints":{"codehealthFindingId/v1":"f75f475700ec6cb6c4b1d71d4e1cd4df24fb5f21091f43a8f71249ff328066eb"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (17 lines \u00D7 2): backend/core/ddd_job_registry.py:214-230 | backend/core/ddd_skill_registry.py:279-295 \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":"backend/core/ddd_job_registry.py"},"region":{"startLine":214}}}],"partialFingerprints":{"codehealthFindingId/v1":"63d110183aaaa0eeebf76e416177f8b2348d1e9baf1e818c5c69b1167295d119"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (12\u201317 lines \u00D7 2): backend/core/voice_synthesize.py:317-333 | backend/skills/s_pollinate/scripts/tts/backends/polly.py:173-184 \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":"backend/core/voice_synthesize.py"},"region":{"startLine":317}}}],"partialFingerprints":{"codehealthFindingId/v1":"75195aaf74362f48198c2e3d08308ebeb50bb5b0ad7dce3621f15cb1d9f24660"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (17 lines \u00D7 2): backend/database/sqlite.py:2911-2927 | backend/database/sqlite.py:2948-2964 \u2014 both copies are in the same file, so extract the block 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":"backend/database/sqlite.py"},"region":{"startLine":2911}}}],"partialFingerprints":{"codehealthFindingId/v1":"3fddcf8220257c57f0e0075f74854c7aadcc73887a7e5296a446abc462c5884b"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (15\u201317 lines \u00D7 2): backend/middleware/error_handler.py:98-114 | backend/middleware/error_handler.py:140-154 \u2014 both copies are in the same file, so extract the block 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 \u0060backend/middleware/error_handler.py:98\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. Note first that the copies are not typed on the same thing: the declarations holding them bind \u0060exc\u0060 to \u0060RequestValidationError\u0060 in one and \u0060ValidationError\u0060 in another, and the duplicated lines use it. The extracted unit therefore needs a parameter type that fits BOTH \u2014 their common supertype where they have one, or a new abstraction over them where they do not \u2014 and settling that is the step that comes BEFORE the extraction above. Where the two types are deliberately unrelated, the duplication is the price of that separation and the honest resolution is to record the decision rather than to extract."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/middleware/error_handler.py"},"region":{"startLine":98}}}],"partialFingerprints":{"codehealthFindingId/v1":"fb63ec9e6c90aa61299f6d22f9419bb5f4f1e1f4cf04bc98e25856c6292463f4"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (17 lines \u00D7 2): backend/skills/s_docx/ooxml/scripts/validation/docx.py:174-190 | backend/skills/s_pptx/ooxml/scripts/validation/docx.py:174-190 \u2014 before extracting anything, compare \u0060backend/skills/s_docx/ooxml/scripts/validation/docx.py\u0060 and \u0060backend/skills/s_pptx/ooxml/scripts/validation/docx.py\u0060 as WHOLE FILES: this scan already matched 11 separate duplicated blocks between them, totalling at least 244 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/skills/s_docx/ooxml/scripts/validation/docx.py"},"region":{"startLine":174}}}],"partialFingerprints":{"codehealthFindingId/v1":"6cdbbab5b25bd64f3a1a2d4a0fe70d162cf35a53515d87d30701a9b705b7635f"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (17 lines \u00D7 2): backend/skills/s_frontend-design/scripts/core.py:108-124 | backend/skills/s_web-design-review/scripts/core.py:108-124 \u2014 before extracting anything, compare \u0060backend/skills/s_frontend-design/scripts/core.py\u0060 and \u0060backend/skills/s_web-design-review/scripts/core.py\u0060 as WHOLE FILES: this scan already matched 7 separate duplicated blocks between them, totalling at least 126 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/skills/s_frontend-design/scripts/core.py"},"region":{"startLine":108}}}],"partialFingerprints":{"codehealthFindingId/v1":"438af5725978091893399bf613fe5927a6195914612aeb154cdaa8e82b4571b6"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (17 lines \u00D7 2): backend/skills/s_frontend-design/scripts/design_system.py:634-650 | backend/skills/s_frontend-design/scripts/design_system.py:898-914 \u2014 both copies are in the same file, so extract the block 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":"backend/skills/s_frontend-design/scripts/design_system.py"},"region":{"startLine":634}}}],"partialFingerprints":{"codehealthFindingId/v1":"ffa40e608525e76126ad38c85aee403e28116d980c60b0f803c9ed3c08c76cee"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (14\u201316 lines \u00D7 3): backend/core/context_injector.py:331-346 | backend/core/context_injector.py:369-384 | backend/core/context_injector.py:405-418 \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. 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, \u0060backend/core/context_injector.py:404\u0060 calls \u0060set\u0060 and \u0060backend/core/context_injector.py:330\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":"backend/core/context_injector.py"},"region":{"startLine":331}}}],"partialFingerprints":{"codehealthFindingId/v1":"e8fa5d8c57fd9f6c7d0b38d3ecf911ae6ad16c37655e47b36fd6f3274ba58a16"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (12\u201316 lines \u00D7 3): backend/core/security_hooks.py:285-299 | backend/core/security_hooks.py:670-681 | backend/core/security_hooks.py:1593-1608 \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":"backend/core/security_hooks.py"},"region":{"startLine":285}}}],"partialFingerprints":{"codehealthFindingId/v1":"abd0109fa6607dab369428f5d266bb1096deec46f3f9e36e2e8809d349e7a72a"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (14\u201316 lines \u00D7 3): backend/jobs/handlers/ddd_refresh.py:248-261 | backend/jobs/handlers/memory_health.py:473-486 | backend/jobs/handlers/skill_proposer.py:291-306 \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 \u0060backend/jobs/handlers/ddd_refresh.py:248\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":"backend/jobs/handlers/ddd_refresh.py"},"region":{"startLine":248}}}],"partialFingerprints":{"codehealthFindingId/v1":"ae1d5af5799661824251f2a51566fc555f837b04431a6ef55eb7b57d18882271"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (16 lines \u00D7 2): backend/hive/provisioner.py:1260-1275 | backend/hive/provisioner.py:1436-1451 \u2014 both copies are in the same file, so extract the block 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 \u0060backend/hive/provisioner.py:1260\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":"backend/hive/provisioner.py"},"region":{"startLine":1260}}}],"partialFingerprints":{"codehealthFindingId/v1":"e23760b4d363bfd18619691d5d7033e1119f5a245bddc9fdec13fdf40689c8c4"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (14\u201316 lines \u00D7 2): backend/jobs/adapters/rss.py:100-115 | backend/jobs/adapters/rss.py:133-146 \u2014 both copies are in the same file, so extract the block 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 \u0060backend/jobs/adapters/rss.py:100\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":"backend/jobs/adapters/rss.py"},"region":{"startLine":100}}}],"partialFingerprints":{"codehealthFindingId/v1":"fe3c86a4681da4cf66cf4ae965feba09bad66bbe0d1435f52ab057bbef46b081"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (16 lines \u00D7 2): backend/routers/mcp.py:222-237 | backend/routers/mcp.py:259-274 \u2014 both copies are in the same file, so extract the block 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 \u0060backend/routers/mcp.py:222\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":"backend/routers/mcp.py"},"region":{"startLine":222}}}],"partialFingerprints":{"codehealthFindingId/v1":"1dfc7713685d2b0346fe5681e64e583b1bbbc96ce264130404099b01a42e127a"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (16 lines \u00D7 2): backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:1484-1499 | backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:1195-1210 \u2014 before extracting anything, compare \u0060backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py\u0060 and \u0060backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py\u0060 as WHOLE FILES: this scan already matched 79 separate duplicated blocks between them, totalling at least 2758 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":"backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py"},"region":{"startLine":1484}}}],"partialFingerprints":{"codehealthFindingId/v1":"549f0ab611208753afdafc6d474d5b825024e1bc6c204ba6cbb67be06fc00d17"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (16 lines \u00D7 2): backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:2132-2147 | backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:1781-1796 \u2014 before extracting anything, compare \u0060backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py\u0060 and \u0060backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py\u0060 as WHOLE FILES: this scan already matched 79 separate duplicated blocks between them, totalling at least 2758 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":"backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py"},"region":{"startLine":2132}}}],"partialFingerprints":{"codehealthFindingId/v1":"c23fe5ede9490b1dac9ddbf8af4b6993e2f1e37d91b0c3240211e019fafcd644"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (13\u201315 lines \u00D7 3): backend/database/sqlite.py:2907-2921 | backend/database/sqlite.py:2993-3005 | backend/database/sqlite.py:3024-3036 \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":"backend/database/sqlite.py"},"region":{"startLine":2907}}}],"partialFingerprints":{"codehealthFindingId/v1":"91addc054a002a89796757e767ff9ec14b4e2dfe2d0fa6d31fec3547447bfa66"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (13\u201315 lines \u00D7 3): backend/hive/provisioner.py:1008-1020 | backend/hive/provisioner.py:1050-1062 | backend/hive/provisioner.py:1106-1120 \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":"backend/hive/provisioner.py"},"region":{"startLine":1008}}}],"partialFingerprints":{"codehealthFindingId/v1":"ad46523a31ef68493a708893bf09cc7749ef2d02d047925aba17b8d792e8a993"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (15 lines \u00D7 2): backend/core/code_intel/route_parser.py:165-179 | backend/core/code_intel/route_parser.py:220-234 \u2014 both copies are in the same file, so extract the block 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":"backend/core/code_intel/route_parser.py"},"region":{"startLine":165}}}],"partialFingerprints":{"codehealthFindingId/v1":"b279e1a11918eab0948b587b8983b7488a3a03c40201663da4cbd189af5b3ab2"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (15 lines \u00D7 2): backend/hooks/context_health_hook.py:3507-3521 | backend/hooks/distillation_hook.py:1932-1949 \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":"backend/hooks/context_health_hook.py"},"region":{"startLine":3507}}}],"partialFingerprints":{"codehealthFindingId/v1":"e6ac3cddb201ca2ec6ee6c923ffec1005a2247d12fd98dc8c9e7d6113c3cea27"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (13\u201315 lines \u00D7 2): backend/hooks/distillation_hook.py:1181-1195 | backend/hooks/distillation_hook.py:1215-1227 \u2014 both copies are in the same file, so extract the block 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":"backend/hooks/distillation_hook.py"},"region":{"startLine":1181}}}],"partialFingerprints":{"codehealthFindingId/v1":"1da7d65051fb1e7db035c6ddf54700344f905184fbbcd70ab677f4f27e32c2bf"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (12\u201315 lines \u00D7 2): backend/scripts/artifact_cli.py:1308-1319 | backend/scripts/artifact_cli.py:1358-1372 \u2014 both copies are in the same file, so extract the block 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, \u0060backend/scripts/artifact_cli.py:1307\u0060 calls \u0060get\u0060 and \u0060backend/scripts/artifact_cli.py:1357\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":"backend/scripts/artifact_cli.py"},"region":{"startLine":1308}}}],"partialFingerprints":{"codehealthFindingId/v1":"10210d0ce1e4f29c3d582795006f569b38ac0f50cdbcfff1d1191965024f7cea"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (15 lines \u00D7 2): backend/skills/s_docx/ooxml/scripts/validation/base.py:107-121 | backend/skills/s_pptx/ooxml/scripts/validation/base.py:107-121 \u2014 before extracting anything, compare \u0060backend/skills/s_docx/ooxml/scripts/validation/base.py\u0060 and \u0060backend/skills/s_pptx/ooxml/scripts/validation/base.py\u0060 as WHOLE FILES: this scan already matched 20 separate duplicated blocks between them, totalling at least 820 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":"backend/skills/s_docx/ooxml/scripts/validation/base.py"},"region":{"startLine":107}}}],"partialFingerprints":{"codehealthFindingId/v1":"ce92f788c69d181b76cd6a025d1ee2914daf0738a17d9002039b02a8f32ec19b"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9\u201315 lines \u00D7 2): backend/skills/s_loops-health/scripts/loops_health_check.py:412-420 | backend/skills/s_loops-health/scripts/loops_health_check.py:499-513 \u2014 both copies are in the same file, so extract the block 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, \u0060backend/skills/s_loops-health/scripts/loops_health_check.py:496\u0060 calls \u0060_check_coherence\u0060, \u0060_read_safe\u0060 and \u0060backend/skills/s_loops-health/scripts/loops_health_check.py:407\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":"backend/skills/s_loops-health/scripts/loops_health_check.py"},"region":{"startLine":412}}}],"partialFingerprints":{"codehealthFindingId/v1":"3173087329ebbb02613180fb51b0197945c438d4c7d303447c0ff21c8b7cced1"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (14 lines \u00D7 6): backend/skills/s_docx/ooxml/scripts/validation/docx.py:103-116 | backend/skills/s_docx/ooxml/scripts/validation/docx.py:152-165 | backend/skills/s_docx/ooxml/scripts/validation/docx.py:242-255 | backend/skills/s_pptx/ooxml/scripts/validation/docx.py:103-116 | backend/skills/s_pptx/ooxml/scripts/validation/docx.py:152-165 | backend/skills/s_pptx/ooxml/scripts/validation/docx.py:242-255 \u2014 before extracting anything, compare \u0060backend/skills/s_docx/ooxml/scripts/validation/docx.py\u0060 and \u0060backend/skills/s_pptx/ooxml/scripts/validation/docx.py\u0060 as WHOLE FILES: this scan already matched 11 separate duplicated blocks between them, totalling at least 244 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 \u0060backend/skills/s_docx/ooxml/scripts/validation/docx.py:103\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":"backend/skills/s_docx/ooxml/scripts/validation/docx.py"},"region":{"startLine":103}}}],"partialFingerprints":{"codehealthFindingId/v1":"ab60cce3f239dd65f0baf3c22d5a0425885f4f77b493ee7638c9dd667ba15c9a"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (14 lines \u00D7 3): backend/core/evolution/governance_router.py:113-126 | backend/core/evolution/governance_router.py:348-361 | backend/core/evolution/governance_router.py:404-417 \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":"backend/core/evolution/governance_router.py"},"region":{"startLine":113}}}],"partialFingerprints":{"codehealthFindingId/v1":"adb014354c7e7e21afdb7444634b38e8435197ea9a53d58e6ee331b51810b3f6"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (12\u201314 lines \u00D7 2): backend/channels/streaming.py:312-325 | backend/channels/streaming.py:365-376 \u2014 both copies are in the same file, so extract the block 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":"backend/channels/streaming.py"},"region":{"startLine":312}}}],"partialFingerprints":{"codehealthFindingId/v1":"21c68c7bdef45922d8ed0cbbbea2cef9f77770b114ccbe46099e170a5ffa2150"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (12\u201314 lines \u00D7 2): backend/core/artifact_registry.py:446-459 | backend/jobs/config_io.py:120-131 \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 \u0060backend/jobs/config_io.py:120\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":"backend/core/artifact_registry.py"},"region":{"startLine":446}}}],"partialFingerprints":{"codehealthFindingId/v1":"4903de3a9400f0e0a10333fa0bfb701490686542e5aa0e669b729021f10c0181"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (14 lines \u00D7 2): backend/core/ddd_cultivation.py:2287-2300 | backend/hooks/improvement_writeback_hook.py:66-79 \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. Note first that the copies are not typed on the same thing: the declarations holding them bind \u0060reason\u0060 to \u0060str\u0060 in one and \u0060str = \u0022\u0022\u0060 in another, and the duplicated lines use it. The extracted unit therefore needs a parameter type that fits BOTH \u2014 their common supertype where they have one, or a new abstraction over them where they do not \u2014 and settling that is the step that comes BEFORE the extraction above. Where the two types are deliberately unrelated, the duplication is the price of that separation and the honest resolution is to record the decision rather than to extract."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/core/ddd_cultivation.py"},"region":{"startLine":2287}}}],"partialFingerprints":{"codehealthFindingId/v1":"b138eaf3b4a1fe6afbb45f9c1b551acd58d9fceb06d78dad41e2c2122bb737d6"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (13\u201314 lines \u00D7 2): backend/core/evolution/correction_tracker.py:134-147 | backend/core/evolution/correction_tracker.py:150-162 \u2014 both copies are in the same file, so extract the block 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":"backend/core/evolution/correction_tracker.py"},"region":{"startLine":134}}}],"partialFingerprints":{"codehealthFindingId/v1":"66811a0bad18de12d70745b4a65a13cfcc67e43ed8a4d0d225a7c5a738992040"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (11\u201314 lines \u00D7 2): backend/database/sqlite.py:507-517 | backend/database/sqlite.py:1649-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. Read the line range as the matched WINDOW rather than a finished unit: at \u0060backend/database/sqlite.py:507\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":"backend/database/sqlite.py"},"region":{"startLine":507}}}],"partialFingerprints":{"codehealthFindingId/v1":"20098819777153e693414742ff31a863f9fe5999309dff18cbec8d0e141cd3bc"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (14 lines \u00D7 2): backend/hooks/context_health_hook.py:1090-1103 | backend/hooks/context_health_hook.py:1763-1776 \u2014 both copies are in the same file, so extract the block 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":"backend/hooks/context_health_hook.py"},"region":{"startLine":1090}}}],"partialFingerprints":{"codehealthFindingId/v1":"b14db946ff348b30805606d0a29802b1bd2609e5fd5ff71d20346052f751ae13"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (14 lines \u00D7 2): backend/hooks/context_health_hook.py:1866-1885 | backend/hooks/context_health_hook.py:2004-2017 \u2014 both copies are in the same file, so extract the block 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 \u0060backend/hooks/context_health_hook.py:1866\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":"backend/hooks/context_health_hook.py"},"region":{"startLine":1866}}}],"partialFingerprints":{"codehealthFindingId/v1":"cf3c494d0e9baf62fad57ac056405509fef2d30274f01ffb71fc8a1e7f54706e"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (8\u201314 lines \u00D7 3): backend/hooks/distillation_hook.py:1545-1556 | backend/hooks/distillation_hook.py:1558-1571 | backend/hooks/distillation_hook.py:1572-1579 \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 \u0060backend/hooks/distillation_hook.py:1545\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":"backend/hooks/distillation_hook.py"},"region":{"startLine":1545}}}],"partialFingerprints":{"codehealthFindingId/v1":"8ee4a0cb47162dc7707c803b3087314e6846daaed026468b212a4812543723ee"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (13\u201314 lines \u00D7 2): backend/skills/s_docx/scripts/document.py:404-416 | backend/skills/s_docx/scripts/document.py:507-520 \u2014 both copies are in the same file, so extract the block 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":"backend/skills/s_docx/scripts/document.py"},"region":{"startLine":404}}}],"partialFingerprints":{"codehealthFindingId/v1":"3b63cae02e9aa07853ddfdd301116b4e5837b4950a907128fb48fc584560a163"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (14 lines \u00D7 2): backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:309-322 | backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:308-321 \u2014 before extracting anything, compare \u0060backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py\u0060 and \u0060backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py\u0060 as WHOLE FILES: this scan already matched 79 separate duplicated blocks between them, totalling at least 2758 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":"backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py"},"region":{"startLine":309}}}],"partialFingerprints":{"codehealthFindingId/v1":"63d1822f78691bbbc1af996f8a402fe426043068e7cd6ad2ea18fd7ae3d8bf27"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (14 lines \u00D7 2): backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:3662-3675 | backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:3293-3306 \u2014 before extracting anything, compare \u0060backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py\u0060 and \u0060backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py\u0060 as WHOLE FILES: this scan already matched 79 separate duplicated blocks between them, totalling at least 2758 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py"},"region":{"startLine":3662}}}],"partialFingerprints":{"codehealthFindingId/v1":"29602e099e8d4f3056ad4cac53891539700bc997d3655d46945c954ed19c39fd"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (13 lines \u00D7 10): backend/skills/s_docx/ooxml/scripts/validation/base.py:263-275 | backend/skills/s_docx/ooxml/scripts/validation/docx.py:110-122 | backend/skills/s_docx/ooxml/scripts/validation/docx.py:159-171 | backend/skills/s_docx/ooxml/scripts/validation/docx.py:249-261 | backend/skills/s_docx/ooxml/scripts/validation/pptx.py:107-119 | backend/skills/s_pptx/ooxml/scripts/validation/base.py:266-278 | backend/skills/s_pptx/ooxml/scripts/validation/docx.py:110-122 | backend/skills/s_pptx/ooxml/scripts/validation/docx.py:159-171 | backend/skills/s_pptx/ooxml/scripts/validation/docx.py:249-261 | backend/skills/s_pptx/ooxml/scripts/validation/pptx.py:107-119 \u2014 before extracting anything, compare \u0060backend/skills/s_docx/ooxml/scripts/validation/base.py\u0060 and \u0060backend/skills/s_pptx/ooxml/scripts/validation/base.py\u0060 as WHOLE FILES: this scan already matched 20 separate duplicated blocks between them, totalling at least 820 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/skills/s_docx/ooxml/scripts/validation/base.py"},"region":{"startLine":263}}}],"partialFingerprints":{"codehealthFindingId/v1":"c09d77fba74aa881e4ee06c0d95f5412ad7cd163e3b0b512336c05e602ad2b6b"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (11\u201313 lines \u00D7 4): backend/database/sqlite.py:2910-2922 | backend/database/sqlite.py:2939-2951 | backend/database/sqlite.py:2996-3006 | backend/database/sqlite.py:3027-3037 \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. \u2605 These copies have DRIFTED, and that is worth reading before extracting anything: just after the matched lines, \u0060backend/database/sqlite.py:2926\u0060 calls \u0060execute\u0060, \u0060fetchall\u0060 and \u0060backend/database/sqlite.py:3039\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":"backend/database/sqlite.py"},"region":{"startLine":2910}}}],"partialFingerprints":{"codehealthFindingId/v1":"d4957a7bcf96d0c0f2256b100387727be2c4c0623b64d9ef5fe2abe519d970b3"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (13 lines \u00D7 2): backend/core/attention_authority.py:339-351 | backend/core/attention_authority.py:356-368 \u2014 both copies are in the same file, so extract the block 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":"backend/core/attention_authority.py"},"region":{"startLine":339}}}],"partialFingerprints":{"codehealthFindingId/v1":"a5c0ce1bb509ed3fd1811f3972e522bda36ca431bc834625ff9bb396f8465950"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (12\u201313 lines \u00D7 2): backend/core/claude_environment.py:101-113 | backend/core/claude_environment.py:124-135 \u2014 both copies are in the same file, so extract the block 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":"backend/core/claude_environment.py"},"region":{"startLine":101}}}],"partialFingerprints":{"codehealthFindingId/v1":"dc5b1b5b316efd7cc5cc2fc9b8e7ec3d57f7aac186a17657d6d3979950bde633"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (13 lines \u00D7 2): backend/core/ddd_entry_lifecycle.py:1241-1253 | backend/core/ddd_entry_lifecycle.py:1289-1301 \u2014 both copies are in the same file, so extract the block 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":"backend/core/ddd_entry_lifecycle.py"},"region":{"startLine":1241}}}],"partialFingerprints":{"codehealthFindingId/v1":"a728908d9665f0fdee73dabbadf1f500b55409f69306a2c57c3cbd85f4eb084d"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (11\u201313 lines \u00D7 2): backend/core/ddd_job_registry.py:138-148 | backend/core/ddd_skill_registry.py:192-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":"backend/core/ddd_job_registry.py"},"region":{"startLine":138}}}],"partialFingerprints":{"codehealthFindingId/v1":"003da446398d05475e5304b9b1d7cbc29003bf0023fd0f3d786cb0de38591e53"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (12\u201313 lines \u00D7 2): backend/core/ddd_packager.py:1511-1523 | backend/core/ddd_packager.py:1679-1690 \u2014 both copies are in the same file, so extract the block 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 \u0060backend/core/ddd_packager.py:1511\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":"backend/core/ddd_packager.py"},"region":{"startLine":1511}}}],"partialFingerprints":{"codehealthFindingId/v1":"0c9f55524b60a06901e515aa58c52b8a19d10911336bc574d1875866b0109afc"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (13 lines \u00D7 2): backend/database/sqlite.py:536-548 | backend/database/sqlite.py:960-972 \u2014 both copies are in the same file, so extract the block 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":"backend/database/sqlite.py"},"region":{"startLine":536}}}],"partialFingerprints":{"codehealthFindingId/v1":"646404601e31d2773be26d448987cfb685d433c70423cbf19b946eb894e9f27f"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (13 lines \u00D7 2): backend/hooks/context_health_hook.py:3307-3320 | backend/hooks/context_health_hook.py:3322-3334 \u2014 both copies are in the same file, so extract the block 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":"backend/hooks/context_health_hook.py"},"region":{"startLine":3307}}}],"partialFingerprints":{"codehealthFindingId/v1":"649b6377d89950f769dc29438737544fb48bd21d0796382d13ed6c7b1996244b"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (13 lines \u00D7 2): backend/routers/channels.py:313-325 | backend/routers/channels.py:363-375 \u2014 both copies are in the same file, so extract the block 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 \u0060backend/routers/channels.py:313\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":"backend/routers/channels.py"},"region":{"startLine":313}}}],"partialFingerprints":{"codehealthFindingId/v1":"3598465d17c43f3a75dfd868c759663834f94a93f30b0b852edd95216266baf1"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (10\u201313 lines \u00D7 2): backend/routers/ddd_brain.py:237-246 | backend/routers/ddd_brain.py:1704-1716 \u2014 both copies are in the same file, so extract the block 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 \u0060backend/routers/ddd_brain.py:237\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":"backend/routers/ddd_brain.py"},"region":{"startLine":237}}}],"partialFingerprints":{"codehealthFindingId/v1":"0fce0263aadfb66ef842d2142e994cfbfad110cec5069ee1e90e2606f457cb62"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (12\u201313 lines \u00D7 2): backend/routers/workspace_api.py:1089-1101 | backend/routers/workspace_api.py:1107-1118 \u2014 both copies are in the same file, so extract the block 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 \u0060backend/routers/workspace_api.py:1089\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":"backend/routers/workspace_api.py"},"region":{"startLine":1089}}}],"partialFingerprints":{"codehealthFindingId/v1":"38fbd13e068756db429edf09e0d8dc88676c6895822acceb552e9d8f7b3fb315"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9\u201313 lines \u00D7 2): backend/scripts/artifact_cli.py:5839-5851 | backend/scripts/artifact_cli.py:6010-6018 \u2014 both copies are in the same file, so extract the block 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 \u0060backend/scripts/artifact_cli.py:5839\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":"backend/scripts/artifact_cli.py"},"region":{"startLine":5839}}}],"partialFingerprints":{"codehealthFindingId/v1":"07092d9f47ad193bda1b0a6fdd53b6f8af3a052abbb2aa610d17aaa8786f42d7"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (13 lines \u00D7 2): backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:700-712 | backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:614-626 \u2014 before extracting anything, compare \u0060backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py\u0060 and \u0060backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py\u0060 as WHOLE FILES: this scan already matched 79 separate duplicated blocks between them, totalling at least 2758 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":"backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py"},"region":{"startLine":700}}}],"partialFingerprints":{"codehealthFindingId/v1":"8680e0130d4b850eafe8b0b154730831cda9a03c068c80082e829640eedc705d"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (13 lines \u00D7 2): backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:758-770 | backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:672-684 \u2014 before extracting anything, compare \u0060backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py\u0060 and \u0060backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py\u0060 as WHOLE FILES: this scan already matched 79 separate duplicated blocks between them, totalling at least 2758 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py"},"region":{"startLine":758}}}],"partialFingerprints":{"codehealthFindingId/v1":"8419bbe34259f58683cc299ce31712c4f8613c0daa769a742a82bc41e3f00ad0"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9\u201312 lines \u00D7 11): backend/database/sqlite.py:975-983 | backend/database/sqlite.py:1091-1099 | backend/database/sqlite.py:1192-1200 | backend/database/sqlite.py:1309-1317 | backend/database/sqlite.py:1361-1369 | backend/database/sqlite.py:1397-1405 | backend/database/sqlite.py:1486-1494 | backend/database/sqlite.py:1497-1508 | backend/database/sqlite.py:1606-1614 | backend/database/sqlite.py:1617-1625 | backend/database/sqlite.py:1718-1726 \u2014 all 11 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":"backend/database/sqlite.py"},"region":{"startLine":975}}}],"partialFingerprints":{"codehealthFindingId/v1":"cd45ee44c2b1ce618c41bfe76ca454c7c478746e4a1ae4ccc5fb45489ef6226d"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (12 lines \u00D7 8): backend/database/sqlite.py:2899-2910 | backend/database/sqlite.py:2919-2930 | backend/database/sqlite.py:2956-2967 | backend/database/sqlite.py:2968-2980 | backend/database/sqlite.py:2981-2996 | backend/database/sqlite.py:3076-3088 | backend/database/sqlite.py:3089-3101 | backend/database/sqlite.py:3102-3122 \u2014 all 8 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":"backend/database/sqlite.py"},"region":{"startLine":2899}}}],"partialFingerprints":{"codehealthFindingId/v1":"2a8beccb11c03e7da84bfdc0c1b0da00cd360af81f57a562ec7338d2587d145e"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (12 lines \u00D7 7): backend/skills/s_frontend-design/scripts/design_system.py:515-526 | backend/skills/s_frontend-design/scripts/design_system.py:686-697 | backend/skills/s_frontend-design/scripts/design_system.py:745-756 | backend/skills/s_frontend-design/scripts/design_system.py:790-801 | backend/skills/s_frontend-design/scripts/design_system.py:902-915 | backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:2336-2347 | backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:1989-2000 \u2014 before extracting anything, compare \u0060backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py\u0060 and \u0060backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py\u0060 as WHOLE FILES: this scan already matched 79 separate duplicated blocks between them, totalling at least 2758 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":"backend/skills/s_frontend-design/scripts/design_system.py"},"region":{"startLine":515}}}],"partialFingerprints":{"codehealthFindingId/v1":"9e526acb78c4562eb44f9e6934d728a9375dbe8595987079445fa43ec46c5a43"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (12 lines \u00D7 6): backend/scripts/locked_write.py:501-512 | backend/scripts/locked_write.py:664-675 | backend/skills/s_persist/scripts/locked_write.py:501-512 | backend/skills/s_persist/scripts/locked_write.py:664-675 | backend/templates/ddd-skills/s_ddd-persist/scripts/locked_write.py:501-512 | backend/templates/ddd-skills/s_ddd-persist/scripts/locked_write.py:636-647 \u2014 before extracting anything, compare \u0060backend/scripts/locked_write.py\u0060 and \u0060backend/skills/s_persist/scripts/locked_write.py\u0060 as WHOLE FILES: this scan already matched 10 separate duplicated blocks between them, totalling at least 456 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":"backend/scripts/locked_write.py"},"region":{"startLine":501}}}],"partialFingerprints":{"codehealthFindingId/v1":"d9e5054051f78406a16a018318635d1d6d21017582d51eba6ec127c71bd41156"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (10\u201312 lines \u00D7 4): backend/hooks/context_health_hook.py:3513-3522 | backend/hooks/distillation_hook.py:1941-1950 | backend/hooks/distillation_hook.py:2094-2103 | backend/hooks/evolution_maintenance_hook.py:380-391 \u2014 there are 4 copies across 3 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":"backend/hooks/context_health_hook.py"},"region":{"startLine":3513}}}],"partialFingerprints":{"codehealthFindingId/v1":"d01c374a8b9ddcd2a45cd19014cce04d62da0620f29b765c156270347f5838b4"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (12 lines \u00D7 3): backend/core/proactive_intelligence.py:276-287 | backend/hooks/distillation_hook.py:395-406 | backend/hooks/distillation_hook.py:2070-2081 \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 \u0060backend/core/proactive_intelligence.py:276\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":"backend/core/proactive_intelligence.py"},"region":{"startLine":276}}}],"partialFingerprints":{"codehealthFindingId/v1":"3714e46ce1b424a6c72c458c7f03172a94c7e183be1a441389aa4debbb55dc06"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (12 lines \u00D7 3): backend/core/streaming_orchestrator.py:1459-1470 | backend/core/streaming_orchestrator.py:1633-1644 | backend/core/streaming_orchestrator.py:1689-1700 \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":"backend/core/streaming_orchestrator.py"},"region":{"startLine":1459}}}],"partialFingerprints":{"codehealthFindingId/v1":"a1e69eeaa47dd044487d7772fb935df7eed48fec4e83d8a5ed7622acc9d78114"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (12 lines \u00D7 3): backend/routers/mcp.py:156-167 | backend/routers/mcp.py:227-238 | backend/routers/mcp.py:264-275 \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":"backend/routers/mcp.py"},"region":{"startLine":156}}}],"partialFingerprints":{"codehealthFindingId/v1":"3a74b97d15b99766af17dae8efda289209fedf3176e059e0c91bbff3bb27b296"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (11\u201312 lines \u00D7 2): backend/core/code_intel/graph_store.py:639-650 | backend/core/code_intel/graph_store.py:1665-1675 \u2014 both copies are in the same file, so extract the block 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 \u0060backend/core/code_intel/graph_store.py:639\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":"backend/core/code_intel/graph_store.py"},"region":{"startLine":639}}}],"partialFingerprints":{"codehealthFindingId/v1":"a99595d59b6c89e624a6ca952b584f401f0a02c24ed978e09edf7d654565f8b0"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (12 lines \u00D7 2): backend/core/daemon_guard.py:146-157 | desktop/resources/daemon/daemon_guard.py:146-157 \u2014 before extracting anything, compare \u0060backend/core/daemon_guard.py\u0060 and \u0060desktop/resources/daemon/daemon_guard.py\u0060 as WHOLE FILES: this scan already matched 11 separate duplicated blocks between them, totalling at least 280 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/core/daemon_guard.py"},"region":{"startLine":146}}}],"partialFingerprints":{"codehealthFindingId/v1":"0091be02056fa006793edb4d4a65eecd2336f3086439341470a919c5e75d3245"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (12 lines \u00D7 2): backend/core/mcp_config_loader.py:669-680 | backend/core/mcp_config_loader.py:707-718 \u2014 both copies are in the same file, so extract the block 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 \u0060backend/core/mcp_config_loader.py:669\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":"backend/core/mcp_config_loader.py"},"region":{"startLine":669}}}],"partialFingerprints":{"codehealthFindingId/v1":"b5dfb74f99d695e5c95c20f6b2f6867ee0bd0d5545b1e005145ed106d748183b"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (12 lines \u00D7 2): backend/core/session_miner.py:358-369 | backend/core/session_miner.py:400-411 \u2014 both copies are in the same file, so extract the block 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":"backend/core/session_miner.py"},"region":{"startLine":358}}}],"partialFingerprints":{"codehealthFindingId/v1":"c821bf4e6976936aab28c1a29cea67b25305b66824acad9fa504bc65f50f04a2"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (10\u201312 lines \u00D7 2): backend/core/session_router.py:3694-3705 | backend/core/session_router.py:3724-3733 \u2014 both copies are in the same file, so extract the block 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":"backend/core/session_router.py"},"region":{"startLine":3694}}}],"partialFingerprints":{"codehealthFindingId/v1":"ac030c2288903b5a8e2bc2d55d7fd57bfcffd83375288d083ce76ba6cbb50d2b"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (12 lines \u00D7 2): backend/hive/provisioner.py:167-178 | backend/hive/provisioner.py:181-192 \u2014 both copies are in the same file, so extract the block 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":"backend/hive/provisioner.py"},"region":{"startLine":167}}}],"partialFingerprints":{"codehealthFindingId/v1":"40254f149bcf47595452e31afb24b3e6a5e35ee3a9b91c02bcd63319ecf1f117"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (12 lines \u00D7 2): backend/jobs/bedrock.py:450-461 | backend/jobs/bedrock.py:471-482 \u2014 both copies are in the same file, so extract the block 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 \u0060backend/jobs/bedrock.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. 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":"backend/jobs/bedrock.py"},"region":{"startLine":450}}}],"partialFingerprints":{"codehealthFindingId/v1":"976017b080856bf456e6347fb64c0816c854d8307233fe4394a9df011578133c"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (10\u201312 lines \u00D7 2): backend/routers/eval.py:195-206 | backend/routers/eval.py:229-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. 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":"backend/routers/eval.py"},"region":{"startLine":195}}}],"partialFingerprints":{"codehealthFindingId/v1":"770d0e3519ed3d23be78a6cdf646ea30409ce92ab7dc80e438cdc0d0a31fd623"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (12 lines \u00D7 2): backend/routers/workspace.py:694-705 | backend/routers/workspace.py:775-786 \u2014 both copies are in the same file, so extract the block 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":"backend/routers/workspace.py"},"region":{"startLine":694}}}],"partialFingerprints":{"codehealthFindingId/v1":"bd8f4257f9b83e6cc807ad97c70f3ef191c46292de81a3a8d2e90e99c33c805d"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (12 lines \u00D7 2): backend/skills/s_frontend-design/scripts/design_system.py:961-972 | backend/skills/s_frontend-design/scripts/design_system.py:974-985 \u2014 both copies are in the same file, so extract the block 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":"backend/skills/s_frontend-design/scripts/design_system.py"},"region":{"startLine":961}}}],"partialFingerprints":{"codehealthFindingId/v1":"f8cee7d20d35ff9b615fe41acc53ebc221d5645eda06ed4680e057a6b31d1c2d"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (12 lines \u00D7 2): backend/skills/s_frontend-design/scripts/search.py:42-53 | backend/skills/s_web-design-review/scripts/search.py:42-53 \u2014 before extracting anything, compare \u0060backend/skills/s_frontend-design/scripts/search.py\u0060 and \u0060backend/skills/s_web-design-review/scripts/search.py\u0060 as WHOLE FILES: 100% 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. 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":"backend/skills/s_frontend-design/scripts/search.py"},"region":{"startLine":42}}}],"partialFingerprints":{"codehealthFindingId/v1":"1f48b754ce23bb63f6231fcefdb2315b4139a9687141bb9920f6873895619bc5"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (12 lines \u00D7 2): backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:251-262 | backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:250-261 \u2014 before extracting anything, compare \u0060backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py\u0060 and \u0060backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py\u0060 as WHOLE FILES: this scan already matched 79 separate duplicated blocks between them, totalling at least 2758 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":"backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py"},"region":{"startLine":251}}}],"partialFingerprints":{"codehealthFindingId/v1":"6ca75137873d13fd350c02580cb7749ad61b2b3ba9412751ade83b3e7b9017d9"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (12 lines \u00D7 2): backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:3625-3636 | backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:3256-3267 \u2014 before extracting anything, compare \u0060backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py\u0060 and \u0060backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py\u0060 as WHOLE FILES: this scan already matched 79 separate duplicated blocks between them, totalling at least 2758 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py"},"region":{"startLine":3625}}}],"partialFingerprints":{"codehealthFindingId/v1":"71d0fc5ad33053e95975fa89b8d812de33e3efddd43d73476b3d218f425f54d4"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (11 lines \u00D7 3): backend/core/mcp_config_loader.py:668-678 | backend/core/mcp_config_loader.py:706-716 | backend/routers/mcp.py:59-69 \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":"backend/core/mcp_config_loader.py"},"region":{"startLine":668}}}],"partialFingerprints":{"codehealthFindingId/v1":"4f3c06e70d37791927cbcb550a9e90c406cb494ddca3c5c242426d7fc1721630"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (11 lines \u00D7 3): backend/core/security_hooks.py:346-356 | backend/core/security_hooks.py:685-695 | backend/core/security_hooks.py:1611-1621 \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":"backend/core/security_hooks.py"},"region":{"startLine":346}}}],"partialFingerprints":{"codehealthFindingId/v1":"6c2d8fc2f81bbb819496d5762c5ff9d1de916c4c7e5aceac95151b26c93f8c42"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9\u201311 lines \u00D7 3): backend/routers/channels.py:320-328 | backend/routers/channels.py:370-378 | backend/routers/channels.py:388-398 \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 \u0060backend/routers/channels.py:388\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":"backend/routers/channels.py"},"region":{"startLine":320}}}],"partialFingerprints":{"codehealthFindingId/v1":"71875b5b8fdd4b2991e868509bd7a08866d93f3e9de81e80224ac56474e0100b"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (11 lines \u00D7 3): backend/skills/s_frontend-design/scripts/design_system.py:715-725 | backend/skills/s_frontend-design/scripts/design_system.py:748-758 | backend/skills/s_frontend-design/scripts/design_system.py:808-818 \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":"backend/skills/s_frontend-design/scripts/design_system.py"},"region":{"startLine":715}}}],"partialFingerprints":{"codehealthFindingId/v1":"8277949cf487feaa4346062d040862eb8dd8ec1752f481905cc9ef0b2ba3f487"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (8\u201311 lines \u00D7 3): backend/skills/s_pollinate/scripts/check_rpv.py:65-72 | backend/skills/s_pollinate/scripts/check_rpv.py:141-148 | backend/skills/s_pollinate/scripts/check_rpv.py:168-178 \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":"backend/skills/s_pollinate/scripts/check_rpv.py"},"region":{"startLine":65}}}],"partialFingerprints":{"codehealthFindingId/v1":"5ad501b5bf0fdedf00a2acb061a4ef30179c37c918f6cb3456ba332c15fe06fa"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (11 lines \u00D7 2): backend/core/ddd_health.py:177-187 | backend/core/ddd_maturity.py:426-436 \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":"backend/core/ddd_health.py"},"region":{"startLine":177}}}],"partialFingerprints":{"codehealthFindingId/v1":"a953d98f5aa77c79bc7ce046fddec844a5167df55a98ab7e1dd47ac621926b2e"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (11 lines \u00D7 2): backend/core/ingestion_gate.py:464-474 | backend/core/ingestion_gate.py:823-833 \u2014 both copies are in the same file, so extract the block 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":"backend/core/ingestion_gate.py"},"region":{"startLine":464}}}],"partialFingerprints":{"codehealthFindingId/v1":"e7f582d712c503479352d154af88b5c8847ef53ff04b8f7414f70d703eafadd2"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (11 lines \u00D7 2): backend/core/knowledge_graph.py:213-223 | backend/core/knowledge_graph.py:235-245 \u2014 both copies are in the same file, so extract the block into one function there and call it from each site \u2014 the copies drift apart the first time only one of them is edited."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/core/knowledge_graph.py"},"region":{"startLine":213}}}],"partialFingerprints":{"codehealthFindingId/v1":"5c0f04cc9a2a4c2f9a18da029d00c802c137974adb31b60ed64ac41d726d250c"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (11 lines \u00D7 2): backend/core/knowledge_store.py:277-287 | backend/core/transcript_indexer.py:331-341 \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":"backend/core/knowledge_store.py"},"region":{"startLine":277}}}],"partialFingerprints":{"codehealthFindingId/v1":"eea0d1ca48c33df45bba13f8359fd168898157847c09b728843064e805e88e3a"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (10\u201311 lines \u00D7 2): backend/core/memory_extractor.py:107-117 | backend/core/summarization.py:691-700 \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, \u0060backend/core/memory_extractor.py:119\u0060 calls \u0060get\u0060 and \u0060backend/core/summarization.py:702\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":"backend/core/memory_extractor.py"},"region":{"startLine":107}}}],"partialFingerprints":{"codehealthFindingId/v1":"b9f84a1ac0691cd135fcbb447b5f0220caf38d0b13f8857d1098f7040a822d7d"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (11 lines \u00D7 2): backend/core/memory_extractor.py:122-132 | backend/core/summarization.py:702-712 \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 \u0060backend/core/memory_extractor.py:122\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. \u2605 These copies have DRIFTED, and that is worth reading before extracting anything: just before the matched lines, \u0060backend/core/memory_extractor.py:119\u0060 calls \u0060get\u0060 and \u0060backend/core/summarization.py:701\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":"backend/core/memory_extractor.py"},"region":{"startLine":122}}}],"partialFingerprints":{"codehealthFindingId/v1":"478e22505c5180fa67031383630150cb0080cff188a94daad7143fedecf9e611"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9\u201311 lines \u00D7 2): backend/core/memory_extractor.py:266-276 | backend/core/summarization.py:826-834 \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":"backend/core/memory_extractor.py"},"region":{"startLine":266}}}],"partialFingerprints":{"codehealthFindingId/v1":"23695600b07d5bb036f4d7ce74f3843abd22515df55f0de51a82e2ae4ddc15d2"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (11 lines \u00D7 2): backend/core/runtime_hooks.py:203-214 | backend/core/runtime_hooks.py:1035-1045 \u2014 both copies are in the same file, so extract the block 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":"backend/core/runtime_hooks.py"},"region":{"startLine":203}}}],"partialFingerprints":{"codehealthFindingId/v1":"54a15c155d0ad0e4dab9de9c18b7a7b1ef599f891a38feb34ab9d497743c69c4"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (11 lines \u00D7 2): backend/core/summarization.py:530-540 | backend/hooks/skill_metrics_hook.py:233-243 \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":"backend/core/summarization.py"},"region":{"startLine":530}}}],"partialFingerprints":{"codehealthFindingId/v1":"07c17295c57ba094b186ea24d46dc54d32855eecb87e5d0d00bc7832c4fbfcbd"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (11 lines \u00D7 2): backend/database/sqlite.py:742-752 | backend/database/sqlite.py:767-777 \u2014 both copies are in the same file, so extract the block 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 \u0060backend/database/sqlite.py:742\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":"backend/database/sqlite.py"},"region":{"startLine":742}}}],"partialFingerprints":{"codehealthFindingId/v1":"69ed7d3edc0408a02ef64b09832448a8c094d233ee5d44fdfb4a32aeaaacb872"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (11 lines \u00D7 2): backend/hive/provisioner.py:1032-1042 | backend/hive/provisioner.py:1075-1085 \u2014 both copies are in the same file, so extract the block 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":"backend/hive/provisioner.py"},"region":{"startLine":1032}}}],"partialFingerprints":{"codehealthFindingId/v1":"f0cf22a8e2198757bd134c13b4599ff369576f6cb8eae79877b0bea98b625a95"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (11 lines \u00D7 2): backend/hooks/context_health_hook.py:1265-1275 | backend/hooks/context_health_hook.py:1288-1298 \u2014 both copies are in the same file, so extract the block 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 \u0060backend/hooks/context_health_hook.py:1265\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":"backend/hooks/context_health_hook.py"},"region":{"startLine":1265}}}],"partialFingerprints":{"codehealthFindingId/v1":"dbbd7e08d84849b095cfcad8788c4dc38120be17dfeb3ee9e0c86221eb3bb944"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (11 lines \u00D7 2): backend/hooks/distillation_hook.py:691-701 | backend/hooks/distillation_hook.py:733-749 \u2014 both copies are in the same file, so extract the block 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 \u0060backend/hooks/distillation_hook.py:691\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":"backend/hooks/distillation_hook.py"},"region":{"startLine":691}}}],"partialFingerprints":{"codehealthFindingId/v1":"29765a33c500194f38030b7ed81de5efade3c99a66a130ad0101d174e0a5c2ff"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (10\u201311 lines \u00D7 2): backend/hooks/distillation_hook.py:2548-2557 | backend/hooks/distillation_hook.py:2884-2894 \u2014 both copies are in the same file, so extract the block 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 \u0060backend/hooks/distillation_hook.py:2548\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":"backend/hooks/distillation_hook.py"},"region":{"startLine":2548}}}],"partialFingerprints":{"codehealthFindingId/v1":"ebe012d9dd952e5c866b2fb42ffefccea34bdd8f29c0894a140ebc546fb357c9"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (11 lines \u00D7 2): backend/hooks/evolution_maintenance_hook.py:752-762 | backend/hooks/evolution_maintenance_hook.py:1060-1070 \u2014 both copies are in the same file, so extract the block 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, \u0060backend/hooks/evolution_maintenance_hook.py:745\u0060 calls \u0060min\u0060 and \u0060backend/hooks/evolution_maintenance_hook.py:1058\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":"backend/hooks/evolution_maintenance_hook.py"},"region":{"startLine":752}}}],"partialFingerprints":{"codehealthFindingId/v1":"767ed7c255b3d379cdfbb13a7d608300b72dd15a6e59bcd61ec9121a90bbe541"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (11 lines \u00D7 2): backend/jobs/executor.py:418-428 | backend/jobs/executor.py:439-450 \u2014 both copies are in the same file, so extract the block 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 \u0060backend/jobs/executor.py:418\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":"backend/jobs/executor.py"},"region":{"startLine":418}}}],"partialFingerprints":{"codehealthFindingId/v1":"120d832c54c624fea8154439bebbe74bcb62ebf733bb6ca28edc54b9e296055c"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (8\u201311 lines \u00D7 2): backend/routers/chat.py:498-508 | backend/routers/todos.py:463-470 \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":"backend/routers/chat.py"},"region":{"startLine":498}}}],"partialFingerprints":{"codehealthFindingId/v1":"2bc3fa1dc2cadc14feca86aedc81d4b29ef62c6b59e3f2a152934966e301a3dd"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (11 lines \u00D7 2): backend/scripts/artifact_cli.py:1294-1304 | backend/scripts/artifact_cli.py:1348-1358 \u2014 both copies are in the same file, so extract the block 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 after the matched lines, \u0060backend/scripts/artifact_cli.py:1307\u0060 calls \u0060get\u0060 and \u0060backend/scripts/artifact_cli.py:1366\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":"backend/scripts/artifact_cli.py"},"region":{"startLine":1294}}}],"partialFingerprints":{"codehealthFindingId/v1":"d5001afd71e2c86492dd0161c9815364bbf418205cec4319c587c61a08410b29"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (11 lines \u00D7 2): backend/scripts/artifact_cli.py:1348-1358 | backend/scripts/pipeline_cleanup.py:56-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. 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":"backend/scripts/artifact_cli.py"},"region":{"startLine":1348}}}],"partialFingerprints":{"codehealthFindingId/v1":"8e3927378a81e30e8aa2dcf126f508d678863c628c0d9a31a1e9b2b89017e4e5"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (11 lines \u00D7 2): backend/scripts/scenario_runner.py:85-95 | backend/scripts/scenario_runner.py:135-145 \u2014 both copies are in the same file, so extract the block 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 after the matched lines, \u0060backend/scripts/scenario_runner.py:146\u0060 calls \u0060get\u0060, \u0060isinstance\u0060 and \u0060backend/scripts/scenario_runner.py:96\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":"backend/scripts/scenario_runner.py"},"region":{"startLine":85}}}],"partialFingerprints":{"codehealthFindingId/v1":"3e7897cd50df233f5429f57280b533a52b8fae49c3e5689d4307d6f22c70d6a2"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (11 lines \u00D7 2): backend/skills/s_frontend-design/scripts/search.py:31-41 | backend/skills/s_web-design-review/scripts/search.py:31-41 \u2014 before extracting anything, compare \u0060backend/skills/s_frontend-design/scripts/search.py\u0060 and \u0060backend/skills/s_web-design-review/scripts/search.py\u0060 as WHOLE FILES: 100% 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. 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":"backend/skills/s_frontend-design/scripts/search.py"},"region":{"startLine":31}}}],"partialFingerprints":{"codehealthFindingId/v1":"af78310c0382e7cc5dd0c034912622c774dde3a7361f2cebed09ca12caf7df0b"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (10\u201311 lines \u00D7 2): backend/skills/s_loops-health/scripts/loops_health_check.py:842-852 | backend/skills/s_loops-health/scripts/loops_health_check.py:868-877 \u2014 both copies are in the same file, so extract the block 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":"backend/skills/s_loops-health/scripts/loops_health_check.py"},"region":{"startLine":842}}}],"partialFingerprints":{"codehealthFindingId/v1":"8a47c12216c56d3e66e4906583805b32695d9323cb2973417963a697ed577d5f"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (11 lines \u00D7 2): backend/skills/s_pollinate/scripts/cross_format_check.py:137-147 | backend/skills/s_pollinate/scripts/cross_format_check.py:212-222 \u2014 both copies are in the same file, so extract the block 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":"backend/skills/s_pollinate/scripts/cross_format_check.py"},"region":{"startLine":137}}}],"partialFingerprints":{"codehealthFindingId/v1":"0b17422f13bf6f83c8174323e31c019706603523e9572b23bf2a54731b6f3022"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (10\u201311 lines \u00D7 2): backend/skills/s_pollinate/scripts/tts/backends/azure.py:25-34 | backend/skills/s_pollinate/scripts/tts/backends/polly.py:274-284 \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, \u0060backend/skills/s_pollinate/scripts/tts/backends/azure.py:22\u0060 calls \u0060get\u0060 and \u0060backend/skills/s_pollinate/scripts/tts/backends/polly.py:272\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":"backend/skills/s_pollinate/scripts/tts/backends/azure.py"},"region":{"startLine":25}}}],"partialFingerprints":{"codehealthFindingId/v1":"6b8df8257e3e32f54026212ad5b6f6d4f9f45b1c96be90bdc759dff5ae2c4c28"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (11 lines \u00D7 2): backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:214-224 | backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:213-223 \u2014 before extracting anything, compare \u0060backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py\u0060 and \u0060backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py\u0060 as WHOLE FILES: this scan already matched 79 separate duplicated blocks between them, totalling at least 2758 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":"backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py"},"region":{"startLine":214}}}],"partialFingerprints":{"codehealthFindingId/v1":"83cff464d72e6bc5ae72972489008bd4bde6d07e772c71633711656ef12f35c6"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (11 lines \u00D7 2): backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:1025-1035 | backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:760-771 \u2014 before extracting anything, compare \u0060backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py\u0060 and \u0060backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py\u0060 as WHOLE FILES: this scan already matched 79 separate duplicated blocks between them, totalling at least 2758 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":"backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py"},"region":{"startLine":1025}}}],"partialFingerprints":{"codehealthFindingId/v1":"732419d8a81b4f2ca0f8059bfbe362dfa43b4817cea203666b68427319081819"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (11 lines \u00D7 2): backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:1602-1612 | backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:1266-1276 \u2014 before extracting anything, compare \u0060backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py\u0060 and \u0060backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py\u0060 as WHOLE FILES: this scan already matched 79 separate duplicated blocks between them, totalling at least 2758 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":"backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py"},"region":{"startLine":1602}}}],"partialFingerprints":{"codehealthFindingId/v1":"b5507bafe0942f23e12d5b964465b9c37753427b5d6322af5ed89e34bb01be48"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (11 lines \u00D7 2): backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:3648-3658 | backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:3279-3289 \u2014 before extracting anything, compare \u0060backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py\u0060 and \u0060backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py\u0060 as WHOLE FILES: this scan already matched 79 separate duplicated blocks between them, totalling at least 2758 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py"},"region":{"startLine":3648}}}],"partialFingerprints":{"codehealthFindingId/v1":"143871a470c6d2446184f1fde65ddaefac2db19ece80ebe3a4c3187703eada15"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (10 lines \u00D7 10): backend/skills/s_docx/ooxml/scripts/validation/docx.py:107-116 | backend/skills/s_docx/ooxml/scripts/validation/docx.py:156-165 | backend/skills/s_docx/ooxml/scripts/validation/docx.py:246-255 | backend/skills/s_docx/ooxml/scripts/validation/pptx.py:104-113 | backend/skills/s_docx/ooxml/scripts/validation/pptx.py:183-192 | backend/skills/s_pptx/ooxml/scripts/validation/docx.py:107-116 | backend/skills/s_pptx/ooxml/scripts/validation/docx.py:156-165 | backend/skills/s_pptx/ooxml/scripts/validation/docx.py:246-255 | backend/skills/s_pptx/ooxml/scripts/validation/pptx.py:104-113 | backend/skills/s_pptx/ooxml/scripts/validation/pptx.py:183-192 \u2014 there are 10 copies across 4 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 10 sites; resolving a subset leaves the remainder to drift apart. Read the line range as the matched WINDOW rather than a finished unit: at \u0060backend/skills/s_docx/ooxml/scripts/validation/docx.py:107\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":"backend/skills/s_docx/ooxml/scripts/validation/docx.py"},"region":{"startLine":107}}}],"partialFingerprints":{"codehealthFindingId/v1":"140c0fbdb739c789f2e02ee5ce02549a2eb8af6501c63f0ecef66148e1fba75c"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (8\u201310 lines \u00D7 4): backend/database/sqlite.py:515-522 | backend/database/sqlite.py:1422-1430 | backend/database/sqlite.py:1659-1668 | backend/database/sqlite.py:1707-1715 \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":"backend/database/sqlite.py"},"region":{"startLine":515}}}],"partialFingerprints":{"codehealthFindingId/v1":"1424ef8d573de977280d3f243224053d983cd064ebdf7987cb6a42b9bf5c1009"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9\u201310 lines \u00D7 4): backend/skills/s_docx/scripts/document.py:320-328 | backend/skills/s_docx/scripts/document.py:401-409 | backend/skills/s_docx/scripts/document.py:504-513 | backend/skills/s_docx/scripts/document.py:561-570 \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. \u2605 These copies have DRIFTED, and that is worth reading before extracting anything: just after the matched lines, \u0060backend/skills/s_docx/scripts/document.py:573\u0060 calls \u0060getElementsByTagName\u0060 and \u0060backend/skills/s_docx/scripts/document.py:412\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":"backend/skills/s_docx/scripts/document.py"},"region":{"startLine":320}}}],"partialFingerprints":{"codehealthFindingId/v1":"1cca9013ff123301b8b6877a41993e2ba01016fd0f0bb885f74feb36dc24032e"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7\u201310 lines \u00D7 5): backend/skills/s_frontend-design/scripts/design_system.py:911-920 | backend/skills/s_frontend-design/scripts/design_system.py:922-931 | backend/skills/s_frontend-design/scripts/design_system.py:933-942 | backend/skills/s_frontend-design/scripts/design_system.py:944-953 | backend/skills/s_frontend-design/scripts/design_system.py:954-960 \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. 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":"backend/skills/s_frontend-design/scripts/design_system.py"},"region":{"startLine":911}}}],"partialFingerprints":{"codehealthFindingId/v1":"8d2dae74077d0df5bbe2787290d6c4db5a38f9c755618f4d9b63e2571b199bc2"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (10 lines \u00D7 3): backend/core/ddd_orchestrator.py:256-265 | backend/core/engine_metrics.py:289-298 | backend/jobs/handlers/ddd_refresh.py:393-402 \u2014 the copies span different directories, so extracting a shared function means choosing where it lives: put it somewhere all 3 call sites can already reach \u2014 a location they all depend on today, or a new shared one if there is none \u2014 and call it from each site; until then, every change has to be made 3 times. 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":"backend/core/ddd_orchestrator.py"},"region":{"startLine":256}}}],"partialFingerprints":{"codehealthFindingId/v1":"5f53d8f8e7d917257354f0f2c445907a42c3aa6bb55050ebb8a96db85634d616"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7\u201310 lines \u00D7 2): backend/channels/adapters/slack.py:1912-1918 | backend/channels/adapters/slack.py:1997-2006 \u2014 both copies are in the same file, so extract the block 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":"backend/channels/adapters/slack.py"},"region":{"startLine":1912}}}],"partialFingerprints":{"codehealthFindingId/v1":"a518c196be1eaefb4b01a65f12eac8881309eb5ef95da0f7ac23ab38868e437a"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (10 lines \u00D7 2): backend/channels/gateway.py:1575-1584 | backend/core/conversation_extract.py:57-66 \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":"backend/channels/gateway.py"},"region":{"startLine":1575}}}],"partialFingerprints":{"codehealthFindingId/v1":"37709da45b632731836f388cffef29e45cda8acde58e840a43f2cb83e7957922"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (10 lines \u00D7 2): backend/core/plugin_manager.py:272-281 | backend/core/plugin_manager.py:382-391 \u2014 both copies are in the same file, so extract the block 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, \u0060backend/core/plugin_manager.py:270\u0060 calls \u0060get\u0060 and \u0060backend/core/plugin_manager.py:380\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":"backend/core/plugin_manager.py"},"region":{"startLine":272}}}],"partialFingerprints":{"codehealthFindingId/v1":"05d8696e612b2b4b1dc40a99bd5b99a0ea491580daa4f94316e595c0d6188ab6"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (8\u201310 lines \u00D7 2): backend/core/security_hooks.py:827-836 | backend/core/security_hooks.py:2248-2255 \u2014 both copies are in the same file, so extract the block 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":"backend/core/security_hooks.py"},"region":{"startLine":827}}}],"partialFingerprints":{"codehealthFindingId/v1":"db4f24549f129122ddd9026432a579e3ad6f9070c5c3525a24205b713e6a5393"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (10 lines \u00D7 2): backend/schemas/auth.py:28-37 | backend/schemas/auth.py:87-96 \u2014 both copies are in the same file, so extract the block 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":"backend/schemas/auth.py"},"region":{"startLine":28}}}],"partialFingerprints":{"codehealthFindingId/v1":"b8d9c602ed395292262636aa1f76ca6a2c7dac7e49c9fa628195b5a22c2a4b0e"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (10 lines \u00D7 2): backend/scripts/artifact_cli.py:4892-4901 | backend/scripts/pipeline_analytics.py:188-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 both call sites, so a change lands once."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/scripts/artifact_cli.py"},"region":{"startLine":4892}}}],"partialFingerprints":{"codehealthFindingId/v1":"da924d43492ff3f9c4b304dff6551b9363b1ec5bf77b07dbac36e4c5807bc969"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (10 lines \u00D7 2): backend/skills/s_frontend-design/scripts/design_system.py:519-528 | backend/skills/s_frontend-design/scripts/design_system.py:874-883 \u2014 both copies are in the same file, so extract the block 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":"backend/skills/s_frontend-design/scripts/design_system.py"},"region":{"startLine":519}}}],"partialFingerprints":{"codehealthFindingId/v1":"0d305f2dcea4d184210c79f21ffd1f0f42e5f4db28808dbc0b8b0b1f821c14fc"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (10 lines \u00D7 2): backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:3612-3621 | backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:3243-3252 \u2014 before extracting anything, compare \u0060backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py\u0060 and \u0060backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py\u0060 as WHOLE FILES: this scan already matched 79 separate duplicated blocks between them, totalling at least 2758 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py"},"region":{"startLine":3612}}}],"partialFingerprints":{"codehealthFindingId/v1":"78e27646ff5cca7e8a0813cb98163194f619bf1241d59f1a6b9840a3aeaedc14"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9 lines \u00D7 12): backend/skills/s_docx/ooxml/scripts/validation/base.py:262-270 | backend/skills/s_docx/ooxml/scripts/validation/docx.py:109-117 | backend/skills/s_docx/ooxml/scripts/validation/docx.py:158-166 | backend/skills/s_docx/ooxml/scripts/validation/docx.py:248-256 | backend/skills/s_docx/ooxml/scripts/validation/pptx.py:106-114 | backend/skills/s_docx/ooxml/scripts/validation/pptx.py:185-193 | backend/skills/s_pptx/ooxml/scripts/validation/base.py:265-273 | backend/skills/s_pptx/ooxml/scripts/validation/docx.py:109-117 | backend/skills/s_pptx/ooxml/scripts/validation/docx.py:158-166 | backend/skills/s_pptx/ooxml/scripts/validation/docx.py:248-256 | backend/skills/s_pptx/ooxml/scripts/validation/pptx.py:106-114 | backend/skills/s_pptx/ooxml/scripts/validation/pptx.py:185-193 \u2014 before extracting anything, compare \u0060backend/skills/s_docx/ooxml/scripts/validation/base.py\u0060 and \u0060backend/skills/s_pptx/ooxml/scripts/validation/base.py\u0060 as WHOLE FILES: this scan already matched 20 separate duplicated blocks between them, totalling at least 820 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":"backend/skills/s_docx/ooxml/scripts/validation/base.py"},"region":{"startLine":262}}}],"partialFingerprints":{"codehealthFindingId/v1":"75eebb8d1c1ebf1841c50c90334937d3b96322700130e3c3dcd78402cb557d2c"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9 lines \u00D7 10): backend/database/sqlite.py:2894-2902 | backend/database/sqlite.py:2906-2914 | backend/database/sqlite.py:2963-2971 | backend/database/sqlite.py:2976-2984 | backend/database/sqlite.py:2992-3000 | backend/database/sqlite.py:3023-3031 | backend/database/sqlite.py:3071-3079 | backend/database/sqlite.py:3084-3092 | backend/database/sqlite.py:3097-3105 | backend/database/sqlite.py:3118-3126 \u2014 all 10 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, \u0060backend/database/sqlite.py:2906\u0060 calls \u0060execute\u0060, \u0060fetchall\u0060 and \u0060backend/database/sqlite.py:2918\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":"backend/database/sqlite.py"},"region":{"startLine":2894}}}],"partialFingerprints":{"codehealthFindingId/v1":"e0d7d7e17560e295186b4be32e18cbb7dfe48133b425a100dc66af8abd9a900b"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (8\u20139 lines \u00D7 3): backend/skills/s_pollinate/scripts/tts/backends/azure.py:26-33 | backend/skills/s_pollinate/scripts/tts/backends/edge.py:24-31 | backend/skills/s_pollinate/scripts/tts/backends/polly.py:275-283 \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. \u2605 These copies have DRIFTED, and that is worth reading before extracting anything: just before the matched lines, \u0060backend/skills/s_pollinate/scripts/tts/backends/azure.py:22\u0060 calls \u0060get\u0060 and \u0060backend/skills/s_pollinate/scripts/tts/backends/polly.py:272\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":"backend/skills/s_pollinate/scripts/tts/backends/azure.py"},"region":{"startLine":26}}}],"partialFingerprints":{"codehealthFindingId/v1":"45ae8ec16e4f5d219e4534ad3337d33905bd6e9d0deaa7420f4c04aa5e6755ca"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9 lines \u00D7 2): backend/channels/gateway.py:513-522 | backend/channels/gateway.py:606-614 \u2014 both copies are in the same file, so extract the block 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":"backend/channels/gateway.py"},"region":{"startLine":513}}}],"partialFingerprints":{"codehealthFindingId/v1":"b0191ba36b5ce662e5f953fe88271baf8c4fab03b7d44a2a99fc39e8891f1d3b"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9 lines \u00D7 2): backend/core/code_intel/graph_store.py:539-547 | backend/core/code_intel/graph_store.py:668-676 \u2014 both copies are in the same file, so extract the block 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":"backend/core/code_intel/graph_store.py"},"region":{"startLine":539}}}],"partialFingerprints":{"codehealthFindingId/v1":"45cdd36f789ca7da8bf62a788febcecdab1cb9b400c80ac180e56c0328a6394f"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9 lines \u00D7 2): backend/core/code_intel/graph_store.py:533-541 | backend/core/code_intel/graph_store.py:576-584 \u2014 both copies are in the same file, so extract the block 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 \u0060backend/core/code_intel/graph_store.py:533\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":"backend/core/code_intel/graph_store.py"},"region":{"startLine":533}}}],"partialFingerprints":{"codehealthFindingId/v1":"08a573e1a798b3f419f8d5a2f39e6d7da5d614a5fb254247ed4c683bb27931ac"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9 lines \u00D7 2): backend/core/code_intel/json_exporter.py:141-149 | backend/core/code_intel/json_exporter.py:196-204 \u2014 both copies are in the same file, so extract the block into one function there and call it from each site \u2014 the copies drift apart the first time only one of them is edited."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/core/code_intel/json_exporter.py"},"region":{"startLine":141}}}],"partialFingerprints":{"codehealthFindingId/v1":"e3e9b34a422edae1ed91947f831e3dcac3a1f59010c4f54aef930445108c0bf4"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9 lines \u00D7 2): backend/database/sqlite.py:525-533 | backend/database/sqlite.py:1671-1679 \u2014 both copies are in the same file, so extract the block 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":"backend/database/sqlite.py"},"region":{"startLine":525}}}],"partialFingerprints":{"codehealthFindingId/v1":"a0ca178529eefc5376bdc28ac311036aadeff9b5b18c1622f6f595b40713a247"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9 lines \u00D7 2): backend/database/sqlite.py:1433-1441 | backend/database/sqlite.py:1465-1473 \u2014 both copies are in the same file, so extract the block 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":"backend/database/sqlite.py"},"region":{"startLine":1433}}}],"partialFingerprints":{"codehealthFindingId/v1":"009b2d868dc863e6707cd31a1d8954afe203bc84265e3b77b8c07058fa85cf37"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9 lines \u00D7 2): backend/hive/provisioner.py:674-685 | backend/hive/provisioner.py:1553-1561 \u2014 both copies are in the same file, so extract the block 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 \u0060backend/hive/provisioner.py:674\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":"backend/hive/provisioner.py"},"region":{"startLine":674}}}],"partialFingerprints":{"codehealthFindingId/v1":"b63736b6d565b5a03fd833ff11de4a6379bb854e4b6ac4b35f6fffe890d90b26"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9 lines \u00D7 2): backend/hooks/daily_activity_hook.py:349-357 | backend/hooks/distillation_hook.py:1472-1480 \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":"backend/hooks/daily_activity_hook.py"},"region":{"startLine":349}}}],"partialFingerprints":{"codehealthFindingId/v1":"51f17ef91dae93db3ced49ee22f9dbc83b9616771b7729e9186c4a94347630c3"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9 lines \u00D7 2): backend/jobs/executor.py:313-321 | backend/jobs/executor.py:349-357 \u2014 both copies are in the same file, so extract the block 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":"backend/jobs/executor.py"},"region":{"startLine":313}}}],"partialFingerprints":{"codehealthFindingId/v1":"8f789229a85bfdc89e7427e7c0373998d2ed90041df894381af87c043d457ff4"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9 lines \u00D7 2): backend/jobs/executor.py:387-395 | backend/jobs/executor.py:406-414 \u2014 both copies are in the same file, so extract the block 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 \u0060backend/jobs/executor.py:387\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":"backend/jobs/executor.py"},"region":{"startLine":387}}}],"partialFingerprints":{"codehealthFindingId/v1":"7cd5b9ea0a291693425093115269856b408310619d83a7e9e254608293498827"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9 lines \u00D7 2): backend/jobs/handlers/ddd_refresh.py:201-209 | backend/jobs/handlers/ddd_refresh.py:212-220 \u2014 both copies are in the same file, so extract the block 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 \u0060backend/jobs/handlers/ddd_refresh.py:201\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":"backend/jobs/handlers/ddd_refresh.py"},"region":{"startLine":201}}}],"partialFingerprints":{"codehealthFindingId/v1":"beee5fb5d4e5e18d89dd14113011d4a1932525a0aa487637b5696449a5daa828"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9 lines \u00D7 2): backend/jobs/scheduler.py:555-563 | backend/jobs/scheduler.py:573-581 \u2014 both copies are in the same file, so extract the block 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, \u0060backend/jobs/scheduler.py:570\u0060 calls \u0060set\u0060 and \u0060backend/jobs/scheduler.py:549\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":"backend/jobs/scheduler.py"},"region":{"startLine":555}}}],"partialFingerprints":{"codehealthFindingId/v1":"99fb0bb6583f7a3b619530dc1e6bd180e467ae9de7ea261716c528739ff33fd4"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9 lines \u00D7 2): backend/routers/pollinate.py:508-516 | backend/routers/pollinate.py:679-687 \u2014 both copies are in the same file, so extract the block 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":"backend/routers/pollinate.py"},"region":{"startLine":508}}}],"partialFingerprints":{"codehealthFindingId/v1":"a5f5d26b986baa3eaf723b172dfd3f058dddc7c7fa340562fec5861269d342f0"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9 lines \u00D7 2): backend/scripts/artifact_cli.py:71-79 | backend/scripts/artifact_cli.py:2975-2983 \u2014 both copies are in the same file, so extract the block 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":"backend/scripts/artifact_cli.py"},"region":{"startLine":71}}}],"partialFingerprints":{"codehealthFindingId/v1":"39d22b03b4568190ec8eed8a67ce85b8b3e0fb71c08d45855ecd000f2e17600e"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9 lines \u00D7 2): backend/scripts/pipeline_analytics.py:786-794 | backend/scripts/pipeline_analytics.py:894-902 \u2014 both copies are in the same file, so extract the block 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":"backend/scripts/pipeline_analytics.py"},"region":{"startLine":786}}}],"partialFingerprints":{"codehealthFindingId/v1":"00573cc1d6402afd73d79b42611f641b44c4c9056dd4b0b03d536ab0b5dc36a2"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9 lines \u00D7 2): backend/scripts/scenario_runner.py:95-103 | backend/scripts/scenario_runner.py:148-156 \u2014 both copies are in the same file, so extract the block 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, \u0060backend/scripts/scenario_runner.py:146\u0060 calls \u0060get\u0060, \u0060isinstance\u0060 and \u0060backend/scripts/scenario_runner.py:94\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":"backend/scripts/scenario_runner.py"},"region":{"startLine":95}}}],"partialFingerprints":{"codehealthFindingId/v1":"f8beae268d0bde0e62b9c54f962c46812c224064d4f84e4a4a883a6a07e94e56"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9 lines \u00D7 2): backend/scripts/verify_build.py:339-347 | backend/scripts/verify_build.py:351-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. 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":"backend/scripts/verify_build.py"},"region":{"startLine":339}}}],"partialFingerprints":{"codehealthFindingId/v1":"f4207f954db3362da5205a826f537db9614e0f8baee8f3cba55166105eb18514"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7\u20139 lines \u00D7 2): backend/skills/s_frontend-design/scripts/design_system.py:816-822 | backend/skills/s_frontend-design/scripts/design_system.py:829-837 \u2014 both copies are in the same file, so extract the block 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":"backend/skills/s_frontend-design/scripts/design_system.py"},"region":{"startLine":816}}}],"partialFingerprints":{"codehealthFindingId/v1":"7040077a2cc96609bfa8390dd3a13a4a78cde691694b525e5706a99297683722"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9 lines \u00D7 2): backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:2964-2972 | backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:2977-2985 \u2014 both copies are in the same file, so extract the block 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":"backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py"},"region":{"startLine":2964}}}],"partialFingerprints":{"codehealthFindingId/v1":"8e436be694654053d01c2d423f6946cb11f72f487fe180a120ada47d8c11aa03"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (8 lines \u00D7 3): backend/skills/s_frontend-design/scripts/design_system.py:283-290 | backend/skills/s_frontend-design/scripts/design_system.py:423-430 | backend/skills/s_frontend-design/scripts/design_system.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":"backend/skills/s_frontend-design/scripts/design_system.py"},"region":{"startLine":283}}}],"partialFingerprints":{"codehealthFindingId/v1":"82b2d60d23afe0ee5e836fc1fd0a8ccb17e277d5551e1108239005c52fbe6f9e"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (8 lines \u00D7 2): backend/channels/gateway.py:908-915 | backend/channels/gateway.py:970-981 \u2014 both copies are in the same file, so extract the block 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":"backend/channels/gateway.py"},"region":{"startLine":908}}}],"partialFingerprints":{"codehealthFindingId/v1":"e49af76a634b132d241f8cdefdd01ecb495d9aa2d450075c70ca88a0906945b1"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (8 lines \u00D7 2): backend/core/proactive_intelligence.py:582-589 | backend/core/proactive_intelligence.py:662-669 \u2014 both copies are in the same file, so extract the block 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 after the matched lines, \u0060backend/core/proactive_intelligence.py:590\u0060 calls \u0060isinstance\u0060 and \u0060backend/core/proactive_intelligence.py:671\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":"backend/core/proactive_intelligence.py"},"region":{"startLine":582}}}],"partialFingerprints":{"codehealthFindingId/v1":"871ad7ed563c160afb967bfb0c9259f066b0ba6f39812cb6fb17c7cfdb416ef9"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (8 lines \u00D7 2): backend/jobs/handlers/ddd_weekly_report.py:151-158 | backend/jobs/handlers/swarmai_monthly_report.py:230-237 \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":"backend/jobs/handlers/ddd_weekly_report.py"},"region":{"startLine":151}}}],"partialFingerprints":{"codehealthFindingId/v1":"397894845e79bc211ec9ddaf011aa7c0841aef36f8fe2f329962bb89aef18353"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7\u20138 lines \u00D7 2): backend/routers/hive.py:637-643 | backend/routers/hive.py:657-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. 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":"backend/routers/hive.py"},"region":{"startLine":637}}}],"partialFingerprints":{"codehealthFindingId/v1":"88819fc15271e90348bee506188d5d322a9fa00db57e724cc005fa50ba130b21"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (8 lines \u00D7 2): backend/scripts/artifact_cli.py:5874-5881 | backend/scripts/artifact_cli.py:5941-5948 \u2014 both copies are in the same file, so extract the block 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":"backend/scripts/artifact_cli.py"},"region":{"startLine":5874}}}],"partialFingerprints":{"codehealthFindingId/v1":"9a8b83b51ac644e073f2cd1b7ff48daac6a052bad19035be4254394d259599d5"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (8 lines \u00D7 2): backend/scripts/evolution_escalation_probe.py:100-109 | backend/scripts/evolution_escalation_probe.py:121-128 \u2014 both copies are in the same file, so extract the block 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 \u0060backend/scripts/evolution_escalation_probe.py:100\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":"backend/scripts/evolution_escalation_probe.py"},"region":{"startLine":100}}}],"partialFingerprints":{"codehealthFindingId/v1":"60e1a4a74f05c455b03c2720d5e4c712c2121e1f90bc06695467a0160752fd9f"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (8 lines \u00D7 2): backend/scripts/pipeline_validator.py:1695-1704 | backend/scripts/pipeline_validator.py:3626-3633 \u2014 both copies are in the same file, so extract the block 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":"backend/scripts/pipeline_validator.py"},"region":{"startLine":1695}}}],"partialFingerprints":{"codehealthFindingId/v1":"d8bf795cc292dbcd7b034df1c7811a394b3ce107baeae79fc8fcf6a566a57c48"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (8 lines \u00D7 2): backend/scripts/pipeline_validator.py:1846-1853 | backend/scripts/pipeline_validator.py:1860-1867 \u2014 both copies are in the same file, so extract the block 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 \u0060backend/scripts/pipeline_validator.py:1846\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":"backend/scripts/pipeline_validator.py"},"region":{"startLine":1846}}}],"partialFingerprints":{"codehealthFindingId/v1":"ff030f370c092baa659369c9004f8df02bf80cd06c418bc64e7e575d07cfbcee"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6\u20137 lines \u00D7 6): backend/core/conversation_extract.py:121-126 | backend/core/memory_extractor.py:265-271 | backend/core/summarization.py:825-830 | backend/jobs/handlers/ddd_refresh.py:251-256 | backend/jobs/handlers/memory_health.py:476-481 | backend/jobs/handlers/skill_proposer.py:294-299 \u2014 the copies span different directories, so extracting a shared function means choosing where it lives: put it somewhere all 6 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 6 times."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/core/conversation_extract.py"},"region":{"startLine":121}}}],"partialFingerprints":{"codehealthFindingId/v1":"acdcf88c4003534ffe8c98be54e6eadcff348fbc5dc8ce039866d37e80f3a869"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 4): backend/skills/s_frontend-design/scripts/design_system.py:726-732 | backend/skills/s_frontend-design/scripts/design_system.py:744-750 | backend/skills/s_frontend-design/scripts/design_system.py:759-765 | backend/skills/s_frontend-design/scripts/design_system.py:789-797 \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":"backend/skills/s_frontend-design/scripts/design_system.py"},"region":{"startLine":726}}}],"partialFingerprints":{"codehealthFindingId/v1":"f7bb666821a31abe8804f7adb06f1ea24c041d8fcafcd598c729a39679bb888a"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 3): backend/core/summarization.py:532-538 | backend/hooks/skill_metrics_hook.py:184-190 | backend/hooks/skill_metrics_hook.py:235-241 \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":"backend/core/summarization.py"},"region":{"startLine":532}}}],"partialFingerprints":{"codehealthFindingId/v1":"96b44f7f7bfd525e9f0205a1b1f1b18dfdbac16428046343fa6c33b272803e3c"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 3): backend/jobs/scheduler.py:524-530 | backend/jobs/scheduler.py:554-560 | backend/jobs/scheduler.py:572-578 \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, \u0060backend/jobs/scheduler.py:570\u0060 calls \u0060set\u0060 and \u0060backend/jobs/scheduler.py:549\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":"backend/jobs/scheduler.py"},"region":{"startLine":524}}}],"partialFingerprints":{"codehealthFindingId/v1":"c5f8a9c27f14b50a7bdc9a100fa4e08d24b1743c38ec4b54656fffa9f58cdaf7"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 2): backend/core/conversation_extract.py:122-128 | backend/core/session_harvest.py:108-114 \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":"backend/core/conversation_extract.py"},"region":{"startLine":122}}}],"partialFingerprints":{"codehealthFindingId/v1":"56191334c908ea27c2c4107fe1da13f701d8f67c87f4f9ac13f546f8ef6eeeb1"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 2): backend/core/ddd_entry_lifecycle.py:573-579 | backend/core/ddd_entry_lifecycle.py:713-719 \u2014 both copies are in the same file, so extract the block 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":"backend/core/ddd_entry_lifecycle.py"},"region":{"startLine":573}}}],"partialFingerprints":{"codehealthFindingId/v1":"9a78b1774c5c5432f6322064e2acdb45061e636293294b2ac8a26c93eeb820f4"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 2): backend/jobs/handlers/swarmai_monthly_report.py:500-506 | backend/jobs/handlers/swarmai_monthly_report.py:508-514 \u2014 both copies are in the same file, so extract the block 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 \u0060backend/jobs/handlers/swarmai_monthly_report.py:500\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":"backend/jobs/handlers/swarmai_monthly_report.py"},"region":{"startLine":500}}}],"partialFingerprints":{"codehealthFindingId/v1":"f3aca4b7bf3e44269c9bf682bb007d13494820d6a348fe57f00057f749afb811"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 2): backend/routers/hive.py:495-501 | backend/routers/hive.py:517-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. 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":"backend/routers/hive.py"},"region":{"startLine":495}}}],"partialFingerprints":{"codehealthFindingId/v1":"f034aeda7008468a51cc957c9ed973f302b8dcace99b59780eff24521f2435cb"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 2): backend/scripts/artifact_cli.py:2084-2090 | backend/scripts/artifact_cli.py:2382-2388 \u2014 both copies are in the same file, so extract the block 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":"backend/scripts/artifact_cli.py"},"region":{"startLine":2084}}}],"partialFingerprints":{"codehealthFindingId/v1":"6d5abe25ea49f6eabee4fab1a99f4caacd59c68bebc85b17f9b4d2bb5f45fac1"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 2): backend/scripts/artifact_cli.py:5821-5827 | backend/scripts/artifact_cli.py:5947-5953 \u2014 both copies are in the same file, so extract the block 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":"backend/scripts/artifact_cli.py"},"region":{"startLine":5821}}}],"partialFingerprints":{"codehealthFindingId/v1":"5ae92bbcfd838df2774376350a709bb3430068086106a638bd1705342c6162ce"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 2): backend/scripts/pipeline_validator.py:2902-2911 | backend/scripts/pipeline_validator.py:3212-3218 \u2014 both copies are in the same file, so extract the block 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 \u0060backend/scripts/pipeline_validator.py:2902\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":"backend/scripts/pipeline_validator.py"},"region":{"startLine":2902}}}],"partialFingerprints":{"codehealthFindingId/v1":"8c87568302c5d5f3443ce89db0c92f10e964c60130e6e2dd8f862f9d839ff4c2"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 2): backend/skills/s_frontend-design/scripts/design_system.py:443-449 | backend/skills/s_frontend-design/scripts/design_system.py:838-844 \u2014 both copies are in the same file, so extract the block 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":"backend/skills/s_frontend-design/scripts/design_system.py"},"region":{"startLine":443}}}],"partialFingerprints":{"codehealthFindingId/v1":"c16e806f27508346d005126573136e2567599f41e3251e1d085a2772b5fa99de"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 2): backend/skills/s_pollinate/scripts/check_rpv.py:19-25 | backend/skills/s_pollinate/scripts/check_rpv.py:93-99 \u2014 both copies are in the same file, so extract the block 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":"backend/skills/s_pollinate/scripts/check_rpv.py"},"region":{"startLine":19}}}],"partialFingerprints":{"codehealthFindingId/v1":"958187902f52293442bcac13965e3aaaf636ea4312979b825622f11ddf9323b0"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 2): backend/skills/s_pptx/scripts/style-extract.py:95-101 | backend/skills/s_pptx/scripts/style-extract.py:109-115 \u2014 both copies are in the same file, so extract the block 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":"backend/skills/s_pptx/scripts/style-extract.py"},"region":{"startLine":95}}}],"partialFingerprints":{"codehealthFindingId/v1":"19b5153ab4ceb5680fc89314bc1a028c75b76b690d1a167de2f44ff2f6ac55c1"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 2): backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:241-247 | backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:240-246 \u2014 before extracting anything, compare \u0060backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py\u0060 and \u0060backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py\u0060 as WHOLE FILES: this scan already matched 79 separate duplicated blocks between them, totalling at least 2758 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py"},"region":{"startLine":241}}}],"partialFingerprints":{"codehealthFindingId/v1":"5b59b482af37f927e1cd4b63b6292e6a1520cb1619d54e437f7156f1c4693e52"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 2): backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:1505-1511 | backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:1216-1222 \u2014 before extracting anything, compare \u0060backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py\u0060 and \u0060backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py\u0060 as WHOLE FILES: this scan already matched 79 separate duplicated blocks between them, totalling at least 2758 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py"},"region":{"startLine":1505}}}],"partialFingerprints":{"codehealthFindingId/v1":"ca3b52a1a7a9d4116f6aed810042c3b61731840eea6f805d97f505c557840bc8"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 6): backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:2820-2825 | backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:2827-2832 | backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:2834-2839 | backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:2473-2478 | backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:2480-2485 | backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:2487-2492 \u2014 before extracting anything, compare \u0060backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py\u0060 and \u0060backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py\u0060 as WHOLE FILES: this scan already matched 79 separate duplicated blocks between them, totalling at least 2758 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 \u0060backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:2820\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":"backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py"},"region":{"startLine":2820}}}],"partialFingerprints":{"codehealthFindingId/v1":"f2fcee57f2abc511faeedb133bea0851333e7fc030872b63be39a0afe167293e"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 5): backend/core/conversation_extract.py:122-127 | backend/core/session_harvest.py:108-113 | backend/jobs/handlers/ddd_refresh.py:252-258 | backend/jobs/handlers/memory_health.py:477-483 | backend/jobs/handlers/skill_proposer.py:295-301 \u2014 the copies span different directories, so extracting a shared function means choosing where it lives: put it somewhere all 5 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 5 times."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/core/conversation_extract.py"},"region":{"startLine":122}}}],"partialFingerprints":{"codehealthFindingId/v1":"d8a8be54327f4470697be0aadc912c36c3f6cccaffb3525d86543b250b38ff77"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 4): backend/core/memory_extractor.py:113-118 | backend/core/session_miner.py:151-156 | backend/core/summarization.py:696-701 | backend/core/transcript_indexer.py:79-84 \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. \u2605 These copies have DRIFTED, and that is worth reading before extracting anything: just after the matched lines, \u0060backend/core/memory_extractor.py:119\u0060 calls \u0060get\u0060 and \u0060backend/core/session_miner.py:157\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":"backend/core/memory_extractor.py"},"region":{"startLine":113}}}],"partialFingerprints":{"codehealthFindingId/v1":"5d3c7e661e23b72e14ab176ebfa9bb2ac9ad313235cc99e5af174600457d9fa0"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 4): backend/skills/s_pollinate/scripts/check_rpv.py:25-30 | backend/skills/s_pollinate/scripts/check_rpv.py:67-72 | backend/skills/s_pollinate/scripts/check_rpv.py:143-148 | backend/skills/s_pollinate/scripts/check_rpv.py:171-178 \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. \u2605 These copies have DRIFTED, and that is worth reading before extracting anything: just after the matched lines, \u0060backend/skills/s_pollinate/scripts/check_rpv.py:31\u0060 calls \u0060get\u0060 and \u0060backend/skills/s_pollinate/scripts/check_rpv.py:149\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":"backend/skills/s_pollinate/scripts/check_rpv.py"},"region":{"startLine":25}}}],"partialFingerprints":{"codehealthFindingId/v1":"b66533a2dc30530c385a510b6306b758f9fef0e426eb73bfab47e36cb211d2f6"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 3): backend/routers/hive.py:495-500 | backend/routers/hive.py:517-522 | backend/routers/hive.py:541-547 \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":"backend/routers/hive.py"},"region":{"startLine":495}}}],"partialFingerprints":{"codehealthFindingId/v1":"d4902be0e927835656fee3538a363a5a2572032472394300ef6b92a09b94c3ee"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 3): backend/scripts/artifact_cli.py:5821-5826 | backend/scripts/artifact_cli.py:5903-5908 | backend/scripts/artifact_cli.py:5947-5952 \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":"backend/scripts/artifact_cli.py"},"region":{"startLine":5821}}}],"partialFingerprints":{"codehealthFindingId/v1":"82be84ad6079571b53b56a8d4e46ddd0b3975479624a11b264aabf89af53e3ac"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 3): backend/scripts/artifact_cli.py:5931-5936 | backend/scripts/artifact_cli.py:5952-5957 | backend/scripts/artifact_cli.py:5962-5967 \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, \u0060backend/scripts/artifact_cli.py:5958\u0060 calls \u0060add_argument\u0060 and \u0060backend/scripts/artifact_cli.py:5968\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":"backend/scripts/artifact_cli.py"},"region":{"startLine":5931}}}],"partialFingerprints":{"codehealthFindingId/v1":"4d45aa3352b8761e53cd98fdd6105d22f4636439ba5099fafa6b5427b85aec71"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2): backend/core/ddd_packager.py:1293-1298 | backend/core/ddd_packager.py:1355-1360 \u2014 both copies are in the same file, so extract the block 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":"backend/core/ddd_packager.py"},"region":{"startLine":1293}}}],"partialFingerprints":{"codehealthFindingId/v1":"a22014df013174ea3b9939ea333dd429020756e08a11fac3ccbffb1bce378ad5"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2): backend/core/proactive_intelligence.py:972-977 | backend/core/proactive_intelligence.py:1089-1099 \u2014 both copies are in the same file, so extract the block 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":"backend/core/proactive_intelligence.py"},"region":{"startLine":972}}}],"partialFingerprints":{"codehealthFindingId/v1":"c9baec64d17a9d96a95ccec810a67f3379aeda0d6ea08062f29402d196634783"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2): backend/core/summarization.py:465-470 | backend/core/summarization.py:484-489 \u2014 both copies are in the same file, so extract the block 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":"backend/core/summarization.py"},"region":{"startLine":465}}}],"partialFingerprints":{"codehealthFindingId/v1":"fa493a194063ebc78ad0e73a8a72c598cb2e7c860a14cf998c60fa3b708d865f"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2): backend/database/sqlite.py:501-506 | backend/database/sqlite.py:1642-1648 \u2014 both copies are in the same file, so extract the block 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":"backend/database/sqlite.py"},"region":{"startLine":501}}}],"partialFingerprints":{"codehealthFindingId/v1":"e7f508c0cf6734b27acd36d985bd23379ecdade4e41a533064a1e58f3a54d5ff"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2): backend/hooks/distillation_hook.py:1892-1897 | backend/hooks/distillation_hook.py:1977-1982 \u2014 both copies are in the same file, so extract the block 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":"backend/hooks/distillation_hook.py"},"region":{"startLine":1892}}}],"partialFingerprints":{"codehealthFindingId/v1":"bf7fa7611662b8694939dff748c9e10d28fb1fad47daa0c4d799aee917431c4f"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2): backend/scripts/artifact_cli.py:5937-5942 | backend/scripts/artifact_cli.py:5974-5979 \u2014 both copies are in the same file, so extract the block 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":"backend/scripts/artifact_cli.py"},"region":{"startLine":5937}}}],"partialFingerprints":{"codehealthFindingId/v1":"bfe293ca6b14199696b32a4798d68de2f0efbc1752f3609493d98ac1ab0c89d1"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2): backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:1614-1619 | backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:1278-1283 \u2014 before extracting anything, compare \u0060backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py\u0060 and \u0060backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py\u0060 as WHOLE FILES: this scan already matched 79 separate duplicated blocks between them, totalling at least 2758 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 \u0060backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:1614\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":"backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py"},"region":{"startLine":1614}}}],"partialFingerprints":{"codehealthFindingId/v1":"88a53d81dacbca4a67a91d3e580ec3a2cf7d8de3cee76234021102732b9327a8"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2): scripts/security_scan.py:189-194 | scripts/security_scan.py:286-291 \u2014 both copies are in the same file, so extract the block 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":"scripts/security_scan.py"},"region":{"startLine":189}}}],"partialFingerprints":{"codehealthFindingId/v1":"9c58fe7b5855cd3bb2fa678c97b1789a8663141d8ed58d5c4b7155bcb35afebb"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 6): backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:227-231 | backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:234-238 | backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:241-245 | backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:226-230 | backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:233-237 | backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:240-244 \u2014 before extracting anything, compare \u0060backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py\u0060 and \u0060backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py\u0060 as WHOLE FILES: this scan already matched 79 separate duplicated blocks between them, totalling at least 2758 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py"},"region":{"startLine":227}}}],"partialFingerprints":{"codehealthFindingId/v1":"27395490304773486207ea273826e0fa219134fa8d509964a2e2f9242aa895cc"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): backend/routers/todos.py:111-116 | backend/routers/todos.py:127-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."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/routers/todos.py"},"region":{"startLine":111}}}],"partialFingerprints":{"codehealthFindingId/v1":"693cb42ae2b5dceb1af10797c0ff21e98b3cc7f4b8ec88df945f425ee0c4259e"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (4\u20135 lines \u00D7 3): backend/skills/s_frontend-design/scripts/design_system.py:439-443 | backend/skills/s_frontend-design/scripts/design_system.py:455-458 | backend/skills/s_frontend-design/scripts/design_system.py:491-495 \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":"backend/skills/s_frontend-design/scripts/design_system.py"},"region":{"startLine":439}}}],"partialFingerprints":{"codehealthFindingId/v1":"5c030c8004d50022c0191ffbb4787f0c7d12211f4f426545ddfc895e2083183c"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): backend/skills/s_frontend-design/scripts/design_system.py:485-491 | backend/skills/s_frontend-design/scripts/design_system.py:673-677 \u2014 both copies are in the same file, so extract the block 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":"backend/skills/s_frontend-design/scripts/design_system.py"},"region":{"startLine":485}}}],"partialFingerprints":{"codehealthFindingId/v1":"807517e30c8a44f4f05b64c649f85d6b7b5f60c967b6568fc5384b56a4809868"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:1622-1626 | backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:1286-1290 \u2014 before extracting anything, compare \u0060backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py\u0060 and \u0060backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py\u0060 as WHOLE FILES: this scan already matched 79 separate duplicated blocks between them, totalling at least 2758 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 \u0060backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:1622\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":"backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py"},"region":{"startLine":1622}}}],"partialFingerprints":{"codehealthFindingId/v1":"3eb877c812d59bfcf466c6f3fa1ecd51865d1bec82cecf7f1ae1554416aaccba"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 2): backend/core/daemon_guard.py:94-100 | desktop/resources/daemon/daemon_guard.py:94-100 \u2014 before extracting anything, compare \u0060backend/core/daemon_guard.py\u0060 and \u0060desktop/resources/daemon/daemon_guard.py\u0060 as WHOLE FILES: this scan already matched 11 separate duplicated blocks between them, totalling at least 280 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/core/daemon_guard.py"},"region":{"startLine":94}}}],"partialFingerprints":{"codehealthFindingId/v1":"006e4d6a919f49f311756fb6f4304248ef32627bcd2d4b229c6786913fb44de0"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (35 lines \u00D7 2): backend/core/daemon_guard.py:211-245 | desktop/resources/daemon/daemon_guard.py:211-245 \u2014 before extracting anything, compare \u0060backend/core/daemon_guard.py\u0060 and \u0060desktop/resources/daemon/daemon_guard.py\u0060 as WHOLE FILES: this scan already matched 11 separate duplicated blocks between them, totalling at least 280 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":"backend/core/daemon_guard.py"},"region":{"startLine":211}}}],"partialFingerprints":{"codehealthFindingId/v1":"45793913801ba80ff939f9b9b0a81aa90964fcd780f90c926781d72867a8120b"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (22 lines \u00D7 2): backend/core/daemon_guard.py:254-275 | desktop/resources/daemon/daemon_guard.py:254-275 \u2014 before extracting anything, compare \u0060backend/core/daemon_guard.py\u0060 and \u0060desktop/resources/daemon/daemon_guard.py\u0060 as WHOLE FILES: this scan already matched 11 separate duplicated blocks between them, totalling at least 280 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":"backend/core/daemon_guard.py"},"region":{"startLine":254}}}],"partialFingerprints":{"codehealthFindingId/v1":"0040af9c4172304dd706739f0e21888f9610859224750d9b8b1980607861df98"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (11 lines \u00D7 2): backend/core/daemon_guard.py:478-488 | desktop/resources/daemon/daemon_guard.py:478-488 \u2014 before extracting anything, compare \u0060backend/core/daemon_guard.py\u0060 and \u0060desktop/resources/daemon/daemon_guard.py\u0060 as WHOLE FILES: this scan already matched 11 separate duplicated blocks between them, totalling at least 280 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/core/daemon_guard.py"},"region":{"startLine":478}}}],"partialFingerprints":{"codehealthFindingId/v1":"c020f52c4568f48f77e506a531b3907e31dc3a6e1cb940c0871e473f4323e3c5"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (10 lines \u00D7 2): backend/core/eval_service.py:75-84 | backend/scripts/eval_runner.py:65-77 \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":"backend/core/eval_service.py"},"region":{"startLine":75}}}],"partialFingerprints":{"codehealthFindingId/v1":"424bc9bd7544a9b376a9de8e878de9a8ef03cf1f1f30e25af33d6bbaf192581a"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): backend/core/voice_synthesize.py:228-232 | backend/skills/s_pollinate/scripts/tts/backends/polly.py:147-151 \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":"backend/core/voice_synthesize.py"},"region":{"startLine":228}}}],"partialFingerprints":{"codehealthFindingId/v1":"2dca65d28d46d7af1ab80f76320d84e331033472378b08b99c13964524a2be14"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (8 lines \u00D7 2): backend/core/voice_synthesize.py:254-268 | backend/skills/s_pollinate/scripts/tts/backends/polly.py:155-162 \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":"backend/core/voice_synthesize.py"},"region":{"startLine":254}}}],"partialFingerprints":{"codehealthFindingId/v1":"e7fe2d92e9b9d218e69ed2375afea67e283cb68e4a963981cc9b96ccdd811ad3"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (15 lines \u00D7 2): backend/routers/artifacts.py:97-111 | backend/routers/workspace_api.py:123-137 \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":"backend/routers/artifacts.py"},"region":{"startLine":97}}}],"partialFingerprints":{"codehealthFindingId/v1":"0f0a8767a58ac323a57133164a5f699fdd9f0f224254f54491864eb9eb24dc65"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9 lines \u00D7 2): backend/skills/s_docx/ooxml/scripts/validation/base.py:816-824 | backend/skills/s_pptx/ooxml/scripts/validation/base.py:819-827 \u2014 before extracting anything, compare \u0060backend/skills/s_docx/ooxml/scripts/validation/base.py\u0060 and \u0060backend/skills/s_pptx/ooxml/scripts/validation/base.py\u0060 as WHOLE FILES: this scan already matched 20 separate duplicated blocks between them, totalling at least 820 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The \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":"backend/skills/s_docx/ooxml/scripts/validation/base.py"},"region":{"startLine":816}}}],"partialFingerprints":{"codehealthFindingId/v1":"d13bce3263039ea5fc1770c450dd246c08aa42301a221bcf9528f13d36d42eeb"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 2): backend/skills/s_docx/ooxml/scripts/validation/docx.py:264-270 | backend/skills/s_pptx/ooxml/scripts/validation/docx.py:264-270 \u2014 before extracting anything, compare \u0060backend/skills/s_docx/ooxml/scripts/validation/docx.py\u0060 and \u0060backend/skills/s_pptx/ooxml/scripts/validation/docx.py\u0060 as WHOLE FILES: this scan already matched 11 separate duplicated blocks between them, totalling at least 244 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":"backend/skills/s_docx/ooxml/scripts/validation/docx.py"},"region":{"startLine":264}}}],"partialFingerprints":{"codehealthFindingId/v1":"374250bca9422e979c19b9334d50453c7d89d83317cd094367d94ff799e4058b"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): backend/skills/s_docx/ooxml/scripts/validation/pptx.py:122-126 | backend/skills/s_pptx/ooxml/scripts/validation/pptx.py:122-126 \u2014 before extracting anything, compare \u0060backend/skills/s_docx/ooxml/scripts/validation/pptx.py\u0060 and \u0060backend/skills/s_pptx/ooxml/scripts/validation/pptx.py\u0060 as WHOLE FILES: this scan already matched 9 separate duplicated blocks between them, totalling at least 298 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The \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":"backend/skills/s_docx/ooxml/scripts/validation/pptx.py"},"region":{"startLine":122}}}],"partialFingerprints":{"codehealthFindingId/v1":"967f2bcf0faea042aefb7ea96191cbce09ceed3b0356c103071dddb3912f8cdd"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (23 lines \u00D7 2): backend/skills/s_docx/ooxml/scripts/validation/redlining.py:115-137 | backend/skills/s_pptx/ooxml/scripts/validation/redlining.py:115-137 \u2014 before extracting anything, compare \u0060backend/skills/s_docx/ooxml/scripts/validation/redlining.py\u0060 and \u0060backend/skills/s_pptx/ooxml/scripts/validation/redlining.py\u0060 as WHOLE FILES: this scan already matched 5 separate duplicated blocks between them, totalling at least 245 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The \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":"backend/skills/s_docx/ooxml/scripts/validation/redlining.py"},"region":{"startLine":115}}}],"partialFingerprints":{"codehealthFindingId/v1":"b5eced2597f575b87f88af3bcf0e4423899eb95cfebb13ce2661dd600871a288"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (8 lines \u00D7 2): backend/skills/s_frontend-design/scripts/core.py:93-100 | backend/skills/s_web-design-review/scripts/core.py:93-100 \u2014 before extracting anything, compare \u0060backend/skills/s_frontend-design/scripts/core.py\u0060 and \u0060backend/skills/s_web-design-review/scripts/core.py\u0060 as WHOLE FILES: this scan already matched 7 separate duplicated blocks between them, totalling at least 126 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":"backend/skills/s_frontend-design/scripts/core.py"},"region":{"startLine":93}}}],"partialFingerprints":{"codehealthFindingId/v1":"9369cff3f6158f4f3d09da941cdc69e93220cc75301c1672b24fb97d69453ba3"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (12 lines \u00D7 2): backend/skills/s_library/scripts/library.py:60-71 | backend/skills/s_loops-health/scripts/loops_health_check.py:29-40 \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":"backend/skills/s_library/scripts/library.py"},"region":{"startLine":60}}}],"partialFingerprints":{"codehealthFindingId/v1":"8b5fc5769faf8c68bbdf8e8f7c9fa8fc04fde77960006f1f9224052c3c988476"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (13 lines \u00D7 2): backend/skills/s_notify/notify.py:35-47 | backend/skills/s_radar-todo/scripts/todo_db.py:34-49 \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":"backend/skills/s_notify/notify.py"},"region":{"startLine":35}}}],"partialFingerprints":{"codehealthFindingId/v1":"171a5475bd41ae3f06261ab9e9eedb8d25a73c6958f7e2cd6400bd603cab63eb"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9 lines \u00D7 2): backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:722-730 | backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:636-644 \u2014 before extracting anything, compare \u0060backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py\u0060 and \u0060backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py\u0060 as WHOLE FILES: this scan already matched 79 separate duplicated blocks between them, totalling at least 2758 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 \u0060backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:722\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":"backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py"},"region":{"startLine":722}}}],"partialFingerprints":{"codehealthFindingId/v1":"3c9d7c784bc47027b5c81695268f74a3e6cb42dcbff401bf43b2e26f6fe78b67"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (21 lines \u00D7 2): backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:1872-1892 | backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:1536-1556 \u2014 before extracting anything, compare \u0060backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py\u0060 and \u0060backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py\u0060 as WHOLE FILES: this scan already matched 79 separate duplicated blocks between them, totalling at least 2758 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The \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":"backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py"},"region":{"startLine":1872}}}],"partialFingerprints":{"codehealthFindingId/v1":"2fb958b889c25ad9c4cbdb7ec4ca6fec1992e617341681ae50aac467ce2ae420"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (11 lines \u00D7 2): backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:2050-2060 | backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:3139-3149 \u2014 before extracting anything, compare \u0060backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py\u0060 and \u0060backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py\u0060 as WHOLE FILES: this scan already matched 79 separate duplicated blocks between them, totalling at least 2758 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py"},"region":{"startLine":2050}}}],"partialFingerprints":{"codehealthFindingId/v1":"c6a7f2f8d03acbacc33c3ac6f847381c9df60dfbcc3a5e317f6aad3bd7622446"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 2): backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:2224-2230 | backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:1876-1882 \u2014 before extracting anything, compare \u0060backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py\u0060 and \u0060backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py\u0060 as WHOLE FILES: this scan already matched 79 separate duplicated blocks between them, totalling at least 2758 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py"},"region":{"startLine":2224}}}],"partialFingerprints":{"codehealthFindingId/v1":"0ad041ad18268dbafaf36020e4ec983ddb9125f0b240927ae7a52bb86299d53a"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (15 lines \u00D7 2): backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:2234-2248 | backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:1886-1900 \u2014 before extracting anything, compare \u0060backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py\u0060 and \u0060backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py\u0060 as WHOLE FILES: this scan already matched 79 separate duplicated blocks between them, totalling at least 2758 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The \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":"backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py"},"region":{"startLine":2234}}}],"partialFingerprints":{"codehealthFindingId/v1":"217e8517e21833be26d557f9b0562308edb05ba355c636e2fd31a8d22e9b624a"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (11 lines \u00D7 2): backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:3551-3561 | backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:3182-3192 \u2014 before extracting anything, compare \u0060backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py\u0060 and \u0060backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py\u0060 as WHOLE FILES: this scan already matched 79 separate duplicated blocks between them, totalling at least 2758 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":"backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py"},"region":{"startLine":3551}}}],"partialFingerprints":{"codehealthFindingId/v1":"f8b7df43e68115cf68d9c53c36116b875bcb61465ad3131f1a1726828b947786"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:3640-3644 | backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:3271-3275 \u2014 before extracting anything, compare \u0060backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py\u0060 and \u0060backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py\u0060 as WHOLE FILES: this scan already matched 79 separate duplicated blocks between them, totalling at least 2758 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py"},"region":{"startLine":3640}}}],"partialFingerprints":{"codehealthFindingId/v1":"4facc97a10ddb71174a7e94412417e13368685b4db846d321dfaede6255e4186"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:3706-3710 | backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py:3337-3341 \u2014 before extracting anything, compare \u0060backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py\u0060 and \u0060backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py\u0060 as WHOLE FILES: this scan already matched 79 separate duplicated blocks between them, totalling at least 2758 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The \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":"backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py"},"region":{"startLine":3706}}}],"partialFingerprints":{"codehealthFindingId/v1":"52794c4ad09b4a6e35864c6795cf5e3353c0e5067ca7c4a5bc0322d8316a4aa0"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (14 lines \u00D7 2): backend/core/ddd_cultivation.py:578-592 | backend/core/ingestion_gate.py:145-158 \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":"backend/core/ddd_cultivation.py"},"region":{"startLine":578}}}],"partialFingerprints":{"codehealthFindingId/v1":"f29f1fb7f2556b6f867742869f3a2334b61afe256dc1af2e18d2aa2da5fb3811"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 3): backend/routers/tasks.py:162-166 | backend/routers/tasks.py:171-175 | backend/routers/todos.py:161-168 \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. 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":"backend/routers/tasks.py"},"region":{"startLine":162}}}],"partialFingerprints":{"codehealthFindingId/v1":"634df7b9fa4d28a34ed31a201ed018d93a1e87c9fd4d47eee057f0f2059c0e98"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): backend/scripts/memory_chain_probe.py:247-251 | backend/scripts/recall_chain_probe.py:273-277 \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":"backend/scripts/memory_chain_probe.py"},"region":{"startLine":247}}}],"partialFingerprints":{"codehealthFindingId/v1":"31efc14a4c9f06a21525ceacfe40b2d76a0147ed0680979c58e9303571c474b1"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2): backend/skills/s_frontend-design/scripts/design_system.py:342-347 | backend/skills/s_frontend-design/scripts/design_system.py:380-385 \u2014 both copies are in the same file, so extract the block 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":"backend/skills/s_frontend-design/scripts/design_system.py"},"region":{"startLine":342}}}],"partialFingerprints":{"codehealthFindingId/v1":"63d88caad4b051da475388728adbde4f030c7584973ec9ba791c566b98a6886e"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (19\u201323 lines \u00D7 2): scripts/smoke_e2e.py:163-185 | scripts/smoke_e2e.py:488-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. 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":"scripts/smoke_e2e.py"},"region":{"startLine":163}}}],"partialFingerprints":{"codehealthFindingId/v1":"695238514d4e91e581f4c1521822e47926824bdb507a40af22907745a9962151"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 2): scripts/smoke_e2e.py:353-359 | scripts/smoke_e2e.py:362-368 \u2014 both copies are in the same file, so extract the block 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":"scripts/smoke_e2e.py"},"region":{"startLine":353}}}],"partialFingerprints":{"codehealthFindingId/v1":"f0e9a3ebd620df47399dc0edf44032e36be4c77e5837b1132b5de7d378a78b05"}},{"ruleId":"D8","level":"warning","message":{"text":"Coverage not measured \u2014 JavaScript/TypeScript suite: Coverage NOT MEASURED: the JavaScript/TypeScript half could not be measured \u2014 desktop/ runs vitest but declares no coverage provider, so the suite can run and still produce no lcov \u2014 add \u0060@vitest/coverage-v8\u0060 (or \u0060@vitest/coverage-istanbul\u0060) as a devDependency. Coverage is excluded from the score rather than counted as a near-zero. The named suite step is one the repository\u0027s maintainers can perform; once it passes, the real number is measured on the next scan. Alternatively, commit the lcov/Cobertura report your CI produces and it is read without a re-run."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"62e63e619c28f057e129f2997c965d32a457366a9ce18ca019ffb6bdfba85c99"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: desktop/src/hooks/useChatStreamingLifecycle.ts: desktop/src/hooks/useChatStreamingLifecycle.ts changed 107 times in last 90 days, max cyclomatic complexity 308 in (anonymous) at line 2302. 70 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-06-16..2026-09-14, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-16 10:48:17 \u002B08:00\u0027 --until=\u00272026-09-14 10:48:17 \u002B08:00\u0027 --full-history --no-merges -- desktop/src/hooks/useChatStreamingLifecycle.ts\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":"desktop/src/hooks/useChatStreamingLifecycle.ts"},"region":{"startLine":2302}}}],"partialFingerprints":{"codehealthFindingId/v1":"c920e91b81d5ac9c4fed13c6933f10a48f137466b489f6a352c33fc4cb2fb6cf"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: backend/scripts/artifact_cli.py: backend/scripts/artifact_cli.py changed 80 times in last 90 days, max cyclomatic complexity 177 in artifact_cli.cmd_run_report at line 3992. 51 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-06-16..2026-09-14, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-16 10:48:17 \u002B08:00\u0027 --until=\u00272026-09-14 10:48:17 \u002B08:00\u0027 --full-history --no-merges -- backend/scripts/artifact_cli.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":"backend/scripts/artifact_cli.py"},"region":{"startLine":3992}}}],"partialFingerprints":{"codehealthFindingId/v1":"10e4c3e2252a398925c8b1066f60f9f51152e1e1964fb153bea4cfdae80ca650"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: backend/core/streaming_orchestrator.py: backend/core/streaming_orchestrator.py changed 48 times in last 90 days, max cyclomatic complexity 190 in StreamingOrchestrator._read_formatted_response at line 525. 22 of those changes were fix/bug commits, and the other 26 changed it for other reasons \u2014 this file is under both repair and feature pressure. Before the next change lands here, make sure the area it touches is under test, then split that area out of the file so the following change is smaller than this one \u2014 a file this often edited pays the complexity back every time. Counted over 2026-06-16..2026-09-14, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-16 10:48:17 \u002B08:00\u0027 --until=\u00272026-09-14 10:48:17 \u002B08:00\u0027 --full-history --no-merges -- backend/core/streaming_orchestrator.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":"backend/core/streaming_orchestrator.py"},"region":{"startLine":525}}}],"partialFingerprints":{"codehealthFindingId/v1":"e6beac393868621fe43a410bae298135f1879cc2fda9312fdaa5595053685446"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: backend/scripts/pipeline_validator.py: backend/scripts/pipeline_validator.py changed 41 times in last 90 days, max cyclomatic complexity 214 in pipeline_validator.validate at line 2603. 19 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-06-16..2026-09-14, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-16 10:48:17 \u002B08:00\u0027 --until=\u00272026-09-14 10:48:17 \u002B08:00\u0027 --full-history --no-merges -- backend/scripts/pipeline_validator.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":"backend/scripts/pipeline_validator.py"},"region":{"startLine":2603}}}],"partialFingerprints":{"codehealthFindingId/v1":"30d5a3102f381399dfa6a4b4b21a9ad69eb9ed34a3e636c0b9d37d691e2a07f3"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: backend/core/session_router.py: backend/core/session_router.py changed 81 times in last 90 days, max cyclomatic complexity 90 in SessionRouter.run_conversation at line 2782. 44 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-06-16..2026-09-14, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-16 10:48:17 \u002B08:00\u0027 --until=\u00272026-09-14 10:48:17 \u002B08:00\u0027 --full-history --no-merges -- backend/core/session_router.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":"backend/core/session_router.py"},"region":{"startLine":2782}}}],"partialFingerprints":{"codehealthFindingId/v1":"707d6cd828eddc18acecd0a4c7bf16580ecf3a5c41644b74a28fbe8b9f53147a"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: backend/core/session_unit.py: backend/core/session_unit.py changed 105 times in last 90 days, max cyclomatic complexity 65 in SessionUnit.send at line 1867. 55 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-06-16..2026-09-14, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-16 10:48:17 \u002B08:00\u0027 --until=\u00272026-09-14 10:48:17 \u002B08:00\u0027 --full-history --no-merges -- backend/core/session_unit.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":"backend/core/session_unit.py"},"region":{"startLine":1867}}}],"partialFingerprints":{"codehealthFindingId/v1":"8c32ce6faed57182969efdfa922cbbffd7fb70a729ea2ea34c190ffb84780171"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: desktop/src/pages/ChatPage.tsx: desktop/src/pages/ChatPage.tsx changed 94 times in last 90 days, max cyclomatic complexity 60 in (anonymous) at line 2156. 56 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-06-16..2026-09-14, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-16 10:48:17 \u002B08:00\u0027 --until=\u00272026-09-14 10:48:17 \u002B08:00\u0027 --full-history --no-merges -- desktop/src/pages/ChatPage.tsx\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":"desktop/src/pages/ChatPage.tsx"},"region":{"startLine":2156}}}],"partialFingerprints":{"codehealthFindingId/v1":"bb9769d1c4fd850558bf4dcf5c82e48e8f7a6feecaef9e2677a5415fcf495b2b"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: backend/scripts/eval_runner.py: backend/scripts/eval_runner.py changed 43 times in last 90 days, max cyclomatic complexity 86 in eval_runner.generate_html_report at line 2163. 18 of those changes were fix/bug commits, and the other 25 changed it for other reasons \u2014 this file is under both repair and feature pressure. Before the next change lands here, make sure the area it touches is under test, then split that area out of the file so the following change is smaller than this one \u2014 a file this often edited pays the complexity back every time. Counted over 2026-06-16..2026-09-14, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-16 10:48:17 \u002B08:00\u0027 --until=\u00272026-09-14 10:48:17 \u002B08:00\u0027 --full-history --no-merges -- backend/scripts/eval_runner.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":"backend/scripts/eval_runner.py"},"region":{"startLine":2163}}}],"partialFingerprints":{"codehealthFindingId/v1":"fc9b75df9c4526ea0e26abc080672f095d5461523e7a417b2acfb382fefe2d1e"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: backend/hooks/context_health_hook.py: backend/hooks/context_health_hook.py changed 84 times in last 90 days, max cyclomatic complexity 35 in ContextHealthHook._auto_cultivate_session_signals at line 1163. 40 of those changes were fix/bug commits, and the other 44 changed it for other reasons \u2014 this file is under both repair and feature pressure. Before the next change lands here, make sure the area it touches is under test, then split that area out of the file so the following change is smaller than this one \u2014 a file this often edited pays the complexity back every time. Counted over 2026-06-16..2026-09-14, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-16 10:48:17 \u002B08:00\u0027 --until=\u00272026-09-14 10:48:17 \u002B08:00\u0027 --full-history --no-merges -- backend/hooks/context_health_hook.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":"backend/hooks/context_health_hook.py"},"region":{"startLine":1163}}}],"partialFingerprints":{"codehealthFindingId/v1":"a42eb5d0737d1bc97ad9f96b7b1f35d6bc75ba5e490a7da5b8004633f08df8f3"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: backend/core/prompt_builder.py: backend/core/prompt_builder.py changed 44 times in last 90 days, max cyclomatic complexity 61 in PromptBuilder.build_system_prompt at line 825. 17 of those changes were fix/bug commits, and the other 27 changed it for other reasons \u2014 this file is under both repair and feature pressure. Before the next change lands here, make sure the area it touches is under test, then split that area out of the file so the following change is smaller than this one \u2014 a file this often edited pays the complexity back every time. Counted over 2026-06-16..2026-09-14, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-16 10:48:17 \u002B08:00\u0027 --until=\u00272026-09-14 10:48:17 \u002B08:00\u0027 --full-history --no-merges -- backend/core/prompt_builder.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":"backend/core/prompt_builder.py"},"region":{"startLine":825}}}],"partialFingerprints":{"codehealthFindingId/v1":"be63bd014f48c0610a914dcba67f12129837dd1941551560ad88410530539a99"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: backend/core/proactive_intelligence.py: backend/core/proactive_intelligence.py changed 38 times in last 90 days, max cyclomatic complexity 69 in proactive_intelligence.build_session_briefing_data at line 1884. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-16..2026-09-14, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-16 10:48:17 \u002B08:00\u0027 --until=\u00272026-09-14 10:48:17 \u002B08:00\u0027 --full-history --no-merges -- backend/core/proactive_intelligence.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":"backend/core/proactive_intelligence.py"},"region":{"startLine":1884}}}],"partialFingerprints":{"codehealthFindingId/v1":"2a0f27726101f5123142f3789a55ac3b93c5fbec99d3433c6f2199748e08ec08"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: backend/core/security_hooks.py: backend/core/security_hooks.py changed 42 times in last 90 days, max cyclomatic complexity 58 in security_hooks._segment_is_irreversible at line 284. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-16..2026-09-14, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-16 10:48:17 \u002B08:00\u0027 --until=\u00272026-09-14 10:48:17 \u002B08:00\u0027 --full-history --no-merges -- backend/core/security_hooks.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":"backend/core/security_hooks.py"},"region":{"startLine":284}}}],"partialFingerprints":{"codehealthFindingId/v1":"17cf86aab139e6df8da03bae6387704ec42e69cbdc63fb7cf3f7648082e4ba9f"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: backend/hooks/distillation_hook.py: backend/hooks/distillation_hook.py changed 31 times in last 90 days, max cyclomatic complexity 69 in DistillationTriggerHook._distill_files at line 451. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-16..2026-09-14, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-16 10:48:17 \u002B08:00\u0027 --until=\u00272026-09-14 10:48:17 \u002B08:00\u0027 --full-history --no-merges -- backend/hooks/distillation_hook.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":"backend/hooks/distillation_hook.py"},"region":{"startLine":451}}}],"partialFingerprints":{"codehealthFindingId/v1":"b588b9aedde7a0cc0743933ab72ceba18145f8844126261215f4aa811dc69050"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: backend/jobs/executor.py: backend/jobs/executor.py changed 25 times in last 90 days, max cyclomatic complexity 64 in executor.execute_job at line 154. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-16..2026-09-14, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-16 10:48:17 \u002B08:00\u0027 --until=\u00272026-09-14 10:48:17 \u002B08:00\u0027 --full-history --no-merges -- backend/jobs/executor.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":"backend/jobs/executor.py"},"region":{"startLine":154}}}],"partialFingerprints":{"codehealthFindingId/v1":"33dc39715c5173bffa85b806a9df2c8d8f9c9a0047647e3b71868ff21f2de160"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: backend/channels/gateway.py: backend/channels/gateway.py changed 9 times in last 90 days, max cyclomatic complexity 158 in ChannelGateway._handle_conversation at line 1619. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-16..2026-09-14, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-16 10:48:17 \u002B08:00\u0027 --until=\u00272026-09-14 10:48:17 \u002B08:00\u0027 --full-history --no-merges -- backend/channels/gateway.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":"backend/channels/gateway.py"},"region":{"startLine":1619}}}],"partialFingerprints":{"codehealthFindingId/v1":"a988f4104072b0ed25f3ccb5c1bdd71882813401e79e2200c646f9a4425fc78f"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: desktop/src/components/common/FileEditorCore.tsx: desktop/src/components/common/FileEditorCore.tsx changed 14 times in last 90 days, max cyclomatic complexity 96 in FileEditorCore at line 606. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-16..2026-09-14, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-16 10:48:17 \u002B08:00\u0027 --until=\u00272026-09-14 10:48:17 \u002B08:00\u0027 --full-history --no-merges -- desktop/src/components/common/FileEditorCore.tsx\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":"desktop/src/components/common/FileEditorCore.tsx"},"region":{"startLine":606}}}],"partialFingerprints":{"codehealthFindingId/v1":"9a467d4ba1746b8ff668d4388d73e87604a0be8c7a9a6c5e6c8d9737e19cb2ca"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: backend/main.py: backend/main.py changed 29 times in last 90 days, max cyclomatic complexity 45 in main.lifespan at line 938. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-16..2026-09-14, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-16 10:48:17 \u002B08:00\u0027 --until=\u00272026-09-14 10:48:17 \u002B08:00\u0027 --full-history --no-merges -- backend/main.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":"backend/main.py"},"region":{"startLine":938}}}],"partialFingerprints":{"codehealthFindingId/v1":"c202c1f8303102827e5232ae6de17830dc16c7a204f589b79ff508a84bdbfcff"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: desktop/src/components/layout/ThreeColumnLayout.tsx: desktop/src/components/layout/ThreeColumnLayout.tsx changed 53 times in last 90 days, max cyclomatic complexity 24 in NavSvgIcon at line 378. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-16..2026-09-14, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-16 10:48:17 \u002B08:00\u0027 --until=\u00272026-09-14 10:48:17 \u002B08:00\u0027 --full-history --no-merges -- desktop/src/components/layout/ThreeColumnLayout.tsx\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":"desktop/src/components/layout/ThreeColumnLayout.tsx"},"region":{"startLine":378}}}],"partialFingerprints":{"codehealthFindingId/v1":"f97ab264cd24af18efcd1a47a2fdbe96863fc4a7963f386de6153b5f166eddef"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: desktop/src/components/file-viewer/FileViewerPanel.tsx: desktop/src/components/file-viewer/FileViewerPanel.tsx changed 31 times in last 90 days, max cyclomatic complexity 38 in FileViewerPanelImpl at line 139. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-16..2026-09-14, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-16 10:48:17 \u002B08:00\u0027 --until=\u00272026-09-14 10:48:17 \u002B08:00\u0027 --full-history --no-merges -- desktop/src/components/file-viewer/FileViewerPanel.tsx\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":"desktop/src/components/file-viewer/FileViewerPanel.tsx"},"region":{"startLine":139}}}],"partialFingerprints":{"codehealthFindingId/v1":"9479a2fbbc4fa0a2b51f676a8929e90a0e20cb6ba7da0908353c40cca4d2a9b9"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: backend/core/ddd_entry_lifecycle.py: backend/core/ddd_entry_lifecycle.py changed 43 times in last 90 days, max cyclomatic complexity 27 in ddd_entry_lifecycle.parse_entries at line 521. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-16..2026-09-14, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-16 10:48:17 \u002B08:00\u0027 --until=\u00272026-09-14 10:48:17 \u002B08:00\u0027 --full-history --no-merges -- backend/core/ddd_entry_lifecycle.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":"backend/core/ddd_entry_lifecycle.py"},"region":{"startLine":521}}}],"partialFingerprints":{"codehealthFindingId/v1":"8876fa8f1095dec89a04220c16e601d5f46e01dfccf55dfa22218453e2bbc3f9"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: backend/core/ddd_cultivation.py: backend/core/ddd_cultivation.py changed 40 times in last 90 days, max cyclomatic complexity 28 in ddd_cultivation.apply_to_ddd at line 984. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-16..2026-09-14, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-16 10:48:17 \u002B08:00\u0027 --until=\u00272026-09-14 10:48:17 \u002B08:00\u0027 --full-history --no-merges -- backend/core/ddd_cultivation.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":"backend/core/ddd_cultivation.py"},"region":{"startLine":984}}}],"partialFingerprints":{"codehealthFindingId/v1":"3053e02226ebcd03d1b73d3adb35061cccc54c9bf4e89bb2a4086d845a19fdff"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py: backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py changed 25 times in last 90 days, max cyclomatic complexity 40 in ai_ready_helpers.extract_import_graph at line 2388. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-16..2026-09-14, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-16 10:48:17 \u002B08:00\u0027 --until=\u00272026-09-14 10:48:17 \u002B08:00\u0027 --full-history --no-merges -- backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.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":"backend/skills/s_repo-to-ddd/scripts/ai_ready_helpers.py"},"region":{"startLine":2388}}}],"partialFingerprints":{"codehealthFindingId/v1":"e8f06d4adf0234ad9c8b72e44fa41becb58f5fba71a79eab10d2cc176710a2be"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: desktop/src/stores/MessageStore.ts: desktop/src/stores/MessageStore.ts changed 31 times in last 90 days, max cyclomatic complexity 30 in _applyMerge at line 892. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-16..2026-09-14, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-16 10:48:17 \u002B08:00\u0027 --until=\u00272026-09-14 10:48:17 \u002B08:00\u0027 --full-history --no-merges -- desktop/src/stores/MessageStore.ts\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":"desktop/src/stores/MessageStore.ts"},"region":{"startLine":892}}}],"partialFingerprints":{"codehealthFindingId/v1":"0dd547417d038c5692088a6722d516523079706b173bedbf0450f3a107da823d"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: desktop/src/pages/EvalDashboard.tsx: desktop/src/pages/EvalDashboard.tsx changed 34 times in last 90 days, max cyclomatic complexity 26 in OverviewTab at line 289. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-16..2026-09-14, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-16 10:48:17 \u002B08:00\u0027 --until=\u00272026-09-14 10:48:17 \u002B08:00\u0027 --full-history --no-merges -- desktop/src/pages/EvalDashboard.tsx\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":"desktop/src/pages/EvalDashboard.tsx"},"region":{"startLine":289}}}],"partialFingerprints":{"codehealthFindingId/v1":"fee0103b6933c2759dfd1249799800494519d7b176dd1841cdc00336dcb886cd"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: backend/core/ddd_orchestrator.py: backend/core/ddd_orchestrator.py changed 29 times in last 90 days, max cyclomatic complexity 29 in DddCultivationOrchestrator._auto_apply_ddd_proposals at line 582. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-16..2026-09-14, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-16 10:48:17 \u002B08:00\u0027 --until=\u00272026-09-14 10:48:17 \u002B08:00\u0027 --full-history --no-merges -- backend/core/ddd_orchestrator.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":"backend/core/ddd_orchestrator.py"},"region":{"startLine":582}}}],"partialFingerprints":{"codehealthFindingId/v1":"e7e00f1ce04847892698ead8a10ba8c74386ad97e7a7992af1b9175e07347f12"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: backend/routers/chat.py: backend/routers/chat.py changed 30 times in last 90 days, max cyclomatic complexity 27 in chat.sse_with_heartbeat at line 336. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-16..2026-09-14, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-16 10:48:17 \u002B08:00\u0027 --until=\u00272026-09-14 10:48:17 \u002B08:00\u0027 --full-history --no-merges -- backend/routers/chat.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":"backend/routers/chat.py"},"region":{"startLine":336}}}],"partialFingerprints":{"codehealthFindingId/v1":"ac01592f3772d8675dbf7f2ea243f9b65e9442e57c63fe5abc0ca5fc0ea64f54"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: backend/core/evolution_optimizer.py: backend/core/evolution_optimizer.py changed 8 times in last 90 days, max cyclomatic complexity 97 in evolution_optimizer._run_evolution_cycle_locked at line 1148. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-16..2026-09-14, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-16 10:48:17 \u002B08:00\u0027 --until=\u00272026-09-14 10:48:17 \u002B08:00\u0027 --full-history --no-merges -- backend/core/evolution_optimizer.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":"backend/core/evolution_optimizer.py"},"region":{"startLine":1148}}}],"partialFingerprints":{"codehealthFindingId/v1":"cde18623add0b433d109251f1d62b6da67ab864736114f390d6b70d1ece33be9"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: desktop/src/pages/chat/components/TabView.tsx: desktop/src/pages/chat/components/TabView.tsx changed 23 times in last 90 days, max cyclomatic complexity 33 in (anonymous) at line 486. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-16..2026-09-14, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-16 10:48:17 \u002B08:00\u0027 --until=\u00272026-09-14 10:48:17 \u002B08:00\u0027 --full-history --no-merges -- desktop/src/pages/chat/components/TabView.tsx\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":"desktop/src/pages/chat/components/TabView.tsx"},"region":{"startLine":486}}}],"partialFingerprints":{"codehealthFindingId/v1":"128659587c1f9e7d555ee055cd57d0c476d776a07d7e263f633ed1fab24c76cf"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: desktop/src/components/file-viewer/FileViewer.tsx: desktop/src/components/file-viewer/FileViewer.tsx changed 19 times in last 90 days, max cyclomatic complexity 39 in fetchFileContent at line 262. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-16..2026-09-14, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-16 10:48:17 \u002B08:00\u0027 --until=\u00272026-09-14 10:48:17 \u002B08:00\u0027 --full-history --no-merges -- desktop/src/components/file-viewer/FileViewer.tsx\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":"desktop/src/components/file-viewer/FileViewer.tsx"},"region":{"startLine":262}}}],"partialFingerprints":{"codehealthFindingId/v1":"58adfb6a0f95b3d0c962be20500230d572b4e6aee4c5bd0decbc953fd3240dcf"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: backend/core/ddd_packager.py: backend/core/ddd_packager.py changed 27 times in last 90 days, max cyclomatic complexity 27 in ddd_packager.package_ddd at line 1838. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-16..2026-09-14, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-16 10:48:17 \u002B08:00\u0027 --until=\u00272026-09-14 10:48:17 \u002B08:00\u0027 --full-history --no-merges -- backend/core/ddd_packager.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":"backend/core/ddd_packager.py"},"region":{"startLine":1838}}}],"partialFingerprints":{"codehealthFindingId/v1":"b174c8d0c1397f513115c4f38431a540f010bbface4c6d800c6f44486af01d3b"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: backend/routers/workspace_api.py: backend/routers/workspace_api.py changed 18 times in last 90 days, max cyclomatic complexity 40 in workspace_api.resolve_path_to_physical at line 992. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-16..2026-09-14, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-16 10:48:17 \u002B08:00\u0027 --until=\u00272026-09-14 10:48:17 \u002B08:00\u0027 --full-history --no-merges -- backend/routers/workspace_api.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":"backend/routers/workspace_api.py"},"region":{"startLine":992}}}],"partialFingerprints":{"codehealthFindingId/v1":"8508dcecf5672c63f1bea173d40c803a8f91cf6e6253bd5efaea56e217184b99"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: backend/core/ui_actions.py: backend/core/ui_actions.py changed 21 times in last 90 days, max cyclomatic complexity 34 in ui_actions.build_surface_events 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-06-16..2026-09-14, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-16 10:48:17 \u002B08:00\u0027 --until=\u00272026-09-14 10:48:17 \u002B08:00\u0027 --full-history --no-merges -- backend/core/ui_actions.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":"backend/core/ui_actions.py"},"region":{"startLine":287}}}],"partialFingerprints":{"codehealthFindingId/v1":"62cacfbc624270bccc36cb4635e5da6d2a89cd5c2e82ebca9418584acd97d7b0"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: backend/core/recall_multi.py: backend/core/recall_multi.py changed 23 times in last 90 days, max cyclomatic complexity 30 in recall_multi._recall_ddd at line 701. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-16..2026-09-14, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-16 10:48:17 \u002B08:00\u0027 --until=\u00272026-09-14 10:48:17 \u002B08:00\u0027 --full-history --no-merges -- backend/core/recall_multi.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":"backend/core/recall_multi.py"},"region":{"startLine":701}}}],"partialFingerprints":{"codehealthFindingId/v1":"a8d2a8c15a3b5aa94c37da21d6d6f5925e8244860b5e77703b7de7c4b0a556fb"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: desktop/src/components/layout/BrainHub.tsx: desktop/src/components/layout/BrainHub.tsx changed 32 times in last 90 days, max cyclomatic complexity 21 in DistributeView at line 1173. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-16..2026-09-14, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-16 10:48:17 \u002B08:00\u0027 --until=\u00272026-09-14 10:48:17 \u002B08:00\u0027 --full-history --no-merges -- desktop/src/components/layout/BrainHub.tsx\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":"desktop/src/components/layout/BrainHub.tsx"},"region":{"startLine":1173}}}],"partialFingerprints":{"codehealthFindingId/v1":"69184739dc1a29ae58d3e016f78bec7fd9c4adf8bb2efe07bf17b994f5f14038"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: backend/core/code_intel/parser.py: backend/core/code_intel/parser.py changed 21 times in last 90 days, max cyclomatic complexity 32 in parser.parse_repo_with_coverage at line 1952. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-16..2026-09-14, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-16 10:48:17 \u002B08:00\u0027 --until=\u00272026-09-14 10:48:17 \u002B08:00\u0027 --full-history --no-merges -- backend/core/code_intel/parser.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":"backend/core/code_intel/parser.py"},"region":{"startLine":1952}}}],"partialFingerprints":{"codehealthFindingId/v1":"4e478f651ffbe9b2cb601fe07450e3ca1d77d64f41d3457e2276863f6e5fc34f"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: backend/core/swarm_workspace_manager.py: backend/core/swarm_workspace_manager.py changed 31 times in last 90 days, max cyclomatic complexity 21 in SwarmWorkspaceManager._cleanup_legacy_content at line 2092. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-16..2026-09-14, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-16 10:48:17 \u002B08:00\u0027 --until=\u00272026-09-14 10:48:17 \u002B08:00\u0027 --full-history --no-merges -- backend/core/swarm_workspace_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":"backend/core/swarm_workspace_manager.py"},"region":{"startLine":2092}}}],"partialFingerprints":{"codehealthFindingId/v1":"7707a4ea9a0411a6fe215e9f6b7412f32a820552d81369b6587b0dc4814cd5db"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: desktop/src/pages/chat/components/ChatInput.tsx: desktop/src/pages/chat/components/ChatInput.tsx changed 11 times in last 90 days, max cyclomatic complexity 57 in ChatInput at line 164. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-16..2026-09-14, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-16 10:48:17 \u002B08:00\u0027 --until=\u00272026-09-14 10:48:17 \u002B08:00\u0027 --full-history --no-merges -- desktop/src/pages/chat/components/ChatInput.tsx\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":"desktop/src/pages/chat/components/ChatInput.tsx"},"region":{"startLine":164}}}],"partialFingerprints":{"codehealthFindingId/v1":"e9f56730cfe2472f224efabc2090fa7225fdb892e9323c22e274ca6cb3da5684"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: backend/core/lifecycle_manager.py: backend/core/lifecycle_manager.py changed 34 times in last 90 days, max cyclomatic complexity 18 in LifecycleManager._check_streaming_timeout at line 653. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-16..2026-09-14, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-16 10:48:17 \u002B08:00\u0027 --until=\u00272026-09-14 10:48:17 \u002B08:00\u0027 --full-history --no-merges -- backend/core/lifecycle_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":"backend/core/lifecycle_manager.py"},"region":{"startLine":653}}}],"partialFingerprints":{"codehealthFindingId/v1":"5d9a1728aed1d61fee26506776e2deaf10ab2251f30662269e2da2fee2b5a938"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: backend/database/sqlite.py: backend/database/sqlite.py changed 21 times in last 90 days, max cyclomatic complexity 29 in SQLiteDatabase._run_versioned_migrations at line 2386. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-16..2026-09-14, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-16 10:48:17 \u002B08:00\u0027 --until=\u00272026-09-14 10:48:17 \u002B08:00\u0027 --full-history --no-merges -- backend/database/sqlite.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":"backend/database/sqlite.py"},"region":{"startLine":2386}}}],"partialFingerprints":{"codehealthFindingId/v1":"6b3154015718b72b64120cf18122f794ba7fd4120909402dc8a6d62905058555"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: backend/core/context_directory_loader.py: backend/core/context_directory_loader.py changed 20 times in last 90 days, max cyclomatic complexity 30 in ContextDirectoryLoader.ensure_directory at line 543. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-16..2026-09-14, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-16 10:48:17 \u002B08:00\u0027 --until=\u00272026-09-14 10:48:17 \u002B08:00\u0027 --full-history --no-merges -- backend/core/context_directory_loader.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":"backend/core/context_directory_loader.py"},"region":{"startLine":543}}}],"partialFingerprints":{"codehealthFindingId/v1":"903c0077d0d92779690dfca41b4da42db9b819c67fa8a4dad8381353a15e239a"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: backend/core/ingestion_gate.py: backend/core/ingestion_gate.py changed 17 times in last 90 days, max cyclomatic complexity 29 in ingestion_gate.ingestion_gate at line 633. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-16..2026-09-14, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-16 10:48:17 \u002B08:00\u0027 --until=\u00272026-09-14 10:48:17 \u002B08:00\u0027 --full-history --no-merges -- backend/core/ingestion_gate.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":"backend/core/ingestion_gate.py"},"region":{"startLine":633}}}],"partialFingerprints":{"codehealthFindingId/v1":"91ea0842057271f071436569f14802b248a25b28db3321d8921a5dcc3dc4e8ff"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: desktop/src/components/layout/CMBrainOverlay.tsx: desktop/src/components/layout/CMBrainOverlay.tsx changed 18 times in last 90 days, max cyclomatic complexity 27 in CMBrainContent at line 167. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-16..2026-09-14, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-16 10:48:17 \u002B08:00\u0027 --until=\u00272026-09-14 10:48:17 \u002B08:00\u0027 --full-history --no-merges -- desktop/src/components/layout/CMBrainOverlay.tsx\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":"desktop/src/components/layout/CMBrainOverlay.tsx"},"region":{"startLine":167}}}],"partialFingerprints":{"codehealthFindingId/v1":"cafa437e5c180bdc2dbd0431c0f334f14af9cc7194bc230c24cb2f930e122687"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: backend/core/code_intel/json_exporter.py: backend/core/code_intel/json_exporter.py changed 12 times in last 90 days, max cyclomatic complexity 39 in json_exporter.export_code_intel_json at line 36. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-16..2026-09-14, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-16 10:48:17 \u002B08:00\u0027 --until=\u00272026-09-14 10:48:17 \u002B08:00\u0027 --full-history --no-merges -- backend/core/code_intel/json_exporter.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":"backend/core/code_intel/json_exporter.py"},"region":{"startLine":36}}}],"partialFingerprints":{"codehealthFindingId/v1":"9e93d10fc055b5bb8504abf642cffc948eca270703bd4d1b4b6fdc2c10cd24c2"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: backend/core/memory_index.py: backend/core/memory_index.py changed 31 times in last 90 days, max cyclomatic complexity 15 in memory_index._bm25_scores at line 267. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-16..2026-09-14, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-16 10:48:17 \u002B08:00\u0027 --until=\u00272026-09-14 10:48:17 \u002B08:00\u0027 --full-history --no-merges -- backend/core/memory_index.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":"backend/core/memory_index.py"},"region":{"startLine":267}}}],"partialFingerprints":{"codehealthFindingId/v1":"b40a353ce8c1d99eeb5d6e0a4884e7b49a3a6c571ab2d8e3e3d3145d461471f4"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: backend/routers/pipelines.py: backend/routers/pipelines.py changed 13 times in last 90 days, max cyclomatic complexity 35 in pipelines.pipeline_analytics at line 444. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-16..2026-09-14, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-16 10:48:17 \u002B08:00\u0027 --until=\u00272026-09-14 10:48:17 \u002B08:00\u0027 --full-history --no-merges -- backend/routers/pipelines.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":"backend/routers/pipelines.py"},"region":{"startLine":444}}}],"partialFingerprints":{"codehealthFindingId/v1":"c6a8c7ccf92dd40968f88bfebdadc44d0f4888dd85cc57d57ec619efe1e13505"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: backend/routers/eval.py: backend/routers/eval.py changed 21 times in last 90 days, max cyclomatic complexity 20 in eval._build_learning_dashboard at line 429. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-16..2026-09-14, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-16 10:48:17 \u002B08:00\u0027 --until=\u00272026-09-14 10:48:17 \u002B08:00\u0027 --full-history --no-merges -- backend/routers/eval.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":"backend/routers/eval.py"},"region":{"startLine":429}}}],"partialFingerprints":{"codehealthFindingId/v1":"248dae1985b458bf9c74a579163269de0f3ad5425530e15ae979880932e13919"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: backend/routers/ddd_brain.py: backend/routers/ddd_brain.py changed 27 times in last 90 days, max cyclomatic complexity 15 in ddd_brain._brain_detail_metrics at line 763. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-16..2026-09-14, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-16 10:48:17 \u002B08:00\u0027 --until=\u00272026-09-14 10:48:17 \u002B08:00\u0027 --full-history --no-merges -- backend/routers/ddd_brain.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":"backend/routers/ddd_brain.py"},"region":{"startLine":763}}}],"partialFingerprints":{"codehealthFindingId/v1":"4a166e33893e992f33405f46681c390c2cc42181e2ecca423b387e66c6027291"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py: backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py changed 9 times in last 90 days, max cyclomatic complexity 40 in ai_ready_helpers.extract_import_graph at line 2041. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-16..2026-09-14, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-16 10:48:17 \u002B08:00\u0027 --until=\u00272026-09-14 10:48:17 \u002B08:00\u0027 --full-history --no-merges -- backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.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":"backend/templates/ddd-skills/s_repo-to-ddd/scripts/ai_ready_helpers.py"},"region":{"startLine":2041}}}],"partialFingerprints":{"codehealthFindingId/v1":"6c5f56d2e8353d50cdc08c51c4ca0e81327fb35396b606876a7fd816d9fc66ef"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: backend/core/memory_extractor.py: backend/core/memory_extractor.py changed 12 times in last 90 days, max cyclomatic complexity 29 in memory_extractor.extract_and_save at line 367. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-16..2026-09-14, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-16 10:48:17 \u002B08:00\u0027 --until=\u00272026-09-14 10:48:17 \u002B08:00\u0027 --full-history --no-merges -- backend/core/memory_extractor.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":"backend/core/memory_extractor.py"},"region":{"startLine":367}}}],"partialFingerprints":{"codehealthFindingId/v1":"8c093e31064e1968dbd28b6e7c1a5e1838ba1a4d62034a74687aa152ef2e96cc"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: desktop/src/services/chat.ts: desktop/src/services/chat.ts changed 19 times in last 90 days, max cyclomatic complexity 18 in consumeSSEStream at line 267. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-16..2026-09-14, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-16 10:48:17 \u002B08:00\u0027 --until=\u00272026-09-14 10:48:17 \u002B08:00\u0027 --full-history --no-merges -- desktop/src/services/chat.ts\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":"desktop/src/services/chat.ts"},"region":{"startLine":267}}}],"partialFingerprints":{"codehealthFindingId/v1":"8127afcb8e8a25befd1b0e4d257c12cd30ea5249f3d0dc26f9b9bf812708527e"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: backend/core/ddd_bindings.py: backend/core/ddd_bindings.py changed 18 times in last 90 days, max cyclomatic complexity 19 in ddd_bindings.describe_project_ddd_line at line 545. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-16..2026-09-14, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-16 10:48:17 \u002B08:00\u0027 --until=\u00272026-09-14 10:48:17 \u002B08:00\u0027 --full-history --no-merges -- backend/core/ddd_bindings.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":"backend/core/ddd_bindings.py"},"region":{"startLine":545}}}],"partialFingerprints":{"codehealthFindingId/v1":"a5cad719d969ed4e83fa740e331da32b43710543e1d157e0fa94bb83fa86c963"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: desktop/src/hooks/useCanvasHost.ts: desktop/src/hooks/useCanvasHost.ts changed 21 times in last 90 days, max cyclomatic complexity 16 in handleOpenFile at line 311. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-16..2026-09-14, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-16 10:48:17 \u002B08:00\u0027 --until=\u00272026-09-14 10:48:17 \u002B08:00\u0027 --full-history --no-merges -- desktop/src/hooks/useCanvasHost.ts\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":"desktop/src/hooks/useCanvasHost.ts"},"region":{"startLine":311}}}],"partialFingerprints":{"codehealthFindingId/v1":"77113d4b7d13a018e5bab600569610222eeb6f78660c9433b2dffe5d2671e1a9"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: desktop/src/pages/chat/components/AssistantMessageView.tsx: desktop/src/pages/chat/components/AssistantMessageView.tsx changed 7 times in last 90 days, max cyclomatic complexity 48 in AssistantMessageView 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-06-16..2026-09-14, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-16 10:48:17 \u002B08:00\u0027 --until=\u00272026-09-14 10:48:17 \u002B08:00\u0027 --full-history --no-merges -- desktop/src/pages/chat/components/AssistantMessageView.tsx\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":"desktop/src/pages/chat/components/AssistantMessageView.tsx"},"region":{"startLine":77}}}],"partialFingerprints":{"codehealthFindingId/v1":"1acf5dfa11929d18c952a4529dcaa21d969554cbadbea93235102493d0fa0289"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: desktop/src/pages/chat/components/ContentBlockRenderer.tsx: desktop/src/pages/chat/components/ContentBlockRenderer.tsx changed 10 times in last 90 days, max cyclomatic complexity 33 in ContentBlockRenderer at line 122. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-16..2026-09-14, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-16 10:48:17 \u002B08:00\u0027 --until=\u00272026-09-14 10:48:17 \u002B08:00\u0027 --full-history --no-merges -- desktop/src/pages/chat/components/ContentBlockRenderer.tsx\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":"desktop/src/pages/chat/components/ContentBlockRenderer.tsx"},"region":{"startLine":122}}}],"partialFingerprints":{"codehealthFindingId/v1":"d85c4a89c2e9647bf87c92819e4363714ecc5bfc50a3a2b7e29b7944dcc75d89"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: scripts/smoke_e2e.py: scripts/smoke_e2e.py changed 6 times in last 90 days, max cyclomatic complexity 55 in smoke_e2e.run_smoke at line 312. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-16..2026-09-14, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-16 10:48:17 \u002B08:00\u0027 --until=\u00272026-09-14 10:48:17 \u002B08:00\u0027 --full-history --no-merges -- scripts/smoke_e2e.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":"scripts/smoke_e2e.py"},"region":{"startLine":312}}}],"partialFingerprints":{"codehealthFindingId/v1":"6e6e467fde854229fed7777aef280ec67714d7d0bcbf26a55f6f1904286f748a"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: backend/jobs/handlers/code_intel_reindex.py: backend/jobs/handlers/code_intel_reindex.py changed 8 times in last 90 days, max cyclomatic complexity 40 in code_intel_reindex.reindex_projects at line 20. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-16..2026-09-14, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-16 10:48:17 \u002B08:00\u0027 --until=\u00272026-09-14 10:48:17 \u002B08:00\u0027 --full-history --no-merges -- backend/jobs/handlers/code_intel_reindex.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":"backend/jobs/handlers/code_intel_reindex.py"},"region":{"startLine":20}}}],"partialFingerprints":{"codehealthFindingId/v1":"feb5f654c358c4b2245b77e71afa9b77767ca0d28a0eedd2d4de5d16d54d4edb"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: backend/core/hook_builder.py: backend/core/hook_builder.py changed 21 times in last 90 days, max cyclomatic complexity 15 in hook_builder.build_hooks 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-06-16..2026-09-14, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-16 10:48:17 \u002B08:00\u0027 --until=\u00272026-09-14 10:48:17 \u002B08:00\u0027 --full-history --no-merges -- backend/core/hook_builder.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":"backend/core/hook_builder.py"},"region":{"startLine":229}}}],"partialFingerprints":{"codehealthFindingId/v1":"212dfd58c6004e0b963819719756b1e63536a05ace3b802a2213028198b95f44"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: backend/jobs/handlers/eval_scheduled.py: backend/jobs/handlers/eval_scheduled.py changed 8 times in last 90 days, max cyclomatic complexity 38 in eval_scheduled.run_eval_scheduled at line 138. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-16..2026-09-14, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-16 10:48:17 \u002B08:00\u0027 --until=\u00272026-09-14 10:48:17 \u002B08:00\u0027 --full-history --no-merges -- backend/jobs/handlers/eval_scheduled.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":"backend/jobs/handlers/eval_scheduled.py"},"region":{"startLine":138}}}],"partialFingerprints":{"codehealthFindingId/v1":"2abb571cd7642be4296e7ce5fac5c99509000dfbdbf71cf3230ebf2c8a432a40"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: backend/hooks/evolution_maintenance_hook.py: backend/hooks/evolution_maintenance_hook.py changed 12 times in last 90 days, max cyclomatic complexity 25 in EvolutionMaintenanceHook.execute at line 196. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-16..2026-09-14, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-16 10:48:17 \u002B08:00\u0027 --until=\u00272026-09-14 10:48:17 \u002B08:00\u0027 --full-history --no-merges -- backend/hooks/evolution_maintenance_hook.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":"backend/hooks/evolution_maintenance_hook.py"},"region":{"startLine":196}}}],"partialFingerprints":{"codehealthFindingId/v1":"0c30808b58ea19fb88affb2496cc2df1e9b61900e3b062a65f72450ca4ab86d8"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: backend/core/session_healing.py: backend/core/session_healing.py changed 20 times in last 90 days, max cyclomatic complexity 15 in session_healing.build_rich_checkpoint at line 937. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-16..2026-09-14, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-16 10:48:17 \u002B08:00\u0027 --until=\u00272026-09-14 10:48:17 \u002B08:00\u0027 --full-history --no-merges -- backend/core/session_healing.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":"backend/core/session_healing.py"},"region":{"startLine":937}}}],"partialFingerprints":{"codehealthFindingId/v1":"a3d64a5f9f3dbb89e55b2d1778c21342f9f23e2c5e1832b4938152fb0a9bc7ce"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: backend/skills/s_loops-health/scripts/loops_health_check.py: backend/skills/s_loops-health/scripts/loops_health_check.py changed 8 times in last 90 days, max cyclomatic complexity 35 in SelfLoopsHealthEngine.to_markdown at line 1228. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-16..2026-09-14, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-16 10:48:17 \u002B08:00\u0027 --until=\u00272026-09-14 10:48:17 \u002B08:00\u0027 --full-history --no-merges -- backend/skills/s_loops-health/scripts/loops_health_check.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":"backend/skills/s_loops-health/scripts/loops_health_check.py"},"region":{"startLine":1228}}}],"partialFingerprints":{"codehealthFindingId/v1":"2c89493066757d95c8366855d1967704dadf4669935d03ee0074345eabe0794d"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: backend/core/retry_manager.py: backend/core/retry_manager.py changed 11 times in last 90 days, max cyclomatic complexity 25 in RetryManager._retry_with_resume at line 265. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-16..2026-09-14, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-16 10:48:17 \u002B08:00\u0027 --until=\u00272026-09-14 10:48:17 \u002B08:00\u0027 --full-history --no-merges -- backend/core/retry_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":"backend/core/retry_manager.py"},"region":{"startLine":265}}}],"partialFingerprints":{"codehealthFindingId/v1":"d3c2bb07168c40a6202b320e5cac0e778876bd7efd56f387fedfc9fc639098ed"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: desktop/src/components/layout/DddCard.tsx: desktop/src/components/layout/DddCard.tsx changed 13 times in last 90 days, max cyclomatic complexity 21 in FullBody at line 291. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-16..2026-09-14, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-16 10:48:17 \u002B08:00\u0027 --until=\u00272026-09-14 10:48:17 \u002B08:00\u0027 --full-history --no-merges -- desktop/src/components/layout/DddCard.tsx\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":"desktop/src/components/layout/DddCard.tsx"},"region":{"startLine":291}}}],"partialFingerprints":{"codehealthFindingId/v1":"a0bbe77508f6ca4b80e8757e6c052c33af634861f8589ad016ed6c6601746e9c"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: desktop/src/components/file-viewer/CanvasOutputRail.tsx: desktop/src/components/file-viewer/CanvasOutputRail.tsx changed 17 times in last 90 days, max cyclomatic complexity 16 in OutputRow at line 109. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-16..2026-09-14, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-16 10:48:17 \u002B08:00\u0027 --until=\u00272026-09-14 10:48:17 \u002B08:00\u0027 --full-history --no-merges -- desktop/src/components/file-viewer/CanvasOutputRail.tsx\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":"desktop/src/components/file-viewer/CanvasOutputRail.tsx"},"region":{"startLine":109}}}],"partialFingerprints":{"codehealthFindingId/v1":"2d375ac9c26b9637c01dc81ac20dd9bc35db298f806a2f086317de9161f6f712"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: desktop/src/hooks/streaming-guards.ts: desktop/src/hooks/streaming-guards.ts changed 14 times in last 90 days, max cyclomatic complexity 19 in forceClearStreamVerdict at line 412. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-16..2026-09-14, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-16 10:48:17 \u002B08:00\u0027 --until=\u00272026-09-14 10:48:17 \u002B08:00\u0027 --full-history --no-merges -- desktop/src/hooks/streaming-guards.ts\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":"desktop/src/hooks/streaming-guards.ts"},"region":{"startLine":412}}}],"partialFingerprints":{"codehealthFindingId/v1":"902fad4bb813ba3dd5be0699c220520af84094a9dc1fcb5b8668c5f299df5bf3"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: backend/core/knowledge_store.py: backend/core/knowledge_store.py changed 12 times in last 90 days, max cyclomatic complexity 20 in knowledge_store.sync_knowledge_index at line 737. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-16..2026-09-14, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-16 10:48:17 \u002B08:00\u0027 --until=\u00272026-09-14 10:48:17 \u002B08:00\u0027 --full-history --no-merges -- backend/core/knowledge_store.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":"backend/core/knowledge_store.py"},"region":{"startLine":737}}}],"partialFingerprints":{"codehealthFindingId/v1":"236d5e4a40697833d67c701b67b2afb54b971f78e9f5c2fd28e03c9144ead1e7"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: backend/core/code_intel/graph_store.py: backend/core/code_intel/graph_store.py changed 16 times in last 90 days, max cyclomatic complexity 15 in GraphStore.store_file_nodes_edges at line 595. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-16..2026-09-14, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-16 10:48:17 \u002B08:00\u0027 --until=\u00272026-09-14 10:48:17 \u002B08:00\u0027 --full-history --no-merges -- backend/core/code_intel/graph_store.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":"backend/core/code_intel/graph_store.py"},"region":{"startLine":595}}}],"partialFingerprints":{"codehealthFindingId/v1":"1fdc39a7f94752c66ef10e3a767c88e6cc9b502c0b73a2ffc8aaa7e8d785fc53"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: backend/core/context_recall.py: backend/core/context_recall.py changed 16 times in last 90 days, max cyclomatic complexity 15 in context_recall.recall_context at line 258. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-16..2026-09-14, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-16 10:48:17 \u002B08:00\u0027 --until=\u00272026-09-14 10:48:17 \u002B08:00\u0027 --full-history --no-merges -- backend/core/context_recall.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":"backend/core/context_recall.py"},"region":{"startLine":258}}}],"partialFingerprints":{"codehealthFindingId/v1":"156e888f1bedf7ca4e4dc0dca3fc0c4e33daa1ab7dee462dcc8088deaf856492"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: backend/core/evolution/correction_tracker.py: backend/core/evolution/correction_tracker.py changed 10 times in last 90 days, max cyclomatic complexity 22 in correction_tracker._merge_drift at line 69. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-16..2026-09-14, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-16 10:48:17 \u002B08:00\u0027 --until=\u00272026-09-14 10:48:17 \u002B08:00\u0027 --full-history --no-merges -- backend/core/evolution/correction_tracker.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":"backend/core/evolution/correction_tracker.py"},"region":{"startLine":69}}}],"partialFingerprints":{"codehealthFindingId/v1":"69035a791d16134045074beef64f800035f77daf7932f64e160b07eaa884e69f"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: backend/core/claude_environment.py: backend/core/claude_environment.py changed 9 times in last 90 days, max cyclomatic complexity 24 in _ClaudeClientWrapper._extract_pid at line 81. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-16..2026-09-14, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-16 10:48:17 \u002B08:00\u0027 --until=\u00272026-09-14 10:48:17 \u002B08:00\u0027 --full-history --no-merges -- backend/core/claude_environment.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":"backend/core/claude_environment.py"},"region":{"startLine":81}}}],"partialFingerprints":{"codehealthFindingId/v1":"050c9f6a1281a7e01a450cdf3db11d65f32874f27f62f51bd695abce2ebe0ed6"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: backend/jobs/handlers/memory_health.py: backend/jobs/handlers/memory_health.py changed 5 times in last 90 days, max cyclomatic complexity 43 in memory_health._compress_evolution_entries at line 614. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-16..2026-09-14, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-16 10:48:17 \u002B08:00\u0027 --until=\u00272026-09-14 10:48:17 \u002B08:00\u0027 --full-history --no-merges -- backend/jobs/handlers/memory_health.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":"backend/jobs/handlers/memory_health.py"},"region":{"startLine":614}}}],"partialFingerprints":{"codehealthFindingId/v1":"d7145668cfd13d081a1d639698c8d47be0970ec0b8984bed5053cc8a4cd5cc97"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: backend/core/projection_layer.py: backend/core/projection_layer.py changed 6 times in last 90 days, max cyclomatic complexity 35 in ProjectionLayer.project_skills at line 227. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-16..2026-09-14, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-16 10:48:17 \u002B08:00\u0027 --until=\u00272026-09-14 10:48:17 \u002B08:00\u0027 --full-history --no-merges -- backend/core/projection_layer.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":"backend/core/projection_layer.py"},"region":{"startLine":227}}}],"partialFingerprints":{"codehealthFindingId/v1":"e484e6e424547f374a41e4c819310ef9462a16e76c57eb5e25beff1f59877bb1"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: backend/core/file_change_classifier.py: backend/core/file_change_classifier.py changed 8 times in last 90 days, max cyclomatic complexity 26 in file_change_classifier.parse_bash_delete_targets at line 122. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-16..2026-09-14, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-16 10:48:17 \u002B08:00\u0027 --until=\u00272026-09-14 10:48:17 \u002B08:00\u0027 --full-history --no-merges -- backend/core/file_change_classifier.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":"backend/core/file_change_classifier.py"},"region":{"startLine":122}}}],"partialFingerprints":{"codehealthFindingId/v1":"9c97739cb3c6519db576ac8637cca7f3050004e465c216216c2a839e360f9146"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: backend/routers/system.py: backend/routers/system.py changed 12 times in last 90 days, max cyclomatic complexity 17 in system._probe_ada_details at line 751. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-16..2026-09-14, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-16 10:48:17 \u002B08:00\u0027 --until=\u00272026-09-14 10:48:17 \u002B08:00\u0027 --full-history --no-merges -- backend/routers/system.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":"backend/routers/system.py"},"region":{"startLine":751}}}],"partialFingerprints":{"codehealthFindingId/v1":"d3cfabcae17743f01e64db682a947ce610f3f28b145323cdb0ab43fb8db93ffd"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: desktop/src/components/layout/ToDoOverlay.tsx: desktop/src/components/layout/ToDoOverlay.tsx changed 13 times in last 90 days, max cyclomatic complexity 15 in TodoForm at line 993. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-16..2026-09-14, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-16 10:48:17 \u002B08:00\u0027 --until=\u00272026-09-14 10:48:17 \u002B08:00\u0027 --full-history --no-merges -- desktop/src/components/layout/ToDoOverlay.tsx\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":"desktop/src/components/layout/ToDoOverlay.tsx"},"region":{"startLine":993}}}],"partialFingerprints":{"codehealthFindingId/v1":"5dfee3364d792a5420de87572f2ef32cb722435591895f567905a98822924e86"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: backend/core/community_data.py: backend/core/community_data.py changed 9 times in last 90 days, max cyclomatic complexity 21 in community_data.parse_hot_topics at line 732. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-16..2026-09-14, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-16 10:48:17 \u002B08:00\u0027 --until=\u00272026-09-14 10:48:17 \u002B08:00\u0027 --full-history --no-merges -- backend/core/community_data.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":"backend/core/community_data.py"},"region":{"startLine":732}}}],"partialFingerprints":{"codehealthFindingId/v1":"ca6284095cbea2ad3fcdadbb1d2c621157ca4546ace4d3b557caf01519b45eb3"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: backend/core/evolution/governance_router.py: backend/core/evolution/governance_router.py changed 12 times in last 90 days, max cyclomatic complexity 15 in governance_router.classify_new_corrections at line 167. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-16..2026-09-14, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-16 10:48:17 \u002B08:00\u0027 --until=\u00272026-09-14 10:48:17 \u002B08:00\u0027 --full-history --no-merges -- backend/core/evolution/governance_router.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":"backend/core/evolution/governance_router.py"},"region":{"startLine":167}}}],"partialFingerprints":{"codehealthFindingId/v1":"160d16232c8f944fc840f8ff4b60acbf2f4f7ff6ba520674f2ca78eb4f8fbe99"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: backend/jobs/scheduler.py: backend/jobs/scheduler.py changed 4 times in last 90 days, max cyclomatic complexity 44 in scheduler.run_scheduler at line 472. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-16..2026-09-14, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-16 10:48:17 \u002B08:00\u0027 --until=\u00272026-09-14 10:48:17 \u002B08:00\u0027 --full-history --no-merges -- backend/jobs/scheduler.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":"backend/jobs/scheduler.py"},"region":{"startLine":472}}}],"partialFingerprints":{"codehealthFindingId/v1":"aaed1ee5f7108665a16475edc809ca44907449975ebd3d5cd7a3ea5bf316f5be"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: desktop/src/components/layout/PollinateOverlay.tsx: desktop/src/components/layout/PollinateOverlay.tsx changed 6 times in last 90 days, max cyclomatic complexity 29 in AssetDrawer at line 494. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-16..2026-09-14, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-16 10:48:17 \u002B08:00\u0027 --until=\u00272026-09-14 10:48:17 \u002B08:00\u0027 --full-history --no-merges -- desktop/src/components/layout/PollinateOverlay.tsx\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":"desktop/src/components/layout/PollinateOverlay.tsx"},"region":{"startLine":494}}}],"partialFingerprints":{"codehealthFindingId/v1":"ad77bebdc1f8649580d4b7d0d8845b09c04ed8b27e27f6388c7e80215a2d1c2c"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: backend/jobs/handlers/swarmai_monthly_report.py: backend/jobs/handlers/swarmai_monthly_report.py changed 3 times in last 90 days, max cyclomatic complexity 56 in swarmai_monthly_report._generate_monthly_report at line 589. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-16..2026-09-14, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-16 10:48:17 \u002B08:00\u0027 --until=\u00272026-09-14 10:48:17 \u002B08:00\u0027 --full-history --no-merges -- backend/jobs/handlers/swarmai_monthly_report.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":"backend/jobs/handlers/swarmai_monthly_report.py"},"region":{"startLine":589}}}],"partialFingerprints":{"codehealthFindingId/v1":"c1ad270bb3c32afd5e3670fee3e2df697f522cd6665099d7c46fc10958ea0421"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: backend/core/summarization.py: backend/core/summarization.py changed 5 times in last 90 days, max cyclomatic complexity 32 in SummarizationPipeline._extract_files_modified at line 422. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-16..2026-09-14, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-16 10:48:17 \u002B08:00\u0027 --until=\u00272026-09-14 10:48:17 \u002B08:00\u0027 --full-history --no-merges -- backend/core/summarization.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":"backend/core/summarization.py"},"region":{"startLine":422}}}],"partialFingerprints":{"codehealthFindingId/v1":"e3e36495f851d20e22aeed2dc5e992dfc6077940c7720c882771eccfdae0fd13"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: backend/hooks/improvement_writeback_hook.py: backend/hooks/improvement_writeback_hook.py changed 8 times in last 90 days, max cyclomatic complexity 20 in ImprovementWritebackHook._detect_project at line 151. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-16..2026-09-14, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-16 10:48:17 \u002B08:00\u0027 --until=\u00272026-09-14 10:48:17 \u002B08:00\u0027 --full-history --no-merges -- backend/hooks/improvement_writeback_hook.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":"backend/hooks/improvement_writeback_hook.py"},"region":{"startLine":151}}}],"partialFingerprints":{"codehealthFindingId/v1":"5451acde2e5b7b09faf9ea46f0db88b1aad7a94841fb9f2f7cc447a42e7ef96e"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: desktop/src/pages/chat/components/MergedToolBlock.tsx: desktop/src/pages/chat/components/MergedToolBlock.tsx changed 5 times in last 90 days, max cyclomatic complexity 32 in MergedToolBlock at line 122. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-16..2026-09-14, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-16 10:48:17 \u002B08:00\u0027 --until=\u00272026-09-14 10:48:17 \u002B08:00\u0027 --full-history --no-merges -- desktop/src/pages/chat/components/MergedToolBlock.tsx\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":"desktop/src/pages/chat/components/MergedToolBlock.tsx"},"region":{"startLine":122}}}],"partialFingerprints":{"codehealthFindingId/v1":"b0588c371e52d574f92b3d756391a662a556957aad5abe352029c3ddc33c3987"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: backend/core/context_injector.py: backend/core/context_injector.py changed 6 times in last 90 days, max cyclomatic complexity 26 in context_injector._extract_key_tool_results at line 654. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-16..2026-09-14, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-16 10:48:17 \u002B08:00\u0027 --until=\u00272026-09-14 10:48:17 \u002B08:00\u0027 --full-history --no-merges -- backend/core/context_injector.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":"backend/core/context_injector.py"},"region":{"startLine":654}}}],"partialFingerprints":{"codehealthFindingId/v1":"a4607b33267f85e326d96feb66c79c32bf868dd5c1a600fe7096c8d05b4f071c"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: backend/jobs/handlers/ddd_self_audit.py: backend/jobs/handlers/ddd_self_audit.py changed 7 times in last 90 days, max cyclomatic complexity 22 in ddd_self_audit.run_ddd_self_audit at line 221. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-16..2026-09-14, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-16 10:48:17 \u002B08:00\u0027 --until=\u00272026-09-14 10:48:17 \u002B08:00\u0027 --full-history --no-merges -- backend/jobs/handlers/ddd_self_audit.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":"backend/jobs/handlers/ddd_self_audit.py"},"region":{"startLine":221}}}],"partialFingerprints":{"codehealthFindingId/v1":"8cf4a40a2ca021b78ec0b17f279da6be103799be24a353b8e05fe8c2b3643e8b"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: backend/scripts/pipeline_analytics.py: backend/scripts/pipeline_analytics.py changed 7 times in last 90 days, max cyclomatic complexity 22 in pipeline_analytics._load_all_metrics at line 64. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-16..2026-09-14, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-16 10:48:17 \u002B08:00\u0027 --until=\u00272026-09-14 10:48:17 \u002B08:00\u0027 --full-history --no-merges -- backend/scripts/pipeline_analytics.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":"backend/scripts/pipeline_analytics.py"},"region":{"startLine":64}}}],"partialFingerprints":{"codehealthFindingId/v1":"0fcda560e27ed97c7522b10fe5691b081155825a67cebec8c7c467e84a58bba6"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: backend/core/library_mounts.py: backend/core/library_mounts.py changed 8 times in last 90 days, max cyclomatic complexity 19 in library_mounts.index_docs_mount at line 579. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-16..2026-09-14, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-16 10:48:17 \u002B08:00\u0027 --until=\u00272026-09-14 10:48:17 \u002B08:00\u0027 --full-history --no-merges -- backend/core/library_mounts.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":"backend/core/library_mounts.py"},"region":{"startLine":579}}}],"partialFingerprints":{"codehealthFindingId/v1":"05deefdd933de340ceefeb21b980c9f14bfcf3d93a6155398bc67bb64721cb29"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: backend/scripts/locked_write.py: backend/scripts/locked_write.py changed 6 times in last 90 days, max cyclomatic complexity 25 in locked_write.locked_read_modify_write at line 515. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-16..2026-09-14, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-16 10:48:17 \u002B08:00\u0027 --until=\u00272026-09-14 10:48:17 \u002B08:00\u0027 --full-history --no-merges -- backend/scripts/locked_write.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":"backend/scripts/locked_write.py"},"region":{"startLine":515}}}],"partialFingerprints":{"codehealthFindingId/v1":"0b7fbd829d0e0a6e5b8d473d0c74c7b3182f0ddbe72f1f1db2bf8d46d02ed61b"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: backend/routers/settings.py: backend/routers/settings.py changed 6 times in last 90 days, max cyclomatic complexity 25 in settings.update_app_configuration at line 263. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-16..2026-09-14, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-16 10:48:17 \u002B08:00\u0027 --until=\u00272026-09-14 10:48:17 \u002B08:00\u0027 --full-history --no-merges -- backend/routers/settings.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":"backend/routers/settings.py"},"region":{"startLine":263}}}],"partialFingerprints":{"codehealthFindingId/v1":"0dffac401398132b5d3b90d947cce3930c730f2e00c6ccfd6f33d4dafd516163"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: backend/core/persist_routing.py: backend/core/persist_routing.py changed 5 times in last 90 days, max cyclomatic complexity 29 in persist_routing.classify_content at line 248. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-16..2026-09-14, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-16 10:48:17 \u002B08:00\u0027 --until=\u00272026-09-14 10:48:17 \u002B08:00\u0027 --full-history --no-merges -- backend/core/persist_routing.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":"backend/core/persist_routing.py"},"region":{"startLine":248}}}],"partialFingerprints":{"codehealthFindingId/v1":"e8d54abd6ffbb5ac1564b30dec465c29726600d02e9e72c5fc19f96af68b1115"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: desktop/src/services/system.ts: desktop/src/services/system.ts changed 9 times in last 90 days, max cyclomatic complexity 16 in restoreBackup at line 408. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-16..2026-09-14, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-16 10:48:17 \u002B08:00\u0027 --until=\u00272026-09-14 10:48:17 \u002B08:00\u0027 --full-history --no-merges -- desktop/src/services/system.ts\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":"desktop/src/services/system.ts"},"region":{"startLine":408}}}],"partialFingerprints":{"codehealthFindingId/v1":"0bc68bc3c752acbf241c9d6ec7ddfeb49bc9964a8324902bcd6d07ba42a35270"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: desktop/src/components/layout/PipelineOverlay.tsx: desktop/src/components/layout/PipelineOverlay.tsx changed 8 times in last 90 days, max cyclomatic complexity 18 in PipelineContent at line 89. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-16..2026-09-14, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-16 10:48:17 \u002B08:00\u0027 --until=\u00272026-09-14 10:48:17 \u002B08:00\u0027 --full-history --no-merges -- desktop/src/components/layout/PipelineOverlay.tsx\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":"desktop/src/components/layout/PipelineOverlay.tsx"},"region":{"startLine":89}}}],"partialFingerprints":{"codehealthFindingId/v1":"9256d2f5b74347de12ed0f22f007e170f704ab72ad37265a5f4b90e504da8dd0"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: desktop/src/components/layout/CapabilitiesOverlay.tsx: desktop/src/components/layout/CapabilitiesOverlay.tsx changed 6 times in last 90 days, max cyclomatic complexity 23 in CapabilitiesContent at line 173. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-16..2026-09-14, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-16 10:48:17 \u002B08:00\u0027 --until=\u00272026-09-14 10:48:17 \u002B08:00\u0027 --full-history --no-merges -- desktop/src/components/layout/CapabilitiesOverlay.tsx\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":"desktop/src/components/layout/CapabilitiesOverlay.tsx"},"region":{"startLine":173}}}],"partialFingerprints":{"codehealthFindingId/v1":"3bb74a013d5678d4831af43593f84db2347811817a8f8a8b3f8d91f25c004bd3"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: backend/core/session_utils.py: backend/core/session_utils.py changed 9 times in last 90 days, max cyclomatic complexity 15 in session_utils.classify_failure at line 57. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-16..2026-09-14, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-16 10:48:17 \u002B08:00\u0027 --until=\u00272026-09-14 10:48:17 \u002B08:00\u0027 --full-history --no-merges -- backend/core/session_utils.py\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/core/session_utils.py"},"region":{"startLine":57}}}],"partialFingerprints":{"codehealthFindingId/v1":"12c9147b96d5bf16ec23eb598123799913bab2728e706ead53be8deee4da83de"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: backend/skills/s_autonomous-pipeline/scripts/confidence_score.py: backend/skills/s_autonomous-pipeline/scripts/confidence_score.py changed 2 times in last 90 days, max cyclomatic complexity 66 in confidence_score.calculate_score at line 71. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-16..2026-09-14, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-16 10:48:17 \u002B08:00\u0027 --until=\u00272026-09-14 10:48:17 \u002B08:00\u0027 --full-history --no-merges -- backend/skills/s_autonomous-pipeline/scripts/confidence_score.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":"backend/skills/s_autonomous-pipeline/scripts/confidence_score.py"},"region":{"startLine":71}}}],"partialFingerprints":{"codehealthFindingId/v1":"f9c9060d0b4ab60f77b617d524f552ccf6b29822af3525e159f082daa42d1af4"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: backend/routers/pollinate.py: backend/routers/pollinate.py changed 6 times in last 90 days, max cyclomatic complexity 21 in pollinate._walk_assets at line 327. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-16..2026-09-14, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-16 10:48:17 \u002B08:00\u0027 --until=\u00272026-09-14 10:48:17 \u002B08:00\u0027 --full-history --no-merges -- backend/routers/pollinate.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":"backend/routers/pollinate.py"},"region":{"startLine":327}}}],"partialFingerprints":{"codehealthFindingId/v1":"7b246572c5a09594397d37dcad650e9267f83be002b8b67cc2f11a7ee636e40f"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: desktop/src/components/workspace-explorer/VirtualizedTree.tsx: desktop/src/components/workspace-explorer/VirtualizedTree.tsx changed 3 times in last 90 days, max cyclomatic complexity 42 in flattenTree at line 255. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-16..2026-09-14, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-16 10:48:17 \u002B08:00\u0027 --until=\u00272026-09-14 10:48:17 \u002B08:00\u0027 --full-history --no-merges -- desktop/src/components/workspace-explorer/VirtualizedTree.tsx\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":"desktop/src/components/workspace-explorer/VirtualizedTree.tsx"},"region":{"startLine":255}}}],"partialFingerprints":{"codehealthFindingId/v1":"b8f3aa3b80b5914df7554a9cc13eca64933fe88867e0aca9dd0516a567dbe05a"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: desktop/src/utils/uiCommands.ts: desktop/src/utils/uiCommands.ts changed 7 times in last 90 days, max cyclomatic complexity 18 in dispatchUiCommand at line 99. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-16..2026-09-14, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-16 10:48:17 \u002B08:00\u0027 --until=\u00272026-09-14 10:48:17 \u002B08:00\u0027 --full-history --no-merges -- desktop/src/utils/uiCommands.ts\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":"desktop/src/utils/uiCommands.ts"},"region":{"startLine":99}}}],"partialFingerprints":{"codehealthFindingId/v1":"920c6b3cc69593d0ca6f5abc74af352778c63f10ab8ff9f3b8293ed476cfa6f7"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: backend/core/plugin_manager.py: backend/core/plugin_manager.py changed 4 times in last 90 days, max cyclomatic complexity 30 in PluginManager.install_plugin at line 696. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-16..2026-09-14, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-16 10:48:17 \u002B08:00\u0027 --until=\u00272026-09-14 10:48:17 \u002B08:00\u0027 --full-history --no-merges -- backend/core/plugin_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":"backend/core/plugin_manager.py"},"region":{"startLine":696}}}],"partialFingerprints":{"codehealthFindingId/v1":"89dabebe6d60114dee0e8ac561f42d3660d0675b4c1e8135fc1585da5d17bca6"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: backend/core/code_intel/clustering.py: backend/core/code_intel/clustering.py changed 4 times in last 90 days, max cyclomatic complexity 30 in clustering.compute_graph_clusters at line 75. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-16..2026-09-14, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-16 10:48:17 \u002B08:00\u0027 --until=\u00272026-09-14 10:48:17 \u002B08:00\u0027 --full-history --no-merges -- backend/core/code_intel/clustering.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":"backend/core/code_intel/clustering.py"},"region":{"startLine":75}}}],"partialFingerprints":{"codehealthFindingId/v1":"87605708ca5ce9358d2a8748c0cd9989a29fe78ebba35e36c1aceafbd4486987"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: backend/core/session_health_probe.py: backend/core/session_health_probe.py changed 5 times in last 90 days, max cyclomatic complexity 22 in session_health_probe.session_health_probe at line 190. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-16..2026-09-14, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-16 10:48:17 \u002B08:00\u0027 --until=\u00272026-09-14 10:48:17 \u002B08:00\u0027 --full-history --no-merges -- backend/core/session_health_probe.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":"backend/core/session_health_probe.py"},"region":{"startLine":190}}}],"partialFingerprints":{"codehealthFindingId/v1":"3d40ccd1950486fe4d20b81aa40c6a0e0dccd22d8e16878a44b2121499b21ce5"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: backend/skills/s_pollinate/scripts/pollinate_validator.py: backend/skills/s_pollinate/scripts/pollinate_validator.py changed 3 times in last 90 days, max cyclomatic complexity 36 in pollinate_validator.validate_delivery at line 182. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-16..2026-09-14, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-16 10:48:17 \u002B08:00\u0027 --until=\u00272026-09-14 10:48:17 \u002B08:00\u0027 --full-history --no-merges -- backend/skills/s_pollinate/scripts/pollinate_validator.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":"backend/skills/s_pollinate/scripts/pollinate_validator.py"},"region":{"startLine":182}}}],"partialFingerprints":{"codehealthFindingId/v1":"e3bb749d20aad4f07cd73026a7c9973da604f4e10266a08c289b643b6559fae4"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: backend/scripts/context_recall_cli.py: backend/scripts/context_recall_cli.py changed 6 times in last 90 days, max cyclomatic complexity 18 in context_recall_cli.main at line 52. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-16..2026-09-14, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-16 10:48:17 \u002B08:00\u0027 --until=\u00272026-09-14 10:48:17 \u002B08:00\u0027 --full-history --no-merges -- backend/scripts/context_recall_cli.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":"backend/scripts/context_recall_cli.py"},"region":{"startLine":52}}}],"partialFingerprints":{"codehealthFindingId/v1":"ef1cb90683003c374a2ef644b8039f2de847560df0db6c31f222f8bb44d295be"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: backend/jobs/handlers/ddd_weekly_report.py: backend/jobs/handlers/ddd_weekly_report.py changed 3 times in last 90 days, max cyclomatic complexity 34 in ddd_weekly_report._generate_report at line 207. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-16..2026-09-14, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-16 10:48:17 \u002B08:00\u0027 --until=\u00272026-09-14 10:48:17 \u002B08:00\u0027 --full-history --no-merges -- backend/jobs/handlers/ddd_weekly_report.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":"backend/jobs/handlers/ddd_weekly_report.py"},"region":{"startLine":207}}}],"partialFingerprints":{"codehealthFindingId/v1":"99e9d312ebe228bcbfcf186265d57e404696f0c6d4161484576cf402554708ed"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: backend/core/skill_manager.py: backend/core/skill_manager.py changed 5 times in last 90 days, max cyclomatic complexity 20 in skill_manager.parse_skill_md at line 215. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-16..2026-09-14, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-16 10:48:17 \u002B08:00\u0027 --until=\u00272026-09-14 10:48:17 \u002B08:00\u0027 --full-history --no-merges -- backend/core/skill_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":"backend/core/skill_manager.py"},"region":{"startLine":215}}}],"partialFingerprints":{"codehealthFindingId/v1":"07f44b4632bd30485ce5d8137a58a51e92d5bb96985e5ef98cd01a732a8bf3cb"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: desktop/src/components/settings/AuthConfigPanel.tsx: desktop/src/components/settings/AuthConfigPanel.tsx changed 4 times in last 90 days, max cyclomatic complexity 25 in AuthConfigPanel at line 29. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-16..2026-09-14, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-16 10:48:17 \u002B08:00\u0027 --until=\u00272026-09-14 10:48:17 \u002B08:00\u0027 --full-history --no-merges -- desktop/src/components/settings/AuthConfigPanel.tsx\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":"desktop/src/components/settings/AuthConfigPanel.tsx"},"region":{"startLine":29}}}],"partialFingerprints":{"codehealthFindingId/v1":"0ea0a96ca09aa4d8cea0e9b7e6418af86f7345d2f0b7002aa4e30a1c0c5f30bc"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: backend/jobs/self_tune.py: backend/jobs/self_tune.py changed 6 times in last 90 days, max cyclomatic complexity 16 in self_tune.track_signal_usage at line 176. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-16..2026-09-14, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-16 10:48:17 \u002B08:00\u0027 --until=\u00272026-09-14 10:48:17 \u002B08:00\u0027 --full-history --no-merges -- backend/jobs/self_tune.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":"backend/jobs/self_tune.py"},"region":{"startLine":176}}}],"partialFingerprints":{"codehealthFindingId/v1":"9ea26028983ebc887d410ac18d1aff10f06dfc84ba582f8ec05dfe4782957702"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: backend/core/attention_authority.py: backend/core/attention_authority.py changed 6 times in last 90 days, max cyclomatic complexity 16 in attention_authority._collect_governance at line 195. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-16..2026-09-14, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-16 10:48:17 \u002B08:00\u0027 --until=\u00272026-09-14 10:48:17 \u002B08:00\u0027 --full-history --no-merges -- backend/core/attention_authority.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":"backend/core/attention_authority.py"},"region":{"startLine":195}}}],"partialFingerprints":{"codehealthFindingId/v1":"67ac01480ce9bdb5c1f9f69df4e8a5b7e40e5b5c6ec931e8b2fdeb8ebfa587c1"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: backend/channels/adapters/slack.py: backend/channels/adapters/slack.py changed 4 times in last 90 days, max cyclomatic complexity 23 in SlackChannelAdapter._text_to_blocks at line 1923. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-16..2026-09-14, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-16 10:48:17 \u002B08:00\u0027 --until=\u00272026-09-14 10:48:17 \u002B08:00\u0027 --full-history --no-merges -- backend/channels/adapters/slack.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":"backend/channels/adapters/slack.py"},"region":{"startLine":1923}}}],"partialFingerprints":{"codehealthFindingId/v1":"dfc480973c3394f26b2deeeffc27a5dde891ce604f3dbe46d6b94779d2de0e91"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: backend/core/daily_activity_writer.py: backend/core/daily_activity_writer.py changed 3 times in last 90 days, max cyclomatic complexity 30 in daily_activity_writer._format_session_entry at line 134. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-16..2026-09-14, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-16 10:48:17 \u002B08:00\u0027 --until=\u00272026-09-14 10:48:17 \u002B08:00\u0027 --full-history --no-merges -- backend/core/daily_activity_writer.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":"backend/core/daily_activity_writer.py"},"region":{"startLine":134}}}],"partialFingerprints":{"codehealthFindingId/v1":"00c7efb453e0e7e5e054b03e342ec1f061be6094c09a2b29404f25ba027f6378"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: backend/core/needs_human_review.py: backend/core/needs_human_review.py changed 5 times in last 90 days, max cyclomatic complexity 17 in needs_human_review.needs_human_review_batch at line 369. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-16..2026-09-14, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-16 10:48:17 \u002B08:00\u0027 --until=\u00272026-09-14 10:48:17 \u002B08:00\u0027 --full-history --no-merges -- backend/core/needs_human_review.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":"backend/core/needs_human_review.py"},"region":{"startLine":369}}}],"partialFingerprints":{"codehealthFindingId/v1":"a87e2f4b694d5df659f1e3eaaf60a7e54d4f3a4fccee90d80c6c57707a1c3551"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: desktop/src/services/pipelines.ts: desktop/src/services/pipelines.ts changed 5 times in last 90 days, max cyclomatic complexity 17 in fetchRunDetail at line 256. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-16..2026-09-14, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-16 10:48:17 \u002B08:00\u0027 --until=\u00272026-09-14 10:48:17 \u002B08:00\u0027 --full-history --no-merges -- desktop/src/services/pipelines.ts\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":"desktop/src/services/pipelines.ts"},"region":{"startLine":256}}}],"partialFingerprints":{"codehealthFindingId/v1":"164bc8dfdd5a364a463ca6cc63e7f4cbae6387ec86ef8caddd29164c5bc22348"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: backend/core/evolution/escalation_ladder.py: backend/core/evolution/escalation_ladder.py changed 5 times in last 90 days, max cyclomatic complexity 17 in escalation_ladder.decide_escalation at line 75. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-16..2026-09-14, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-16 10:48:17 \u002B08:00\u0027 --until=\u00272026-09-14 10:48:17 \u002B08:00\u0027 --full-history --no-merges -- backend/core/evolution/escalation_ladder.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":"backend/core/evolution/escalation_ladder.py"},"region":{"startLine":75}}}],"partialFingerprints":{"codehealthFindingId/v1":"0f1b6f6daa8f1900d5d42d24c5fce3123ac380c167d1100b3c93e5a1a6650039"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: backend/core/engine_metrics.py: backend/core/engine_metrics.py changed 3 times in last 90 days, max cyclomatic complexity 27 in engine_metrics.collect_ddd_change_suggestions at line 154. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-16..2026-09-14, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-16 10:48:17 \u002B08:00\u0027 --until=\u00272026-09-14 10:48:17 \u002B08:00\u0027 --full-history --no-merges -- backend/core/engine_metrics.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":"backend/core/engine_metrics.py"},"region":{"startLine":154}}}],"partialFingerprints":{"codehealthFindingId/v1":"a86e6125ad5b87f20b7eae9c345fe8dac3e743093af6d9d6597c0c7aea44f37a"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: backend/core/backup_manager.py: backend/core/backup_manager.py changed 5 times in last 90 days, max cyclomatic complexity 16 in BackupManager._restore_impl at line 471. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-16..2026-09-14, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-16 10:48:17 \u002B08:00\u0027 --until=\u00272026-09-14 10:48:17 \u002B08:00\u0027 --full-history --no-merges -- backend/core/backup_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":"backend/core/backup_manager.py"},"region":{"startLine":471}}}],"partialFingerprints":{"codehealthFindingId/v1":"556c7a75410c48badaf43461dbd82bf6827d577295b52390338f110ca716f724"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: backend/jobs/handlers/session_health_probe.py: backend/jobs/handlers/session_health_probe.py changed 5 times in last 90 days, max cyclomatic complexity 16 in session_health_probe.run_session_health_probe at line 172. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-16..2026-09-14, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-16 10:48:17 \u002B08:00\u0027 --until=\u00272026-09-14 10:48:17 \u002B08:00\u0027 --full-history --no-merges -- backend/jobs/handlers/session_health_probe.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":"backend/jobs/handlers/session_health_probe.py"},"region":{"startLine":172}}}],"partialFingerprints":{"codehealthFindingId/v1":"234e770960d9de208a4f0efd45175e12672cc2afb7aa8eb7e4ad8d2400d5657b"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: backend/core/code_intel_feed.py: backend/core/code_intel_feed.py changed 3 times in last 90 days, max cyclomatic complexity 23 in code_intel_feed.detect_tech_drift at line 59. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-16..2026-09-14, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-16 10:48:17 \u002B08:00\u0027 --until=\u00272026-09-14 10:48:17 \u002B08:00\u0027 --full-history --no-merges -- backend/core/code_intel_feed.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":"backend/core/code_intel_feed.py"},"region":{"startLine":59}}}],"partialFingerprints":{"codehealthFindingId/v1":"a854b819044d4fd83436a222940f49386c95d81c4b690ecdba27009d6652717d"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: backend/skills/s_pollinate/scripts/format_recommend.py: backend/skills/s_pollinate/scripts/format_recommend.py changed 4 times in last 90 days, max cyclomatic complexity 17 in format_recommend.recommend 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-06-16..2026-09-14, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-16 10:48:17 \u002B08:00\u0027 --until=\u00272026-09-14 10:48:17 \u002B08:00\u0027 --full-history --no-merges -- backend/skills/s_pollinate/scripts/format_recommend.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":"backend/skills/s_pollinate/scripts/format_recommend.py"},"region":{"startLine":158}}}],"partialFingerprints":{"codehealthFindingId/v1":"14b68e441134c96f8b892dfa1da401fd5d293af69b83a059b45dc0ef341f7faa"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: backend/core/code_intel/freshness.py: backend/core/code_intel/freshness.py changed 4 times in last 90 days, max cyclomatic complexity 17 in freshness.detect_spec_details_staleness at line 224. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-16..2026-09-14, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-16 10:48:17 \u002B08:00\u0027 --until=\u00272026-09-14 10:48:17 \u002B08:00\u0027 --full-history --no-merges -- backend/core/code_intel/freshness.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":"backend/core/code_intel/freshness.py"},"region":{"startLine":224}}}],"partialFingerprints":{"codehealthFindingId/v1":"4373b23ee622624e3e0f20ca892f17f8d2ed0f0962decd60a32503b1caa33b98"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: backend/core/code_intel/code_intel_hook.py: backend/core/code_intel/code_intel_hook.py changed 3 times in last 90 days, max cyclomatic complexity 22 in code_intel_hook._build_context 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-06-16..2026-09-14, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-16 10:48:17 \u002B08:00\u0027 --until=\u00272026-09-14 10:48:17 \u002B08:00\u0027 --full-history --no-merges -- backend/core/code_intel/code_intel_hook.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":"backend/core/code_intel/code_intel_hook.py"},"region":{"startLine":235}}}],"partialFingerprints":{"codehealthFindingId/v1":"27d3e4bc98da1afa0c5879fde2367e6fa0fc5bd40de79153d7518f6eb7083eb2"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: backend/scripts/backfill_cjk_escapes.py: backend/scripts/backfill_cjk_escapes.py changed 2 times in last 90 days, max cyclomatic complexity 32 in backfill_cjk_escapes.backfill at line 576. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-16..2026-09-14, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-16 10:48:17 \u002B08:00\u0027 --until=\u00272026-09-14 10:48:17 \u002B08:00\u0027 --full-history --no-merges -- backend/scripts/backfill_cjk_escapes.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":"backend/scripts/backfill_cjk_escapes.py"},"region":{"startLine":576}}}],"partialFingerprints":{"codehealthFindingId/v1":"34bb40bca65c6c4a8272d6ae714a39155457b435409cb54d0ac18a324101d88b"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: backend/core/compaction_guard.py: backend/core/compaction_guard.py changed 4 times in last 90 days, max cyclomatic complexity 16 in CompactionGuard.check at line 609. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-16..2026-09-14, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-16 10:48:17 \u002B08:00\u0027 --until=\u00272026-09-14 10:48:17 \u002B08:00\u0027 --full-history --no-merges -- backend/core/compaction_guard.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":"backend/core/compaction_guard.py"},"region":{"startLine":609}}}],"partialFingerprints":{"codehealthFindingId/v1":"abe5563067235842c7de352f544ca16c1aec7a23aee3628e29dc2d82debaa2c0"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: desktop/src/services/todos.ts: desktop/src/services/todos.ts changed 4 times in last 90 days, max cyclomatic complexity 16 in toSnakeCase at line 53. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-16..2026-09-14, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-16 10:48:17 \u002B08:00\u0027 --until=\u00272026-09-14 10:48:17 \u002B08:00\u0027 --full-history --no-merges -- desktop/src/services/todos.ts\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":"desktop/src/services/todos.ts"},"region":{"startLine":53}}}],"partialFingerprints":{"codehealthFindingId/v1":"6dffd82ec3fad565c3d69fd30c45f0b51a0c5b24a3a7a07d2de348101cdd6870"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: desktop/src/components/workspace-explorer/TreeNodeRow.tsx: desktop/src/components/workspace-explorer/TreeNodeRow.tsx changed 2 times in last 90 days, max cyclomatic complexity 32 in TreeNodeRow at line 188. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-16..2026-09-14, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-16 10:48:17 \u002B08:00\u0027 --until=\u00272026-09-14 10:48:17 \u002B08:00\u0027 --full-history --no-merges -- desktop/src/components/workspace-explorer/TreeNodeRow.tsx\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":"desktop/src/components/workspace-explorer/TreeNodeRow.tsx"},"region":{"startLine":188}}}],"partialFingerprints":{"codehealthFindingId/v1":"fc47d23eaf085877b68bc34ba5785d208b7b1e3bf5778b8c418024c9e0382c94"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: desktop/src/pages/chat/components/RightSidebar/HistoryView.tsx: desktop/src/pages/chat/components/RightSidebar/HistoryView.tsx changed 4 times in last 90 days, max cyclomatic complexity 16 in HistoryView at line 34. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-16..2026-09-14, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-16 10:48:17 \u002B08:00\u0027 --until=\u00272026-09-14 10:48:17 \u002B08:00\u0027 --full-history --no-merges -- desktop/src/pages/chat/components/RightSidebar/HistoryView.tsx\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":"desktop/src/pages/chat/components/RightSidebar/HistoryView.tsx"},"region":{"startLine":34}}}],"partialFingerprints":{"codehealthFindingId/v1":"dac31bd51ee2b399645e5f39464f8abb9dd9d3d6a358b8dc9278eef0c1b7e5aa"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: desktop/src/components/common/MarkdownRenderer.tsx: desktop/src/components/common/MarkdownRenderer.tsx changed 4 times in last 90 days, max cyclomatic complexity 15 in isWorkspaceFilePath at line 617. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-16..2026-09-14, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-16 10:48:17 \u002B08:00\u0027 --until=\u00272026-09-14 10:48:17 \u002B08:00\u0027 --full-history --no-merges -- desktop/src/components/common/MarkdownRenderer.tsx\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":"desktop/src/components/common/MarkdownRenderer.tsx"},"region":{"startLine":617}}}],"partialFingerprints":{"codehealthFindingId/v1":"872b4b07ea67a9fe47bef32246886c9c6c0e5f81de7f6e45972af21b4ef40913"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: backend/scripts/migrate_skills.py: backend/scripts/migrate_skills.py changed 3 times in last 90 days, max cyclomatic complexity 19 in migrate_skills.generate_manifest 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-06-16..2026-09-14, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-16 10:48:17 \u002B08:00\u0027 --until=\u00272026-09-14 10:48:17 \u002B08:00\u0027 --full-history --no-merges -- backend/scripts/migrate_skills.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":"backend/scripts/migrate_skills.py"},"region":{"startLine":235}}}],"partialFingerprints":{"codehealthFindingId/v1":"196fcb42c2db25a402abd4b00651624d42d6883f7fa258332ccd932c44e442fe"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: backend/core/evolution/closed_loop.py: backend/core/evolution/closed_loop.py changed 3 times in last 90 days, max cyclomatic complexity 19 in closed_loop.audit_recurrence at line 37. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-16..2026-09-14, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-16 10:48:17 \u002B08:00\u0027 --until=\u00272026-09-14 10:48:17 \u002B08:00\u0027 --full-history --no-merges -- backend/core/evolution/closed_loop.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":"backend/core/evolution/closed_loop.py"},"region":{"startLine":37}}}],"partialFingerprints":{"codehealthFindingId/v1":"1283dd9e3ecbdb1f0ef5529228832c31ae2174c254a9339ad29ea03acbed93e6"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: backend/routers/channels.py: backend/routers/channels.py changed 2 times in last 90 days, max cyclomatic complexity 28 in channels.update_channel at line 180. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-16..2026-09-14, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-16 10:48:17 \u002B08:00\u0027 --until=\u00272026-09-14 10:48:17 \u002B08:00\u0027 --full-history --no-merges -- backend/routers/channels.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":"backend/routers/channels.py"},"region":{"startLine":180}}}],"partialFingerprints":{"codehealthFindingId/v1":"413ce5dfabe066fadda27919819cc65010d5e095aacea83ef768e4b7edc1a191"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: backend/hooks/data_point_folding.py: backend/hooks/data_point_folding.py changed 3 times in last 90 days, max cyclomatic complexity 18 in data_point_folding._fold_one_family at line 201. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-16..2026-09-14, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-16 10:48:17 \u002B08:00\u0027 --until=\u00272026-09-14 10:48:17 \u002B08:00\u0027 --full-history --no-merges -- backend/hooks/data_point_folding.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":"backend/hooks/data_point_folding.py"},"region":{"startLine":201}}}],"partialFingerprints":{"codehealthFindingId/v1":"5f941c226385ea3910b4c3e000e5e8c40cd2875a18dd7ac68ecd59ccca92f8b0"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: desktop/src/components/workspace/FilePreviewModal.tsx: desktop/src/components/workspace/FilePreviewModal.tsx changed 3 times in last 90 days, max cyclomatic complexity 18 in renderContent at line 102. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-16..2026-09-14, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-16 10:48:17 \u002B08:00\u0027 --until=\u00272026-09-14 10:48:17 \u002B08:00\u0027 --full-history --no-merges -- desktop/src/components/workspace/FilePreviewModal.tsx\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":"desktop/src/components/workspace/FilePreviewModal.tsx"},"region":{"startLine":102}}}],"partialFingerprints":{"codehealthFindingId/v1":"52c04e4bfd0a39ed4af09c4b59143551d519173aeea6287ed182d2de8db241b6"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: backend/core/code_intel/domain_rules.py: backend/core/code_intel/domain_rules.py changed 3 times in last 90 days, max cyclomatic complexity 18 in domain_rules.compute_domain_rules 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-06-16..2026-09-14, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-16 10:48:17 \u002B08:00\u0027 --until=\u00272026-09-14 10:48:17 \u002B08:00\u0027 --full-history --no-merges -- backend/core/code_intel/domain_rules.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":"backend/core/code_intel/domain_rules.py"},"region":{"startLine":136}}}],"partialFingerprints":{"codehealthFindingId/v1":"e7300a98239a086bca37e61979d3a728d942b14de40477aa42adf4011efbc1de"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: backend/skills/s_context-hygiene/scripts/scan.py: backend/skills/s_context-hygiene/scripts/scan.py changed 3 times in last 90 days, max cyclomatic complexity 17 in scan.main at line 201. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-16..2026-09-14, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-16 10:48:17 \u002B08:00\u0027 --until=\u00272026-09-14 10:48:17 \u002B08:00\u0027 --full-history --no-merges -- backend/skills/s_context-hygiene/scripts/scan.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":"backend/skills/s_context-hygiene/scripts/scan.py"},"region":{"startLine":201}}}],"partialFingerprints":{"codehealthFindingId/v1":"bac1cddff0fd6e438e266bf178e309126aae710fdef101cdcd964f676ee9ed58"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: backend/skills/s_ddd-distribute/scripts/distribute.py: backend/skills/s_ddd-distribute/scripts/distribute.py changed 3 times in last 90 days, max cyclomatic complexity 17 in distribute.main at line 57. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-16..2026-09-14, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-16 10:48:17 \u002B08:00\u0027 --until=\u00272026-09-14 10:48:17 \u002B08:00\u0027 --full-history --no-merges -- backend/skills/s_ddd-distribute/scripts/distribute.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":"backend/skills/s_ddd-distribute/scripts/distribute.py"},"region":{"startLine":57}}}],"partialFingerprints":{"codehealthFindingId/v1":"8858a42291d2ed3bf88b67eef2b843a8976f1a9b2dd83e29fd39bda6cf45e50e"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: backend/jobs/bedrock.py: backend/jobs/bedrock.py changed 3 times in last 90 days, max cyclomatic complexity 17 in bedrock._resolve_credentials at line 62. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-16..2026-09-14, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-16 10:48:17 \u002B08:00\u0027 --until=\u00272026-09-14 10:48:17 \u002B08:00\u0027 --full-history --no-merges -- backend/jobs/bedrock.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":"backend/jobs/bedrock.py"},"region":{"startLine":62}}}],"partialFingerprints":{"codehealthFindingId/v1":"7c31f2c59de3325a4f4c4daf36bf0d2f70cc7461420c89f2000c700a24a02929"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: backend/core/session_registry.py: backend/core/session_registry.py changed 3 times in last 90 days, max cyclomatic complexity 17 in session_registry.kill_all_claude_processes at line 175. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-16..2026-09-14, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-16 10:48:17 \u002B08:00\u0027 --until=\u00272026-09-14 10:48:17 \u002B08:00\u0027 --full-history --no-merges -- backend/core/session_registry.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":"backend/core/session_registry.py"},"region":{"startLine":175}}}],"partialFingerprints":{"codehealthFindingId/v1":"a36b2bee5e38023f55599e6959df2eb73350aed7bad984e0e567c5a3d00157a9"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: backend/core/session_harvest.py: backend/core/session_harvest.py changed 3 times in last 90 days, max cyclomatic complexity 16 in session_harvest._parse_draft at line 104. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-16..2026-09-14, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-16 10:48:17 \u002B08:00\u0027 --until=\u00272026-09-14 10:48:17 \u002B08:00\u0027 --full-history --no-merges -- backend/core/session_harvest.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":"backend/core/session_harvest.py"},"region":{"startLine":104}}}],"partialFingerprints":{"codehealthFindingId/v1":"885e386b700ebaeea4cb1941e6a010e08ce0f48fba693b6aabf94ad4a5d3eb2c"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: desktop/src/components/common/BackendStartupOverlay.tsx: desktop/src/components/common/BackendStartupOverlay.tsx changed 3 times in last 90 days, max cyclomatic complexity 16 in pollHealth at line 438. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-16..2026-09-14, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-16 10:48:17 \u002B08:00\u0027 --until=\u00272026-09-14 10:48:17 \u002B08:00\u0027 --full-history --no-merges -- desktop/src/components/common/BackendStartupOverlay.tsx\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":"desktop/src/components/common/BackendStartupOverlay.tsx"},"region":{"startLine":438}}}],"partialFingerprints":{"codehealthFindingId/v1":"cbde9844553afb7055d554967db48026ffdb15c50c7d396f54e3ed687b1e8984"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: backend/core/ddd_health.py: backend/core/ddd_health.py changed 3 times in last 90 days, max cyclomatic complexity 15 in ddd_health._build_changelog_index at line 159. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-16..2026-09-14, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-16 10:48:17 \u002B08:00\u0027 --until=\u00272026-09-14 10:48:17 \u002B08:00\u0027 --full-history --no-merges -- backend/core/ddd_health.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":"backend/core/ddd_health.py"},"region":{"startLine":159}}}],"partialFingerprints":{"codehealthFindingId/v1":"8ee59a1fe0cd89a86dcf953e67d03036ca21dd57fb681fe8001d41ea437d560e"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: backend/scripts/evolution_escalation_probe.py: backend/scripts/evolution_escalation_probe.py changed 2 times in last 90 days, max cyclomatic complexity 22 in evolution_escalation_probe.main at line 73. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-16..2026-09-14, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-16 10:48:17 \u002B08:00\u0027 --until=\u00272026-09-14 10:48:17 \u002B08:00\u0027 --full-history --no-merges -- backend/scripts/evolution_escalation_probe.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":"backend/scripts/evolution_escalation_probe.py"},"region":{"startLine":73}}}],"partialFingerprints":{"codehealthFindingId/v1":"baba8e3405292491393fd84b3bd10311813f6131e5744cb54b98aebd4809b2f2"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: backend/jobs/model_resolve.py: backend/jobs/model_resolve.py changed 2 times in last 90 days, max cyclomatic complexity 20 in model_resolve.resolve_job_model at line 36. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-16..2026-09-14, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-16 10:48:17 \u002B08:00\u0027 --until=\u00272026-09-14 10:48:17 \u002B08:00\u0027 --full-history --no-merges -- backend/jobs/model_resolve.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":"backend/jobs/model_resolve.py"},"region":{"startLine":36}}}],"partialFingerprints":{"codehealthFindingId/v1":"787185abfc8c1960c22481d3d8c9a4bca3f12cb23feeee9b18eb0573182dbaa7"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: backend/templates/ddd-skills/s_ddd-persist/scripts/locked_write.py: backend/templates/ddd-skills/s_ddd-persist/scripts/locked_write.py changed 2 times in last 90 days, max cyclomatic complexity 20 in locked_write.locked_read_modify_write at line 515. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-16..2026-09-14, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-16 10:48:17 \u002B08:00\u0027 --until=\u00272026-09-14 10:48:17 \u002B08:00\u0027 --full-history --no-merges -- backend/templates/ddd-skills/s_ddd-persist/scripts/locked_write.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":"backend/templates/ddd-skills/s_ddd-persist/scripts/locked_write.py"},"region":{"startLine":515}}}],"partialFingerprints":{"codehealthFindingId/v1":"c3b5ab3efdbec2799b9b51e64d480606a0f5d65d5006ffa39cf04ad59e747217"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: backend/core/canvas_surface.py: backend/core/canvas_surface.py changed 2 times in last 90 days, max cyclomatic complexity 20 in canvas_surface.is_canvas_surfaceable at line 90. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-16..2026-09-14, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-16 10:48:17 \u002B08:00\u0027 --until=\u00272026-09-14 10:48:17 \u002B08:00\u0027 --full-history --no-merges -- backend/core/canvas_surface.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":"backend/core/canvas_surface.py"},"region":{"startLine":90}}}],"partialFingerprints":{"codehealthFindingId/v1":"01f12b97ebcf6d81c4c61a2ca8da3c0057170131f026f2f6c189ceed8046ddff"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: backend/skills/s_autonomous-pipeline/scripts/pipeline_pr.py: backend/skills/s_autonomous-pipeline/scripts/pipeline_pr.py changed 2 times in last 90 days, max cyclomatic complexity 19 in pipeline_pr.create_pr at line 240. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-16..2026-09-14, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-16 10:48:17 \u002B08:00\u0027 --until=\u00272026-09-14 10:48:17 \u002B08:00\u0027 --full-history --no-merges -- backend/skills/s_autonomous-pipeline/scripts/pipeline_pr.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":"backend/skills/s_autonomous-pipeline/scripts/pipeline_pr.py"},"region":{"startLine":240}}}],"partialFingerprints":{"codehealthFindingId/v1":"ab326f157f2c6c2717f47aa41f4aa0fa634f0ef697b818baeed17334aaba40f4"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: backend/skills/s_pollinate/scripts/font_link_backfill.py: backend/skills/s_pollinate/scripts/font_link_backfill.py changed 2 times in last 90 days, max cyclomatic complexity 19 in font_link_backfill.main at line 94. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-16..2026-09-14, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-16 10:48:17 \u002B08:00\u0027 --until=\u00272026-09-14 10:48:17 \u002B08:00\u0027 --full-history --no-merges -- backend/skills/s_pollinate/scripts/font_link_backfill.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":"backend/skills/s_pollinate/scripts/font_link_backfill.py"},"region":{"startLine":94}}}],"partialFingerprints":{"codehealthFindingId/v1":"cf8fe0e0223ce9185fceae559610f68f3bcc5ae8e33693f26222f4f665efac7b"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: backend/scripts/completion_gate.py: backend/scripts/completion_gate.py changed 2 times in last 90 days, max cyclomatic complexity 18 in completion_gate.completion_surface_verdict at line 59. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-16..2026-09-14, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-16 10:48:17 \u002B08:00\u0027 --until=\u00272026-09-14 10:48:17 \u002B08:00\u0027 --full-history --no-merges -- backend/scripts/completion_gate.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":"backend/scripts/completion_gate.py"},"region":{"startLine":59}}}],"partialFingerprints":{"codehealthFindingId/v1":"22705f721b68bd98cc61ab9bf98855ed35179fe2cd93587b211da881a5e2a04f"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: backend/core/proposal_feedback.py: backend/core/proposal_feedback.py changed 2 times in last 90 days, max cyclomatic complexity 17 in ProposalFeedbackTracker.compute_channel_stats 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-06-16..2026-09-14, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-16 10:48:17 \u002B08:00\u0027 --until=\u00272026-09-14 10:48:17 \u002B08:00\u0027 --full-history --no-merges -- backend/core/proposal_feedback.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":"backend/core/proposal_feedback.py"},"region":{"startLine":158}}}],"partialFingerprints":{"codehealthFindingId/v1":"d3b2b5ed303ddf56713adcee837bf6a2593ac4eec83cb4fb867601fd809580e3"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: desktop/src/components/common/ReviewModeGutter.tsx: desktop/src/components/common/ReviewModeGutter.tsx changed 2 times in last 90 days, max cyclomatic complexity 17 in ReviewModeGutter at line 42. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-16..2026-09-14, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-16 10:48:17 \u002B08:00\u0027 --until=\u00272026-09-14 10:48:17 \u002B08:00\u0027 --full-history --no-merges -- desktop/src/components/common/ReviewModeGutter.tsx\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":"desktop/src/components/common/ReviewModeGutter.tsx"},"region":{"startLine":42}}}],"partialFingerprints":{"codehealthFindingId/v1":"cdbafd89e6f342c87026d3013fb0973121d0ea6ba0b344d1e8046fa18fef30f7"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: desktop/src/components/settings/BackupTab.tsx: desktop/src/components/settings/BackupTab.tsx changed 2 times in last 90 days, max cyclomatic complexity 16 in BackupTab at line 15. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-16..2026-09-14, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-16 10:48:17 \u002B08:00\u0027 --until=\u00272026-09-14 10:48:17 \u002B08:00\u0027 --full-history --no-merges -- desktop/src/components/settings/BackupTab.tsx\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":"desktop/src/components/settings/BackupTab.tsx"},"region":{"startLine":15}}}],"partialFingerprints":{"codehealthFindingId/v1":"58635b367b743767ad16cc7b6d9495c2c9ceba1ce6e277fe1353e35c62e08fab"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: backend/scripts/judge_telemetry_report.py: backend/scripts/judge_telemetry_report.py changed 2 times in last 90 days, max cyclomatic complexity 16 in judge_telemetry_report.render at line 101. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-16..2026-09-14, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-16 10:48:17 \u002B08:00\u0027 --until=\u00272026-09-14 10:48:17 \u002B08:00\u0027 --full-history --no-merges -- backend/scripts/judge_telemetry_report.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":"backend/scripts/judge_telemetry_report.py"},"region":{"startLine":101}}}],"partialFingerprints":{"codehealthFindingId/v1":"a4aad054ced094595696c76c990ccbd205ac46ed36db86c79a4506c0f8fa24d6"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: backend/scripts/check_migration_class.py: backend/scripts/check_migration_class.py changed 2 times in last 90 days, max cyclomatic complexity 16 in check_migration_class.check_migration_class at line 197. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-16..2026-09-14, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-16 10:48:17 \u002B08:00\u0027 --until=\u00272026-09-14 10:48:17 \u002B08:00\u0027 --full-history --no-merges -- backend/scripts/check_migration_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":"backend/scripts/check_migration_class.py"},"region":{"startLine":197}}}],"partialFingerprints":{"codehealthFindingId/v1":"3b888297390a332f6428f3ca9f5a69d81f15b0397d4372989b25025e52ad2576"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: backend/hooks/daily_activity_hook.py: backend/hooks/daily_activity_hook.py changed 2 times in last 90 days, max cyclomatic complexity 15 in DailyActivityExtractionHook._capture_git_activity at line 333. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-16..2026-09-14, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-16 10:48:17 \u002B08:00\u0027 --until=\u00272026-09-14 10:48:17 \u002B08:00\u0027 --full-history --no-merges -- backend/hooks/daily_activity_hook.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":"backend/hooks/daily_activity_hook.py"},"region":{"startLine":333}}}],"partialFingerprints":{"codehealthFindingId/v1":"64550cce5a25915d80da4d6153316eabecb8eadde6ac2bcb951c25c2397e0f04"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: backend/core/code_intel/graph_analysis.py: backend/core/code_intel/graph_analysis.py changed 2 times in last 90 days, max cyclomatic complexity 15 in graph_analysis._build_file_domain_map at line 93. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-16..2026-09-14, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-16 10:48:17 \u002B08:00\u0027 --until=\u00272026-09-14 10:48:17 \u002B08:00\u0027 --full-history --no-merges -- backend/core/code_intel/graph_analysis.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":"backend/core/code_intel/graph_analysis.py"},"region":{"startLine":93}}}],"partialFingerprints":{"codehealthFindingId/v1":"78b43a30e927b23272d4ba849065c9bcdae33626bd5fe13d9d2629da1c7d41bf"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: backend/skills/s_pollinate/scripts/render_style_thumbnails.py: backend/skills/s_pollinate/scripts/render_style_thumbnails.py changed 2 times in last 90 days, max cyclomatic complexity 15 in render_style_thumbnails.roles at line 52. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-06-16..2026-09-14, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-16 10:48:17 \u002B08:00\u0027 --until=\u00272026-09-14 10:48:17 \u002B08:00\u0027 --full-history --no-merges -- backend/skills/s_pollinate/scripts/render_style_thumbnails.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":"backend/skills/s_pollinate/scripts/render_style_thumbnails.py"},"region":{"startLine":52}}}],"partialFingerprints":{"codehealthFindingId/v1":"9be11fd982479f0443096979693bb861e40ec0329c54db9c427d57735dde9588"}},{"ruleId":"D15","level":"warning","message":{"text":"Repeated repair: desktop/src/hooks/useUnifiedTabState.ts: desktop/src/hooks/useUnifiedTabState.ts changed 24 times in last 90 days and 16 of those changes were fix/bug commits, so repair is the majority of this file\u0027s churn. Its max cyclomatic complexity is 10 (its worst body is (anonymous) at line 767), 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: \u201Crevert(tabs): chat-tab ceiling 6\u21924 (3 chat \u002B 1 channel)\u201D; \u201Cfix(chat): OT01 render-freeze \u2014 stream-event guard uses latestStreamGen not streamGen (run_f9adee1e)\u201D; \u201Cfix(ot01): Gate-2 adversarial findings \u2014 queued-drain exemption \u002B log-flood guard \u002B docstring (run_251ea3ee)\u201D; \u201Cfix(ot01): hard-cap backstop clock \u2014 churn-immune force-clear bound (route-A AC1)\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-06-16..2026-09-14, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-16 10:48:17 \u002B08:00\u0027 --until=\u00272026-09-14 10:48:17 \u002B08:00\u0027 --full-history --no-merges -- desktop/src/hooks/useUnifiedTabState.ts\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":"desktop/src/hooks/useUnifiedTabState.ts"},"region":{"startLine":767}}}],"partialFingerprints":{"codehealthFindingId/v1":"8abe3b233404bb61089d4fba813501d2196e63843baac11ab44e18c5f4b87409"}},{"ruleId":"D15","level":"warning","message":{"text":"Repeated repair: desktop/src/components/common/Modal.tsx: desktop/src/components/common/Modal.tsx changed 18 times in last 90 days and 13 of those changes were fix/bug commits, so repair is the majority of this file\u0027s churn. Its max cyclomatic complexity is 4 (its worst body is Modal at line 33), 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: \u201Cfix(nav): single-surface overlay/modal mutual exclusion \u002B tint/spout for raw-button overlays\u201D; \u201Cfix(canvas): emit file_changed for parent Edit/Write results (UserMessage branch)\u201D; \u201Cfix(modal): responsive clamp() fullscreen-overlay widths \u002B de-blur scrim\u201D; \u201Cfix(canvas): Make null-rect modal fallback resize-reactive\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-06-16..2026-09-14, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-16 10:48:17 \u002B08:00\u0027 --until=\u00272026-09-14 10:48:17 \u002B08:00\u0027 --full-history --no-merges -- desktop/src/components/common/Modal.tsx\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":"desktop/src/components/common/Modal.tsx"},"region":{"startLine":33}}}],"partialFingerprints":{"codehealthFindingId/v1":"f6af9a9bbf0cd24a91be6c17cb283a3f7f075ebd5cf64c20a0fa6a5241a65d92"}},{"ruleId":"D15","level":"warning","message":{"text":"Repeated repair: backend/routers/cultivation.py: backend/routers/cultivation.py changed 13 times in last 90 days and 7 of those changes were fix/bug commits, so repair is the majority of this file\u0027s churn. Its max cyclomatic complexity is 12 (its worst body is cultivation.approve_proposal at line 130), 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: \u201Cfix(ci): repair 4 pre-existing CI failures exposed after the YAML parse fix\u201D; \u201C\u6839\u6CBB DDD cultivation \u002B governance \u51C6\u5165\u903B\u8F91:review/approve \u961F\u5217\u5806\u79EF\u566A\u97F3\u7684\u6839\u56E0\u662F 4 \u4E2A\u51C6\u5165 bug\u201D; \u201CConverge all DDD-doc writers onto utils.file_lock.md_lock \u2014 fixes a late\u201D; \u201CFix 2 verified latent bugs in DDD cultivation subsystem: (1) cultivation\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-06-16..2026-09-14, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-16 10:48:17 \u002B08:00\u0027 --until=\u00272026-09-14 10:48:17 \u002B08:00\u0027 --full-history --no-merges -- backend/routers/cultivation.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":"backend/routers/cultivation.py"},"region":{"startLine":130}}}],"partialFingerprints":{"codehealthFindingId/v1":"1a8dfdd7060f2d8e2b2e710d29d7de7498e7c35f6f69bc2eb10954defaa63f70"}},{"ruleId":"D15","level":"warning","message":{"text":"Repeated repair: desktop/src/components/layout/CommunityOverlay.tsx: desktop/src/components/layout/CommunityOverlay.tsx changed 13 times in last 90 days and 7 of those changes were fix/bug commits, so repair is the majority of this file\u0027s churn. Its max cyclomatic complexity is 12 (its worst body is OutboundTab at line 694), 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: \u201Cfix(review-followups): 4 real open items \u2014 gate wiring guard, git-fork batch, honest errors\u201D; \u201Cfix(adversarial-review): 3 confirmed bugs my own tests missed \u002B de-vacuous 1 test\u201D; \u201Cfix(community): wire github-people into the add-feed type picker (was frontend-zero-wired)\u201D; \u201Cfix(community-feed): surface the backend\u0027s honest truncation flag (was silently dropped)\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-06-16..2026-09-14, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-16 10:48:17 \u002B08:00\u0027 --until=\u00272026-09-14 10:48:17 \u002B08:00\u0027 --full-history --no-merges -- desktop/src/components/layout/CommunityOverlay.tsx\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":"desktop/src/components/layout/CommunityOverlay.tsx"},"region":{"startLine":694}}}],"partialFingerprints":{"codehealthFindingId/v1":"4cbe5cd5cee59a0af3b2a4b7727abf7c0ae41096a994612f1993b94a11e088b0"}},{"ruleId":"D15","level":"warning","message":{"text":"Repeated repair: desktop/src/hooks/useHealthMonitor.ts: desktop/src/hooks/useHealthMonitor.ts changed 8 times in last 90 days and 5 of those changes were fix/bug commits, so repair is the majority of this file\u0027s churn. Its max cyclomatic complexity is 8 (its worst body is (anonymous) at line 222), 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: \u201Cfix(paths): unify app-data root off production in tests\u201D; \u201Cfix(offline): close the last false-offline path \u2014 JS poll respects heartbeat liveness\u201D; \u201Cfix(health): watchdog verifies liveness before declaring death \u002B frontend degraded state\u201D; \u201Cfix(desktop): distinguish backend restart vs stall in health UI\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-06-16..2026-09-14, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-16 10:48:17 \u002B08:00\u0027 --until=\u00272026-09-14 10:48:17 \u002B08:00\u0027 --full-history --no-merges -- desktop/src/hooks/useHealthMonitor.ts\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":"desktop/src/hooks/useHealthMonitor.ts"},"region":{"startLine":222}}}],"partialFingerprints":{"codehealthFindingId/v1":"20c8d0c30f351fe547e70d5ca10d9dd31b7aa893da81fcecb8855a4fcce15c9a"}},{"ruleId":"D15","level":"warning","message":{"text":"Repeated repair: backend/core/app_config_manager.py: backend/core/app_config_manager.py changed 7 times in last 90 days and 5 of those changes were fix/bug commits, so repair is the majority of this file\u0027s churn. Its max cyclomatic complexity is 10 (its worst body is AppConfigManager.set_secret at line 256), 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: \u201Cfix(model): collapse 5 drifted model tables into one registry \u002B make silent substitution loud\u201D; \u201Cauth: add Bedrock API-key (bearer-token) mode \u002B onboarding fixes\u201D; \u201Cauth: Gate-2 convergence \u2014 fix 2 HIGH (stale env, use_bedrock default) \u002B atomic secret write\u201D; \u201Cauth AC3/FIX-A: durable secret store for anthropic_api_key (survives restart, never in config.json/backup)\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-06-16..2026-09-14, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-16 10:48:17 \u002B08:00\u0027 --until=\u00272026-09-14 10:48:17 \u002B08:00\u0027 --full-history --no-merges -- backend/core/app_config_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":"backend/core/app_config_manager.py"},"region":{"startLine":256}}}],"partialFingerprints":{"codehealthFindingId/v1":"7bec5cd551e7767c4dc8ec89007988499b6698ff8970b1988363b07a70046f92"}},{"ruleId":"D15","level":"warning","message":{"text":"Repeated repair: desktop/src/pages/chat/components/TSCCModules.tsx: desktop/src/pages/chat/components/TSCCModules.tsx changed 7 times in last 90 days and 5 of those changes were fix/bug commits, so repair is the majority of this file\u0027s churn. Its max cyclomatic complexity is 7 (its worst body is (anonymous) at line 713), 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: \u201CFix stale architecture content in the TSCC Flow tab \u002B OWNER map (TSCCMod\u201D; \u201Cfix(tscc): classify SELF.md as system-owned in the OWNER map\u201D; \u201Cfix(tscc): portal View-Full-Prompt modal to viewport \u002B colored pop-up border\u201D; \u201Cfix(tscc): report the real token budget and recall misses\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-06-16..2026-09-14, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-16 10:48:17 \u002B08:00\u0027 --until=\u00272026-09-14 10:48:17 \u002B08:00\u0027 --full-history --no-merges -- desktop/src/pages/chat/components/TSCCModules.tsx\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":"desktop/src/pages/chat/components/TSCCModules.tsx"},"region":{"startLine":713}}}],"partialFingerprints":{"codehealthFindingId/v1":"7fdf0e0149eb75343d205d463c8af1a3ed8a1f84cea69dfa45d14125f6b30044"}},{"ruleId":"D15","level":"warning","message":{"text":"Repeated repair: backend/core/session_state_persistence.py: backend/core/session_state_persistence.py changed 5 times in last 90 days and 5 of those changes were fix/bug commits, so repair is the majority of this file\u0027s churn. Its max cyclomatic complexity is 10 (its worst body is session_state_persistence.persist_session_state at line 32), 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: \u201Cfix(session): merge pending_ids into persist to prevent data loss on double-restart\u201D; \u201Cfix(session): adversarial fixes \u2014 no unlink on read \u002B missing timestamp guard\u201D; \u201Cfix(session): lazy-inject persisted sdk_session_ids at unit creation (PE HIGH fix)\u201D; \u201Cfix(session): adversarial review fixes \u2014 tighter patterns, time cap, test update\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-06-16..2026-09-14, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-16 10:48:17 \u002B08:00\u0027 --until=\u00272026-09-14 10:48:17 \u002B08:00\u0027 --full-history --no-merges -- backend/core/session_state_persistence.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":"backend/core/session_state_persistence.py"},"region":{"startLine":32}}}],"partialFingerprints":{"codehealthFindingId/v1":"eb1d58a706152d6413da734bee83f9681b60e905f5fbe8db8e310e528c5c303d"}},{"ruleId":"D15","level":"warning","message":{"text":"Repeated repair: desktop/src/components/layout/JobsRunsOverlay.tsx: desktop/src/components/layout/JobsRunsOverlay.tsx changed 7 times in last 90 days and 4 of those changes were fix/bug commits, so repair is the majority of this file\u0027s churn. Its max cyclomatic complexity is 14 (its worst body is JobDetailDrawer at line 316), 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: \u201CM4: migrate the 4 workbench overlays to OverlayHost \u002B fix proprioception SENSE/ACT lesion (run_fdeaead8)\u201D; \u201Cfix(jobs): script-job dispatch prompt directs command to config.command\u201D; \u201Cfix(jobs): Gate-2 adversarial findings \u2014 independent-settle fetch, drawer re-derive, gen-guard\u201D; \u201Cfix(jobs): REVIEW findings \u2014 timestamp-instant sort, Runs-view roster load, drawer/form mutual-exclusion, run-now error feedback\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-06-16..2026-09-14, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-16 10:48:17 \u002B08:00\u0027 --until=\u00272026-09-14 10:48:17 \u002B08:00\u0027 --full-history --no-merges -- desktop/src/components/layout/JobsRunsOverlay.tsx\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":"desktop/src/components/layout/JobsRunsOverlay.tsx"},"region":{"startLine":316}}}],"partialFingerprints":{"codehealthFindingId/v1":"8a89a6889ad65be426204bbc83f14f4df1756e9a684ec5dd9e608adf48869e2e"}},{"ruleId":"D15","level":"warning","message":{"text":"Repeated repair: backend/scripts/scenario_runner.py: backend/scripts/scenario_runner.py changed 7 times in last 90 days and 4 of those changes were fix/bug commits, so repair is the majority of this file\u0027s churn. Its max cyclomatic complexity is 14 (its worst body is scenario_runner.parse_final_text at line 114), 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: \u201Cfix(eval): utilization gate \u2014 polarity guard kills keyword!=behavior false-pass\u201D; \u201Cfix(eval): adversarial Gate-2 (DELIVER) \u2014 2 MED on the behavior-eval changeset\u201D; \u201Cfix(eval): adversarial Gate-2 \u2014 3 fixes on behavior-trajectory eval\u201D; \u201Cfix(eval,evolution): adversarial Gate-2 \u2014 5 findings on the self-evo-loop changeset\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-06-16..2026-09-14, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-16 10:48:17 \u002B08:00\u0027 --until=\u00272026-09-14 10:48:17 \u002B08:00\u0027 --full-history --no-merges -- backend/scripts/scenario_runner.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":"backend/scripts/scenario_runner.py"},"region":{"startLine":114}}}],"partialFingerprints":{"codehealthFindingId/v1":"1ecd065fada16a13164401c8f332d8fcefe8561d4ba462dc817f35d0ee9a6a98"}},{"ruleId":"D15","level":"warning","message":{"text":"Repeated repair: desktop/src/hooks/useChangeStatus.ts: desktop/src/hooks/useChangeStatus.ts changed 6 times in last 90 days and 4 of those changes were fix/bug commits, so repair is the majority of this file\u0027s churn. Its max cyclomatic complexity is 5 (its worst body is handler at line 115), 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: \u201CCycle 6/6 (run_e626e121): Gate-2 adversarial fixes\u201D; \u201Cfix(canvas,chat): speed up outputs list \u002B land chat at bottom on tab switch\u201D; \u201CFix GET /workspace/file/committed: binary/non-UTF-8 files should return\u201D; \u201Cfix(radar): 6-fix \u2014 English UI, committed-based NEW/UPD (cross-repo), line-clamp, compact, NEW-first, diff fail-soft (run_19e04b0f)\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-06-16..2026-09-14, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-16 10:48:17 \u002B08:00\u0027 --until=\u00272026-09-14 10:48:17 \u002B08:00\u0027 --full-history --no-merges -- desktop/src/hooks/useChangeStatus.ts\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":"desktop/src/hooks/useChangeStatus.ts"},"region":{"startLine":115}}}],"partialFingerprints":{"codehealthFindingId/v1":"4ddfd3d9840ccab0bc202b47727988f3c0770688cc15ca9277d5ba8b997d53d5"}},{"ruleId":"D15","level":"warning","message":{"text":"Repeated repair: desktop/src/components/terminal/TerminalTab.tsx: desktop/src/components/terminal/TerminalTab.tsx changed 6 times in last 90 days and 4 of those changes were fix/bug commits, so repair is the majority of this file\u0027s churn. Its max cyclomatic complexity is 8 (its worst body is (anonymous) at line 233), 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: \u201Cfix(terminal): eliminate mouse-selection drift \u2014 preload JetBrains Mono before xterm measures its cell\u201D; \u201Cfix(terminal): 4 UX fixes \u2014 click-swallow overlay, selection re-measure, dense layout, history-preserving collapse\u201D; \u201Cfix(terminal): colors \u002B legible style \u2014 inject TERM, ANSI palette, font\u201D; \u201Cfix(terminal): typing (focus race), default terminal\u002Bcwd, numbered tabs\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-06-16..2026-09-14, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-16 10:48:17 \u002B08:00\u0027 --until=\u00272026-09-14 10:48:17 \u002B08:00\u0027 --full-history --no-merges -- desktop/src/components/terminal/TerminalTab.tsx\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":"desktop/src/components/terminal/TerminalTab.tsx"},"region":{"startLine":233}}}],"partialFingerprints":{"codehealthFindingId/v1":"121ef1fea8eee2be802135dab73ebe8ec140cc6b1b55f89f3f67f5fb3e82da17"}},{"ruleId":"D15","level":"warning","message":{"text":"Repeated repair: scripts/check_commit_trailers.py: scripts/check_commit_trailers.py changed 5 times in last 90 days and 4 of those changes were fix/bug commits, so repair is the majority of this file\u0027s churn. Its max cyclomatic complexity is 12 (its worst body is check_commit_trailers.main at line 137), 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: \u201Cfix(ci): amnesty trailer-less commit d8c247a3 in trailer gate\u201D; \u201Cfix(ci): repair 4 pre-existing CI failures exposed after the YAML parse fix\u201D; \u201Ctrivial: (A) fix test_admission_rootfix.py:166/186 from-backend.-prefixe\u201D; \u201Cfix(ci): enforce the Co-Authored-By identity in CI \u2014 the local hook has been dead all along\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-06-16..2026-09-14, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-16 10:48:17 \u002B08:00\u0027 --until=\u00272026-09-14 10:48:17 \u002B08:00\u0027 --full-history --no-merges -- scripts/check_commit_trailers.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":"scripts/check_commit_trailers.py"},"region":{"startLine":137}}}],"partialFingerprints":{"codehealthFindingId/v1":"a971249fe7efed87f1c5b2e32e3df9920efa4889e65d2760e7f188170c701c8c"}},{"ruleId":"D15","level":"warning","message":{"text":"Repeated repair: scripts/security_scan.py: scripts/security_scan.py changed 5 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 13 (its worst body is security_scan._cors_fingerprints at line 332), 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: \u201CClose R32 self-enforcement gap: add A4 wildcard-CORS regression check to\u201D; \u201Cfix(security-gate): fail CLOSED on scanner tool crash (RP50 fail-open regression)\u201D; \u201Cfix(security): exclude private skills from scan \u002B purge leaked paths from baselines\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-06-16..2026-09-14, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-16 10:48:17 \u002B08:00\u0027 --until=\u00272026-09-14 10:48:17 \u002B08:00\u0027 --full-history --no-merges -- scripts/security_scan.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":"scripts/security_scan.py"},"region":{"startLine":332}}}],"partialFingerprints":{"codehealthFindingId/v1":"1a1521096f635a4f82cc670d84e37ca98135654a715becb59a702516489ec5d9"}},{"ruleId":"D15","level":"warning","message":{"text":"Repeated repair: backend/core/recall_metrics.py: backend/core/recall_metrics.py changed 5 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 5 (its worst body is recall_metrics.record_recall_metric at line 53), 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: \u201Cfix(recall-metrics): requeue a drained window when the flush write fails (no data hole)\u201D; \u201Cfix(recall-metrics): stamp timestamp at measurement time, not flush time\u201D; \u201Cfix(observability): clear the last 17 lying-result handlers; gate against logs that crash\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-06-16..2026-09-14, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-16 10:48:17 \u002B08:00\u0027 --until=\u00272026-09-14 10:48:17 \u002B08:00\u0027 --full-history --no-merges -- backend/core/recall_metrics.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":"backend/core/recall_metrics.py"},"region":{"startLine":53}}}],"partialFingerprints":{"codehealthFindingId/v1":"e70aafe3a166fd2b186a662a878a74e5e9bb466cb8f1c133982556040c5a066c"}},{"ruleId":"D15","level":"warning","message":{"text":"Repeated repair: backend/core/evolution/governance_miner.py: backend/core/evolution/governance_miner.py changed 5 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 10 (its worst body is governance_miner.generate_governance_proposals at line 202), 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\u6839\u6CBB DDD cultivation \u002B governance \u51C6\u5165\u903B\u8F91:review/approve \u961F\u5217\u5806\u79EF\u566A\u97F3\u7684\u6839\u56E0\u662F 4 \u4E2A\u51C6\u5165 bug\u201D; \u201Cfix(evolution): defense-in-depth axis guard on governance_miner loop (run_685db747 Gate-2 MED)\u201D; \u201Cfix(evolution-v3): Phase 2 adversarial Gate-2 findings (2 HIGH, 1 MED)\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-06-16..2026-09-14, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-16 10:48:17 \u002B08:00\u0027 --until=\u00272026-09-14 10:48:17 \u002B08:00\u0027 --full-history --no-merges -- backend/core/evolution/governance_miner.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":"backend/core/evolution/governance_miner.py"},"region":{"startLine":202}}}],"partialFingerprints":{"codehealthFindingId/v1":"b5e0df13085086c15fc4b355bfc2897777c16740c1b5aae02a6caf52c5c35cb1"}},{"ruleId":"D15","level":"warning","message":{"text":"Repeated repair: backend/core/evolution/judgment_classifier.py: backend/core/evolution/judgment_classifier.py changed 5 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 10 (its worst body is judgment_classifier._classify_cognitive at line 235), 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: \u201Cfix(evolution): adversarial Gate-2 \u2014 traceback discriminator must precede noise substrings\u201D; \u201Cfix(evolution): noise-gate the correction tracker \u2014 stop operator-noise polluting OPERATIONAL \u002B fake governance\u201D; \u201Cfix(evolution-v3): adversarial Gate-2 findings (1 CRITICAL, 1 HIGH, 2 MED)\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-06-16..2026-09-14, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-16 10:48:17 \u002B08:00\u0027 --until=\u00272026-09-14 10:48:17 \u002B08:00\u0027 --full-history --no-merges -- backend/core/evolution/judgment_classifier.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":"backend/core/evolution/judgment_classifier.py"},"region":{"startLine":235}}}],"partialFingerprints":{"codehealthFindingId/v1":"c089a961b362e2185da4b5bfa418ddab0aa17bbdc585352ace75dc014eb5649c"}},{"ruleId":"D15","level":"warning","message":{"text":"Repeated repair: backend/core/code_intel/__init__.py: backend/core/code_intel/__init__.py changed 4 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 8 (its worst body is code_intel.invalidate_cache at line 88), 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: \u201Cfix(observability): clear 6 more lying-result handlers; teach the gate that yielding an error event counts\u201D; \u201Cfix(code-intel): validate repo_root ownership before index/watch \u2014 stop cross-project contamination (run_1950e67e)\u201D; \u201Ccode-intel: fix reindex repo_path parsing \u2014 reuse shared multi-format helper\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-06-16..2026-09-14, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-16 10:48:17 \u002B08:00\u0027 --until=\u00272026-09-14 10:48:17 \u002B08:00\u0027 --full-history --no-merges -- backend/core/code_intel/__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":"backend/core/code_intel/__init__.py"},"region":{"startLine":88}}}],"partialFingerprints":{"codehealthFindingId/v1":"1745295ad961a9da0c65ea5fcf9c2e500b9cea4b547124aee3aa2d5280307e6d"}},{"ruleId":"D15","level":"warning","message":{"text":"Repeated repair: backend/core/permission_manager.py: backend/core/permission_manager.py changed 4 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 5 (its worst body is PermissionManager.is_resolved at line 217), 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: \u201Cfix(hooks): exempt HITL gates from 5s chain timeout \u002B align approval wait to 4h (run_6e780e00)\u201D; \u201Cfix(session): complete approve-into-void deadlock fix \u2014 endpoint recovery \u002B Gate-2 comment (run_65f317db)\u201D; \u201Cfix(perm): permission-prompt hang \u2014 durable re-surface \u002B bounded timeout \u002B narrowed rm gate\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-06-16..2026-09-14, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-16 10:48:17 \u002B08:00\u0027 --until=\u00272026-09-14 10:48:17 \u002B08:00\u0027 --full-history --no-merges -- backend/core/permission_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":"backend/core/permission_manager.py"},"region":{"startLine":217}}}],"partialFingerprints":{"codehealthFindingId/v1":"d686b99e39899aebc06e56544a11c8e47cd15341c7ffb095ebc4ac986109a467"}},{"ruleId":"D15","level":"warning","message":{"text":"Repeated repair: backend/scripts/refresh_ai_docs.py: backend/scripts/refresh_ai_docs.py changed 4 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 12 (its worst body is refresh_ai_docs._load_engines at line 142), 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: \u201Cfix(docs): core_loc \u002B core_modules \u2192 git-tracked tests-OUT caliber\u201D; \u201Cfix(docs): point SSE staleness checks at streaming_orchestrator\u201D; \u201Cfix(docs): total_backend_loc via git ls-files \u2014 reproducible, no timeout\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-06-16..2026-09-14, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-16 10:48:17 \u002B08:00\u0027 --until=\u00272026-09-14 10:48:17 \u002B08:00\u0027 --full-history --no-merges -- backend/scripts/refresh_ai_docs.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":"backend/scripts/refresh_ai_docs.py"},"region":{"startLine":142}}}],"partialFingerprints":{"codehealthFindingId/v1":"231a3a1ffcad044788eef35f8b9c26c04aa7cf0487ec8665605c816fd7e90234"}},{"ruleId":"D15","level":"warning","message":{"text":"Repeated repair: desktop/src/stores/TerminalStore.ts: desktop/src/stores/TerminalStore.ts changed 4 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 5 (its worst body is openTerminal at line 143), 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: \u201Cfix(terminal): 4 UX fixes \u2014 click-swallow overlay, selection re-measure, dense layout, history-preserving collapse\u201D; \u201Cfix(terminal): typing (focus race), default terminal\u002Bcwd, numbered tabs\u201D; \u201Cfix(terminal): Gate-2 adversarial fixes \u2014 platform-aware shell \u002B drain one-shot clear\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-06-16..2026-09-14, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-06-16 10:48:17 \u002B08:00\u0027 --until=\u00272026-09-14 10:48:17 \u002B08:00\u0027 --full-history --no-merges -- desktop/src/stores/TerminalStore.ts\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":"desktop/src/stores/TerminalStore.ts"},"region":{"startLine":143}}}],"partialFingerprints":{"codehealthFindingId/v1":"710e0c7962206ef0a05a6e75cdc7af575957c00b5b6e4f2e76bb51c7acf8a65b"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # ToDo lifecycle: auto-complete bound todos, implicit file matching \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/main.py"},"region":{"startLine":1221}}}],"partialFingerprints":{"codehealthFindingId/v1":"400b5ae808452c237450acebe5fb289f3c0c29bd1752378b6c9868adc408d537"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # ToDo flow-closure fields (run_d28de5fd) \u2014 Gate-1 C: _dict_to_response is 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":"backend/core/todo_manager.py"},"region":{"startLine":562}}}],"partialFingerprints":{"codehealthFindingId/v1":"8af0bb8ca884fd4e41cb944b6740f87f883ecf8275037872ba4a1d3356d5fdb0"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # fail-open) \u2014 but the match body is a TODO and the gate exits 0 (allows all) until 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":"backend/core/evolution/gate_scaffold.py"},"region":{"startLine":36}}}],"partialFingerprints":{"codehealthFindingId/v1":"4967aae157d7fcfa1f8e4891a7b22ba121e59d536236065db1f4fd6613da3baf"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO(human): inspect \u0060event\u0060 (tool_name / tool_input) and return 2 with a 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":"backend/core/evolution/gate_scaffold.py"},"region":{"startLine":70}}}],"partialFingerprints":{"codehealthFindingId/v1":"2a3e75c4f8d559fb91e56a8076d788e17c49d863cb70329f5680b6add8582d36"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # ToDo Schema Extensions (Swarm Radar ToDos \u2014 Sub-Spec 2) \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/database/sqlite.py"},"region":{"startLine":3111}}}],"partialFingerprints":{"codehealthFindingId/v1":"ab2becbb821efd0ee141d8bb20395894d1553a1614437f505b2f44eec0d39ea5"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # opens with a non-type bracket like \u0022[TODO] ...\u0022 or \u0022[2026] ...\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":"backend/hooks/context_health_hook.py"},"region":{"startLine":1055}}}],"partialFingerprints":{"codehealthFindingId/v1":"ed0fce06cbc37ce2fcc4a00032327a8dfe445e2b773ee50f9cfd4580d822dfc6"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # (Todo Resolution job removed run_50db230a \u2014 it auto-resolved/cancelled todos, \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/jobs/system_jobs.py"},"region":{"startLine":323}}}],"partialFingerprints":{"codehealthFindingId/v1":"a52e8dd7dd7a9262fd1a1ffa7bba007edc384cf0fc5f7de7a0f76e9a46d8e43f"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # path; \u0060queries\u0060 is a commented-out TODO). Exposing member editing would be 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":"backend/jobs/models.py"},"region":{"startLine":78}}}],"partialFingerprints":{"codehealthFindingId/v1":"584953a7b2e2b613831869ad45c2a316923ec831d5810b73e74a74d1b3820fd9"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # \u2500\u2500 Todo Lifecycle: Expiration, Escalation, Purge \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/jobs/executor.py"},"region":{"startLine":1839}}}],"partialFingerprints":{"codehealthFindingId/v1":"7639fb814b21b4b1b12ecf71b965700c4d22857d8c14c194fc946916583f5d7d"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # todo still awaiting human review (review_state=\u0027completed\u0027), even if 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":"backend/jobs/executor.py"},"region":{"startLine":1963}}}],"partialFingerprints":{"codehealthFindingId/v1":"876cb19403cf7abf789ed5556106c2e90dc552848ce5ad35faa1edcf84d93afc"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: Implement Tavily search when API key is available \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/jobs/adapters/web_search.py"},"region":{"startLine":36}}}],"partialFingerprints":{"codehealthFindingId/v1":"4b017331a1f28b70a613b41d8d42271a39f739fb148b5afb3a90d65c1270c4f2"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # \u2500\u2500 ToDo flow-closure History (run_d28de5fd) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/routers/todos.py"},"region":{"startLine":75}}}],"partialFingerprints":{"codehealthFindingId/v1":"a4a91d2168f29a3ad081be8c0f6c0d74729d0361ec9249243efecc10fdf4c83d"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # \u2500\u2500 ToDo Attachments (run_162b8817) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/routers/todos.py"},"region":{"startLine":403}}}],"partialFingerprints":{"codehealthFindingId/v1":"9fd8a15b6cbb034fb54c389e043a8258a18385311a726cd7328693c1f488a3a7"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # ToDo flow-closure fields (run_d28de5fd) \u2014 review dimension is ORTHOGONAL to status. \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/schemas/todo.py"},"region":{"startLine":144}}}],"partialFingerprints":{"codehealthFindingId/v1":"24235454789a724740232809a0f9e2af293c93c0a7c6ad7f1e48c5d333b42f15"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # ToDo Flow-Closure \u2014 History, Stats, Review (run_d28de5fd) \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/tests/test_todos_router.py"},"region":{"startLine":370}}}],"partialFingerprints":{"codehealthFindingId/v1":"c432ce17f930ccd6bcaa31bf9bcf6ee0372c51a2766f20370b11f1c3f5c3ee1d"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # ToDo Flow-Closure \u2014 Dispatch \u002B Retreat (run_5088b841, A2) \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/tests/test_todos_router.py"},"region":{"startLine":436}}}],"partialFingerprints":{"codehealthFindingId/v1":"14c134df47c8bcce3f8bcc9cb01aff6f190e903caee4d281b4749bc5acbb30f2"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # VALID_TYPES guard as the honor, or \u0022[TODO] ...\u0022 loses content. \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/tests/test_run2_type_wiring.py"},"region":{"startLine":221}}}],"partialFingerprints":{"codehealthFindingId/v1":"ea9fcb2953b2efcd91eaf43ecadf2bf5ae27af1ee51c6b7aefcbc8bdbe754e58"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # --- ToDo enums --- \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/tests/test_property_enum_validation.py"},"region":{"startLine":16}}}],"partialFingerprints":{"codehealthFindingId/v1":"7c3987c1cefda6c49bae6109fc014d8168dcbdd4fed64b4a9a54cd75607cc660"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # A legitimate [TODO]-style lead is NOT in VALID_TYPES \u2192 must survive in body. \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/tests/test_distill_lesson_types.py"},"region":{"startLine":138}}}],"partialFingerprints":{"codehealthFindingId/v1":"078c930d1cd0043132466894b4a0ac0f6947c4b26d9e07c696c3a2ef8ffbefb4"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: // ToDo gone, Jobs shown \u2014 exactly one surface open \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060// REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/layout/overlayHostE2E.test.tsx"},"region":{"startLine":149}}}],"partialFingerprints":{"codehealthFindingId/v1":"98f9e2985c1e53764e3c8565a9027e7b34180c61e10c2db9e662987c087f75de"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: // ToDo \u2014 a checklist: a card with a check mark (queued work you own). \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060// REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/layout/ThreeColumnLayout.tsx"},"region":{"startLine":503}}}],"partialFingerprints":{"codehealthFindingId/v1":"4ae36f6352cb4292b94e169e87e365fa4471a6003a06dac1d899439ce6017fb9"}},{"ruleId":"D17","level":"warning","message":{"text":"HackComment: // hack existed because the legacy overlay stayed mounted and \u0060open\u0060 didn\u0027t observably \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":"desktop/src/components/layout/__tests__/NewBrainOverlay.interaction.test.tsx"},"region":{"startLine":184}}}],"partialFingerprints":{"codehealthFindingId/v1":"1ab9b75f8cf7908b089027bdb924e56169695f891ecacf075027afc0d83a24fd"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: // ToDo / Jobs \u0026 Runs / Pipeline / Pollinate \u002B NewBrain overlays retired (M3\u002BM4): \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060// REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/pages/ChatPage.tsx"},"region":{"startLine":64}}}],"partialFingerprints":{"codehealthFindingId/v1":"3ea69a9239e42a4b87b384c9967cad680c91c5e0390f5277646bbe21770659f2"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: // ToDo Dispatch \u2460\u2192\u2461 (A2, run_5088b841). APPEND-ONLY record of dispatches whose \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060// REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/pages/ChatPage.tsx"},"region":{"startLine":1199}}}],"partialFingerprints":{"codehealthFindingId/v1":"0f2f24e36e9daa191bab0cb7a36b83eac255ef0d7b9d661372529a72cbece8c8"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: // ToDo Dispatch backfill: this tab\u0027s session just materialized (active path). \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060// REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/pages/ChatPage.tsx"},"region":{"startLine":1920}}}],"partialFingerprints":{"codehealthFindingId/v1":"f2b246e4c284b65857b873c59a18f03c1cc714f57dcf1902bd5d38e28f05e855"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: // ToDo Radar sidebar constants \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060// REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/pages/chat/constants.ts"},"region":{"startLine":24}}}],"partialFingerprints":{"codehealthFindingId/v1":"127a5f014d65b87a5c3a17115a2fbb8d77c64c2170303c2d2e2b1cc28b36064e"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: // \u2500\u2500 ToDo flow-closure (A2) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060// REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/services/todos.ts"},"region":{"startLine":171}}}],"partialFingerprints":{"codehealthFindingId/v1":"37fb21a13fdc27862026e9932cf25b5c36ce716afc53998dfa15ada21268e016"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: // ToDo flow-closure fields (run_5088b841, A2) \u2014 mirror A1\u0027s 7 backend columns. \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060// REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/types/todo.ts"},"region":{"startLine":50}}}],"partialFingerprints":{"codehealthFindingId/v1":"4f4b5432c203913e09efe5fa9d3706299dbb0e6318bad63b42574c483ad1b516"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: // ============== Todo Types (canonical Todo 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":"desktop/src/types/index.ts"},"region":{"startLine":1279}}}],"partialFingerprints":{"codehealthFindingId/v1":"a5c8178f713042e3ccceb9589a7858d6f093abc70ae9b4f4aae69e004b6a4d67"}},{"ruleId":"D19","level":"note","message":{"text":"Documentation: no installation or build instructions: The desktop README shows how to run Tauri frontend from the project root but there is no installation or build step for the backend. Add setup instructions for running the backend standalone (cd backend, uv sync, activate .venv/bin/activate then python main.py) and a one-line \u0027Run both backend \u002B frontend\u0027 command."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"README.md"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"1fa6bfcd5c6ae231d1b8ee99bced50b832d1f61cde9da6cbb533467b879a57db"}},{"ruleId":"D19","level":"note","message":{"text":"Documentation: no installation or build instructions: The \u0027Installation\u0027 section is cut at the clip marker before Build from Source and Clone the repo install steps appear; no build/run instructions for the frontend or backend follow the prerequisites list. Complete the Installation chapter with Build from Source (setup Node, run npm install -g claude-code \u002B ai-ready helpers), clone the repo, install frontend dependencies, set up backend environment, and run in development mode."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/USER_GUIDE.md"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"67a862a6c3204e81f6f44ef1578b071841701922d344a9c76ae6b856d06083c5"}},{"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":"cac6eef7d3b69ac2c0ae0f33670f89cef5e1504dee08fb6fbcbab41cc219d6c4"},"properties":{"commitSha":"aa41ae1f68cb616b6e680a7ddf22737479972f0f"}},{"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":"32fdfa8101e2a84404c582985e455d6e834fba9fdd343532aa1a467b5ea9bb32"},"properties":{"commitSha":"aa41ae1f68cb616b6e680a7ddf22737479972f0f"}},{"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":"5d566268a954325a412b4320851639a8830855c82383e1741859a84db12a8c24"},"properties":{"commitSha":"8b03144d0547f4df79304ae3b138fab40d194ff5"}},{"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":"16418ab36c8a1f6931c098d720a76d6815b890c758b50bb2e1dcb9857bc12fe5"},"properties":{"commitSha":"83075b02a0784c42b95c2e3ff7e72e853068b335"}},{"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":"18e734607f98410ba3eafa3012a715d4322c538e856a1ff7a879bd5ac8deef03"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"f7ad9ddad2ef52a8f1c20dff69fd2251d48fd00e3c5bb333e0a94dca7d5da81f"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"db8d7333f70fb527f75b5dbf795dfcce903f206b270e91de7791aacda00db655"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"2ba550c21cbcb2f003cb248a75b28d004140e43e9bde541df1581aae817446ec"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"918c19da52ef7c9b9f9284d1c1db05b7f7529e83535a1e6811e413b1e49d40e7"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"0e415e9b52f0d96b30bb5f4b3d2499c5ff39938e1cd7e2f728eb1984f79e79f8"},"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"}}]},{"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":"1f0eece2bdc9dc76e4a1f4fe0021f2e54a9f9d3749ab3c1103163a7131e7fb9a"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"848230d9994ea1be9c83b9d6fdf9109811faba4b240726c8f4e379106ff318ab"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"0c5f762b8a58e9787e158c1da1db431664724cfb11870431707ca72ac9715f10"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"3a8e1a0dd08335c949771e4adc5c49e91c6d28106b95faba032f68bf4a067225"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"6efe5eb2e6e232d40f62c4eceef055c51446a6b1a482c72a018284666940baff"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"58e73af918c0e4c4a1941f3f18aa9d6810a384b156aeb80c1a82c7d8386ce691"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"12b91060c9bd6612ed63ab3ed405dd8403fae93c72b3669881749579bb4e04b0"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"3b38f559bb7943c233a5c2ae7f3752bd87e0343c4bfabf060ac718f1b7a1dc29"},"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"}}]},{"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":"6b12310d9f6c35277721c49271b8ded618cb5bd36700bb3babe3fef40a28e0ca"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"147205d670e5fc22f622605db32b109815f3ed668469c5a6d51bc6bfcb74c9f2"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"8850564d96e971f5001084aa433aa84236bef2cd5eaa20eea40a536e3371c1c5"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"e3a92c206eb984eac781f11d1c300012a13864a912686be891001a44a41ed7a7"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"5db35721cbe43b6c94ec474ca9beb386167bef27e61dbea01a837c7fcb3e23c7"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"a10eaffe9e7450a7657b8e455f9891776c6ad651dbf34313a7afda21b06f59f6"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"b36974b34137c1a99b7943af759006761814231a6b53c05e825cedb73454f2f4"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"a4da886e937061736c187afa47b4e6d839a6aa67f6efc30fa0f23a4261e52bee"},"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"}}]},{"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":"02d2a6b8d6273ad1a50e288529ea08eef627e9f05d90cc834ea2cea0b13116c2"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"ec1e59b6f5c98b1cf1f634a2e776264e8e2caf4cbc3dfb12cf92ddef24da0586"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"4cc97d3d72eab18cb89737a64c941b7954645034cdd2ab4a33ef5cdeadd83cda"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"ef488843633c984916511de4f175d4b1cc911bd345edafa4512b0be3a4b8dfce"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"0cd89440c03b23cbbe553d5aff68c8770652acf2c0eabe86f2662d9dfc1ac45f"},"taxa":[{"id":"CWE-522","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-829","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"a1f31e3fc38e806c632551480508ae27b2701acddad0a9d80c648ba1fc9463b3"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"71d409363b55a1d24dc05307b924cc6c6729c6dbea72afa05fed85828fe13b0b"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"1b2c20be6cd4d5daf6f7edc67eba8034a47d61bbb379e300b26def29fe5d9722"},"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"}}]},{"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":"c1bb7814097052b3b9e49cf20adb5ffa3c94da3abc00863955683dc4725b2e91"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"b15e7c4516957eb0ce628a71875180462280b3da835590c3e3ea26dfe36c7cc0"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"493308c88e8c66fcb98ce33fa8a7c07e2fee06375429dcf7629ec741ee5f79d7"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"39c94cbe76284f39432df58cf08c3b77853cea32b0d007e0d025916e5d0dcdd9"},"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"}}]},{"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":"ae4b19a624088a80ae967fa19fc6e2d3b4d86bf95f6afb9918729adad8224e32"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"a550cf5e27a8b506045e8d79bea30953c1a97b6937e60e5e7073c41d1cf1cd6e"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"0015faa3f41ba498f22c174208a0cb9ca2872b761f7ac29a920ad5aed4405099"},"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"}}]},{"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":"ac8eb79dfa01848c9591d4d3d4639a6823be4bbb96d16a40df23728da77d6f08"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"82a1893f62fe8dee3fcdaad2e3da3e94b86729172346ee8d336b86cb9d8780c6"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"86cc361b36735e4f8d9b9924f9bfcd4f8ebd2ce257f31fd78c4b71420d976aeb"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"6b562a86ba4fad32d6ccdcd6ca2d4c34c2236a59e5d8276adbfb83a1790cdee0"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"d9525315a3cb1310a0b67d8bed75b5c222bfee55a252476ffae05acacc3d32ca"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"5a498cd11fd91a338650bb071832557ece40d0c3bbbbb2771d6505dfa0e9a169"},"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"}}]},{"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":"bc277f6ce0d09fb91b41104958bfa4f80d0ac582391b553eb9f0aec2cb1ea9a4"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"030e06150ccaa7f8f98b8cd801dcc557a2dcdb87ac92727b5052d987d54de0aa"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"3b21b3e6ad049d854c73edd8b6242b71a10fa6c622c4172a4f6c7deb472cdf6c"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"a9a25afc63b301e3eecde95f7fec9a1480290d447e1fe8c8fb5219b8ebfc053b"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"3277d7fb7128c6edb5ef336f293e0b8b37eb0d0be7d21973b21556f389b39a04"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"7ae42b7721e3efe59d5d7af6a92a3cf44c96b8e0b44064418e65dec007f38243"},"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"}}]},{"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":"abf574d4f4bcaafb4f571f1fdaddfefc0bc63bccc18f3a1a91c4eb329be355c2"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"ba4e251c982a0d520dee483c4364d631354e4ca47320ac9510a11c4bc6581798"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"edb6878814061a8ab646891e1fb520239e968fd778fa69f019f44b9cc3ab1b4c"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"3c3ad5035106107ef9b511858afddfdaf688a7c64d220a1a995e775a461b4f89"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"b355bac043b38e9338ee16617c127422c8317a47e231c7f86331a7246eab20f9"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"bf4aafda12b67f6c59c1db0636bade2203e6bef7b3bf784e9027df4025512de9"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"0ea6684dc7a0ca2993c87a9ae5c8f52404ab6b6232a4365d9698496ce1643f40"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"dcca1de5b5cece7bf7ec208289ed60818e3d686febe7bea1329fc72df29c651b"},"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"}}]},{"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":"62d650459066b9c5e3d82105d4dd423284d9fbdb63e9240f78311d328f81a17c"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"ff27ad966709a5ee49e1d59e843e3dedc31f7c102d43fc2e939c6ac29816fb7f"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"b491bd9badc2a772b5e836fcb8623a636aa172c6cca53908f058346dfb0ecf25"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"c4100309d27ec090d44ad0e10348741b05bc3c8a876410b1f4b823b0883d87f5"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"73eeca107b22305eec0b03819189505d3fe4bf0bd1414fd54a316f6807bed26a"},"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"}}]},{"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":"f1b966c70d2e5f6ab697ac6d268d54938c60e802d8ea58ea6ff9cb7e10a35f70"},"taxa":[{"id":"CWE-78","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"b21ef51d97f04d1a8b921e635aca9ef4e877341aa2c3b0f6eaeabc61234774b6"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"f3526ae158dac3f4206fcf9b7a1edf762bedebdc242d662fb1b513f3a6d60d2f"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"e8f51d4d8680a1b6ded6d1277fb40e58e067409c8e24cc273cacc0f72c3aa654"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"4f51d598102786d6fe7ccdb4c5ce07901ce46b3341024418f2338de4b1f69943"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"8018fa76f9798f58c2d54888e01f82e01d93750f0c34580eea02821510c2b5a4"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"bc216a52b819aa4a0b7f5bc91dd57a39a75da658b26b6efc67ab56c9dc049565"},"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"}}]},{"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":"1b4511c53e02c81755a593474710d00223291493c8e07450bc1d5b39e2dc7fd8"},"taxa":[{"id":"CWE-78","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"6819b36024d45f5f0e1d43e74427f1e72c7d8dae5d09101e0f966a51bf6829ab"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"ae59d5e9dd2c30e110a21be3f2f3e4339df91ffb4154cfcf5f17bedb858ec684"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"6504d8d1633fd2629c17cb911821ef9d4b240f323d5e1ebac2df01ac4726a04a"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"cc817651145b3746bc99495e7fbc5498d41cc1b481fe483113715158512ae9c6"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"5c345193eb5906333a686cc268ee1517ae41d2d38dc0eb623995a922e52e5337"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"8d29b94038490c84613e9786e27a95b1e6778b882160e1bb8b3d7dcc9422beff"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"0ebfa2765d8efb6978e2b1650650a9da4c08d488c70af43b366445729a0fb817"},"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"}}]},{"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":"d14aeb239850d1cf3ca915c94f12cff4aa3852c2362620f96cbfd76024415e68"},"taxa":[{"id":"CWE-78","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"64478662fa5e1544368a8d37a73d78bfc90ea789fe52460bc2794d70b8e273b3"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"04b15c1d822501a1f3b0513e178960337673a790f4f183f2453907ced2d2833f"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"5820d2832b24c301dfa745945b6d73762e17d6f8190921e1bba42ea7ccd769f9"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"31e15292ee7781495cff3025f3779e23aded0d07be93120b45c65e1d6518c389"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"64aee044c1f4dd4bb7a77441c8cfb2ad1960dbe2c5bbb6dcc4a3af1fa08e7b62"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"55a5bc4a80aeddd75645f19cd0b15a9ccf9f7ff655f12f0887ab47d4183dd877"},"taxa":[{"id":"CWE-78","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"957b150e90b8de065e3fab913d6db8aa84cc38085b4826b482eaabde0c4cf347"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"865c1256b0af6cac7fabd52ec1703a6840a81e82c2cc09619e5e78e47af02756"},"taxa":[{"id":"CWE-522","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-829","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"b45ba80919220fae46df345496310afc2ed11151592dcbbc6a91f27bbfcce5f6"},"taxa":[{"id":"CWE-79","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"edb0a649a1b2344844cb2fda358d36f0fe399d3c1882e3775d53a28f2ed1e990"},"taxa":[{"id":"CWE-494","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":"cc9c8f9c86d4e0e1ba5945d04b4b71ec2026cf96913820c7ebfdd035da69b073"},"taxa":[{"id":"CWE-522","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-552","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":"fce31a2d31070c30c33fa3a6e7942534068baf3faa22f8cbac8707ae42afa974"},"taxa":[{"id":"CWE-522","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-552","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":"edb348695b08c29c55045f169ac22a35e67fe2ae3df7cf74bbd41cc0cedd0c33"},"taxa":[{"id":"CWE-532","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":"bff0d559f5214cae89f39bf36eb84f642f3d89496ea648bc8f5a5d9eed58054a"},"taxa":[{"id":"CWE-532","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":"fa94395d9918ff1e38387e1dc38ed696d71215f4363797eb9d6e4220c87f46eb"},"taxa":[{"id":"CWE-327","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"warning","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"8dc8183accf21aeefe540881e37348c2d32fbc09caa91f1fa66a703afec939f3"},"taxa":[{"id":"CWE-532","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":"7ba95bdbf72c056b17dfc0641f0bdb08241fd4cfb72d2204202a586f7da758c5"},"taxa":[{"id":"CWE-532","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":"dbf266212a67d2cd7ff6b44beb7d3e28734b7236871ae60f3639635256f885e0"},"taxa":[{"id":"CWE-532","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":"f4176d34d32493b0456688cadcb133105dafbb11e363d8d2f8b1f2f75f5278fc"},"taxa":[{"id":"CWE-532","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":"5eb1145f6a1bec278fda519be1659f5fc4a8e261cdb321819214de8d2c24b888"},"taxa":[{"id":"CWE-327","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"warning","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"e33e204e8b0b294fe15bf982d3a573b6825928f044dd9a349c93ffdb0e24227a"},"taxa":[{"id":"CWE-327","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"warning","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"0d7a7302dcbc3553901d3cbe1ba3ae8cac80ec5028ad5ad8697b7b2caf1c155e"},"taxa":[{"id":"CWE-611","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":"4bea9ab49857ae7ba8beccbde868770b8444a919e376ec1c493500cbbdb55049"},"taxa":[{"id":"CWE-345","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":"74baee0cbcc60252168ee2a2926fd83b3c324b2256ff5f8fc9b0976714376af8"},"taxa":[{"id":"CWE-79","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"note","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"4b2dde9537b872c22f5b0b91c062cb6b82c8a8cc8bb2011ada8e1292d822036c"},"taxa":[{"id":"CWE-78","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"note","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"ae0093853fa313045bedbac69242e434c15fcc6de218c15ec1b573ecb5966cfc"},"taxa":[{"id":"CWE-78","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"note","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"b269ab235fbeb119f0b3d84cfa9f27dc7932df3b4610ffc1f676e64209f23b04"},"taxa":[{"id":"CWE-939","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D30","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":"9270c40cdcfd1c2748c8d3ff2cf9ffce1697f6319327989f2d219886b9601122"}},{"ruleId":"D30","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":"fd6472e19afdc9d1c2b413fe26fd5e9c7f94a758d833176d68625aa4f80e4717"}},{"ruleId":"D30","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":"c07d204b0abaa2c3a7320d51b0a67b20e1304b4417191cf39e05f3e4375607b2"}},{"ruleId":"D30","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":"15e329f54af97758efcc72d6fb71f5e127ca9231448de11e856766d8071f8efc"}},{"ruleId":"D30","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":"708f6a48d01a6f468be42d516055b68cb6dd4dfdf87ff5f63e21327e1a6f90f7"}},{"ruleId":"D30","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":"db55fb0c8d2f7ecff91650b223bc3196d7585fb75f89a6a2f7a1085eed484f1c"}},{"ruleId":"D30","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":"508e48b28e9902e302401ff684557bf0ad380be7f6cb8ddc322c87d9790c8769"}},{"ruleId":"D30","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":"0396d6c1e36171aaf5c8d76046c54d4b05599530398e7b8e31d2519469b3ccd9"}},{"ruleId":"D30","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":"01a9ee3e35d08358071cd7f4dae1024ea3fb9867688e195f6aad07c6c3c5acfc"}},{"ruleId":"D30","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":"1b02b5f3f621ff293cdedcbb742a1d53c808a37350128de807a79a5d634e074f"}},{"ruleId":"D30","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":"a5a5ced154da577c5846c32e0e5fa73d6a8b81450d33131a4492e7acd67c1acc"}},{"ruleId":"D30","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":"5aa23549012e08aa669d2e565009c34600e5a9d0fac092782a6592a8518118f5"}},{"ruleId":"D30","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":"ebec4175db8792a18ea82ca59c96946ab132063b09431bb659ac041e63f70385"}},{"ruleId":"D30","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":"a4adcde6af53c5d0faeb40dc9223ead008fda42df32d62901e1dd5fe683a1a4a"}},{"ruleId":"D30","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":"cee650b43694559dfd4e31b96bca272db8b54210714572a4c947d0688b61c544"}},{"ruleId":"D30","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":"33531b2381590c7270d3d8b45a7d05c39965b63fef7f790f92067f5daf01d2cf"}},{"ruleId":"D30","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":"065590a3e1bce63d5275648cbdb5ef9a180b370a7f70ab098ed46ae5e9d601bf"}},{"ruleId":"D30","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":"33ba53554d9e65a768873f772513f12ee517f7cf1f62027f24f88be26dd3cc30"}},{"ruleId":"D30","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":"5f99dbf4b34cf49a77822a22b9e5755b8591081c79824305fa9423d3f48c964d"}},{"ruleId":"D30","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":"e5faa250af9706aed35103694097da0a0f4d33f9ac25716442820a4c6441e6c3"}},{"ruleId":"D30","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":"245d96d193093d492473be922ca0fbe41e67201750a978ff7d2df5f2eb723e3f"}},{"ruleId":"D30","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":"a3ccc17392dfc302bbfd4e616c85bc7136b38d1290e7a27bffac7725dbbce170"}},{"ruleId":"D30","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":"ce020ecb9b690ef7c9fa40b0116e6ac369150644ca34e92d74a380b0fe3fa6f7"}},{"ruleId":"D30","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":"4c5fdef6affc5c87e71d90419536617e9e9cbaddbccf12b22c697321de898ac5"}},{"ruleId":"D30","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":"fe3703b8022b69ba0a7baabcf86384ad0decb7900f7e3bf40ec6fa839a6112fb"}},{"ruleId":"D35","level":"warning","message":{"text":"Change coupling: ThreeColumnLayout.tsx \u2194 useExclusiveOverlay.ts: \u0060desktop/src/components/layout/ThreeColumnLayout.tsx\u0060 and \u0060desktop/src/components/layout/useExclusiveOverlay.ts\u0060 change together 80% of the time (8 of the 10 commits that touched whichever of the two files changed less often, counting a file under its earlier names as well \u2014 a repo-wide or module-wide sweep is evidence about the sweep rather than about any pair inside it and is left out of BOTH sides of this ratio, while a dependency bump, a formatter/rename sweep, or a commit whose edit to one of the two files was a tool directive such as //go:generate or whitespace only is left out of the shared count ONLY, so the two sides are not taken over identical commit sets) with no explicit dependency between them. They sit in the same directory, but in this ecosystem each file is its own module \u2014 a sibling reference still needs an import \u2014 so the missing import edge is real: the coupling runs through shared behaviour, not a declared dependency. If they duplicate structure, extract the common part into one unit; otherwise the coupling is hidden and worth breaking. You can check this without leaving the row: of the 8 shared commits counted here, the most recent 3 are \u0060317e077e\u0060 Community overlay redesign \u002B nav card moves: (1) Community System\u2192Work z; \u00605daa1961\u0060 Promote Capabilities from a Settings-tab entry to a first-class user-fac; \u006030de2edf\u0060 M5: delete the legacy overlay trio \u2014 OverlayHost is now the only full\u2026 \u2014 run \u0060git show\u0060 on any of them."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/layout/ThreeColumnLayout.tsx"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"3a66c9d71e9b3c17e964cc60d306ff99d52e73a446c155f5234b0a9968fdbc73"}},{"ruleId":"D35","level":"warning","message":{"text":"Change coupling: community_api.py \u2194 CommunityOverlay.tsx: \u0060backend/routers/community_api.py\u0060 and \u0060desktop/src/components/layout/CommunityOverlay.tsx\u0060 change together 58% of the time (7 of the 12 commits that touched whichever of the two files changed less often, counting a file under its earlier names as well \u2014 a repo-wide or module-wide sweep is evidence about the sweep rather than about any pair inside it and is left out of BOTH sides of this ratio, while a dependency bump, a formatter/rename sweep, or a commit whose edit to one of the two files was a tool directive such as //go:generate or whitespace only is left out of the shared count ONLY, so the two sides are not taken over identical commit sets) and are written in DIFFERENT LANGUAGES, so no import can join them and they cannot be co-located into one unit \u2014 they compile and ship as separate artifacts. What binds them is a CONTRACT across that boundary \u2014 an event or message name, a route, a serialised shape \u2014 that each side currently spells out on its own, which is exactly why a change to one drags the other. Declare that contract once where both sides read it (a shared schema, a generated constants file, an interface-definition file) so a change on one side fails the other\u0027s build instead of drifting silently; where the surface is too small to be worth that, name the counterpart in a comment on both sides so the next reader finds it. There is nothing here to merge. You can check this without leaving the row: of the 7 shared commits counted here, the most recent 3 are \u006096b057c3\u0060 Redesign Community overlay UI (de-box all 3 tabs, one-focus-per-tab per; \u006049c94be3\u0060 Community overlay redesign: rename tabs to Inbound/Watching/Outbound; In; \u00603acc00ab\u0060 \u4FEE GitHub_Community \u4E24\u4E2A Feed \u53EF\u89C1\u6027\u7F3A\u53E3:(1) \u5468\u62A5\u4E5F\u5199\u4E00\u4EFD\u5230 Knowledge/Reports/ \u8BA9 Feed t \u2014 run \u0060git show\u0060 on any of them."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/routers/community_api.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"a2c30f675afa9c3a41a8a7017a3f2d3e30feb491cc692c0242b7cd3467b561a0"}},{"ruleId":"D35","level":"warning","message":{"text":"Change coupling: useCanvasAutoSurface.ts \u2194 useReferencedFiles.ts: \u0060desktop/src/hooks/useCanvasAutoSurface.ts\u0060 and \u0060desktop/src/hooks/useReferencedFiles.ts\u0060 change together 54% of the time (7 of the 13 commits that touched whichever of the two files changed less often, counting a file under its earlier names as well \u2014 a repo-wide or module-wide sweep is evidence about the sweep rather than about any pair inside it and is left out of BOTH sides of this ratio, while a dependency bump, a formatter/rename sweep, or a commit whose edit to one of the two files was a tool directive such as //go:generate or whitespace only is left out of the shared count ONLY, so the two sides are not taken over identical commit sets) with no explicit dependency between them. They sit in the same directory, but in this ecosystem each file is its own module \u2014 a sibling reference still needs an import \u2014 so the missing import edge is real: the coupling runs through shared behaviour, not a declared dependency. If they duplicate structure, extract the common part into one unit; otherwise the coupling is hidden and worth breaking. You can check this without leaving the row: of the 7 shared commits counted here, the most recent 3 are \u00609f9fb8ae\u0060 REFACTOR (systemic, one-shot via strangler-fig): make the Canvas subsyst; \u00607ebdb1b1\u0060 Fix P0 Canvas tab-isolation bleed \u002B close\u2192collapse (run_26aa6caa); \u0060ba9e6842\u0060 Canvas OUTPUTS PR-review surface (run_b8ea6d5c): non-coding immediate\u2026 \u2014 run \u0060git show\u0060 on any of them."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/hooks/useCanvasAutoSurface.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"126ec02ce6f7aae7b8aa95630789bb74f41de56e0b0da372bb8db4e21884a10c"}},{"ruleId":"D36","level":"note","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"1b213f6eedd4b140d0bc37bdf1496f72811a643f34064f12518b32e9e83bcfc7"}},{"ruleId":"D36","level":"warning","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"90f83b4fa27db32740afe9540c905f3c0499caed87f61049a8a903ecc95b41c3"}},{"ruleId":"D36","level":"warning","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"0752d0df7434000fcabf1048e2de30a7a1a8b982b3db9a19898c4dec199856b4"}},{"ruleId":"D36","level":"warning","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"d068c977b62d9a977df1bb6f53e8b00b586c3abee955f91d715f92b8e019d624"}},{"ruleId":"D36","level":"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"}},{"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":"01617c8618e3c4e3878dbf35ba9ff053ccec9d7cd1ea559a8db623472c13a49c"}},{"ruleId":"D36","level":"note","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"ace515990e7ee0f17b5c17e44dd168a5bdecf90804a3a3dd845cf05540978013"}},{"ruleId":"AC1","level":"warning","message":{"text":"\u003Cvideo\u003E without a captions track: Video with no captions \u003Ctrack\u003E offers no captions. This player\u0027s source is set at runtime, so there is no caption file to author here: give the player a way to carry captions \u2014 accept a track/captions URL alongside the media and render a \u003Ctrack kind=\u0022captions\u0022\u003E when one is supplied \u2014 and capture that asset wherever the media enters the product (upload, import or generation)."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/file-viewer/renderers/VideoRenderer.tsx"},"region":{"startLine":58}}}],"partialFingerprints":{"codehealthFindingId/v1":"9ab69fe45ae52992703e94398be9af399dc85c4513c60f9b57d5d76d0bd5cbb8"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Clabel\u003E that labels no control: This \u003Clabel\u003E has no for and wraps no form control, so it names nothing: assistive tech never announces it, and clicking the caption focuses no field. Note that an id on the label is not an association \u2014 it is the TARGET of one, so a control still has to point at it. Give the label for=\u0022\u003Cthe control\u0027s id\u003E\u0022, move the control inside the label, or point the control\u0027s aria-labelledby at this label\u0027s id."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/public/brain-hub-demo.html"},"region":{"startLine":408}}}],"partialFingerprints":{"codehealthFindingId/v1":"4f7301ac0a434bb772ecdcce3c8411c92cd01d49e4affe0333da2335b414a1f2"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Cinput\u003E without a programmatic label: This control has only a placeholder \u2014 a placeholder is not a label (it vanishes on input and many AT ignore it). Add a \u003Clabel for\u003E, a wrapping \u003Clabel\u003E, or aria-label."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/public/brain-hub-demo.html"},"region":{"startLine":408}}}],"partialFingerprints":{"codehealthFindingId/v1":"e70658de76c481ef9bb9ee9aacb89ab7cd09583bd03479d8a7734705c4287f63"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Clabel\u003E that labels no control: This \u003Clabel\u003E has no for and wraps no form control, so it names nothing: assistive tech never announces it, and clicking the caption focuses no field. Note that an id on the label is not an association \u2014 it is the TARGET of one, so a control still has to point at it. Give the label for=\u0022\u003Cthe control\u0027s id\u003E\u0022, move the control inside the label, or point the control\u0027s aria-labelledby at this label\u0027s id."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/public/brain-hub-demo.html"},"region":{"startLine":409}}}],"partialFingerprints":{"codehealthFindingId/v1":"40f25dae59e8812a7868b99fc64ba02ef29e66ccccc5f61445fed86b2c51ec32"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Cinput\u003E without a programmatic label: This control has only a placeholder \u2014 a placeholder is not a label (it vanishes on input and many AT ignore it). Add a \u003Clabel for\u003E, a wrapping \u003Clabel\u003E, or aria-label."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/public/brain-hub-demo.html"},"region":{"startLine":409}}}],"partialFingerprints":{"codehealthFindingId/v1":"4b72226362bace88bd640d3ea41393b0a51300ae3f620afceaf7e459c5c76e6c"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Clabel\u003E that labels no control: This \u003Clabel\u003E has no for and wraps no form control, so it names nothing: assistive tech never announces it, and clicking the caption focuses no field. Note that an id on the label is not an association \u2014 it is the TARGET of one, so a control still has to point at it. Give the label for=\u0022\u003Cthe control\u0027s id\u003E\u0022, move the control inside the label, or point the control\u0027s aria-labelledby at this label\u0027s id."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/public/brain-hub-demo.html"},"region":{"startLine":410}}}],"partialFingerprints":{"codehealthFindingId/v1":"9ebf97a9c918741537545caad4f105960a17124683c79404daf4bb1fecff96c5"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Clabel\u003E that labels no control: This \u003Clabel\u003E has no for and wraps no form control, so it names nothing: assistive tech never announces it, and clicking the caption focuses no field. Note that an id on the label is not an association \u2014 it is the TARGET of one, so a control still has to point at it. Give the label for=\u0022\u003Cthe control\u0027s id\u003E\u0022, move the control inside the label, or point the control\u0027s aria-labelledby at this label\u0027s id."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/public/brain-hub-demo.html"},"region":{"startLine":420}}}],"partialFingerprints":{"codehealthFindingId/v1":"e0b75587bd06cb059d0673f293b4ab22de95b60271db02d8e7e710204bdd00ec"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Clabel\u003E that labels no control: This \u003Clabel\u003E has no for and wraps no form control, so it names nothing: assistive tech never announces it, and clicking the caption focuses no field. Note that an id on the label is not an association \u2014 it is the TARGET of one, so a control still has to point at it. Give the label for=\u0022\u003Cthe control\u0027s id\u003E\u0022, move the control inside the label, or point the control\u0027s aria-labelledby at this label\u0027s id."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/public/brain-hub-demo.html"},"region":{"startLine":430}}}],"partialFingerprints":{"codehealthFindingId/v1":"61d2c2b81c4eb9b9d747c6c7e230cd4981888a9f091ada910610b7cce0a1e658"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Clabel\u003E that labels no control: This \u003Clabel\u003E has no htmlFor and wraps no form control, so it names nothing: assistive tech never announces it, and clicking the caption focuses no field. Note that an id on the label is not an association \u2014 it is the TARGET of one, so a control still has to point at it. Give the label htmlFor=\u0022\u003Cthe control\u0027s id\u003E\u0022, move the control inside the label, or point the control\u0027s aria-labelledby at this label\u0027s id."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/common/AgentFormModal.tsx"},"region":{"startLine":213}}}],"partialFingerprints":{"codehealthFindingId/v1":"fe85aadf763fc5fbf1b0e559cbc06bdce70dcdaa6734ba7cc42235f59736f765"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Cinput\u003E without a programmatic label: This control has only a placeholder \u2014 a placeholder is not a label (it vanishes on input and many AT ignore it). Add a \u003Clabel htmlFor\u003E, a wrapping \u003Clabel\u003E, or aria-label."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/common/AgentFormModal.tsx"},"region":{"startLine":214}}}],"partialFingerprints":{"codehealthFindingId/v1":"c38d3837f7a2f10ae5580eea04bd0caa368c1f96b757c24d5fec2799a315a21c"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Clabel\u003E that labels no control: This \u003Clabel\u003E has no htmlFor and wraps no form control, so it names nothing: assistive tech never announces it, and clicking the caption focuses no field. Note that an id on the label is not an association \u2014 it is the TARGET of one, so a control still has to point at it. Give the label htmlFor=\u0022\u003Cthe control\u0027s id\u003E\u0022, move the control inside the label, or point the control\u0027s aria-labelledby at this label\u0027s id."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/common/AgentFormModal.tsx"},"region":{"startLine":237}}}],"partialFingerprints":{"codehealthFindingId/v1":"8c1f241aec4282179bab5e3a254bede7c0f5ddfdd7680ba2ee2038cd197339f6"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Cinput\u003E without a programmatic label: This control has only a placeholder \u2014 a placeholder is not a label (it vanishes on input and many AT ignore it). Add a \u003Clabel htmlFor\u003E, a wrapping \u003Clabel\u003E, or aria-label."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/common/AgentFormModal.tsx"},"region":{"startLine":238}}}],"partialFingerprints":{"codehealthFindingId/v1":"108767738c7a9e1374ea6504bf7d8cb967e9239381cb62799990c81af66af1a5"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Clabel\u003E that labels no control: This \u003Clabel\u003E has no htmlFor and wraps no form control, so it names nothing: assistive tech never announces it, and clicking the caption focuses no field. Note that an id on the label is not an association \u2014 it is the TARGET of one, so a control still has to point at it. Give the label htmlFor=\u0022\u003Cthe control\u0027s id\u003E\u0022, move the control inside the label, or point the control\u0027s aria-labelledby at this label\u0027s id."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/common/AgentFormModal.tsx"},"region":{"startLine":249}}}],"partialFingerprints":{"codehealthFindingId/v1":"ea380bf4afbd6bca648ba7534819033c4466c12619efb708b4629cc1919ac0fa"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Ctextarea\u003E without a programmatic label: This control has only a placeholder \u2014 a placeholder is not a label (it vanishes on input and many AT ignore it). Add a \u003Clabel htmlFor\u003E, a wrapping \u003Clabel\u003E, or aria-label."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/common/AgentFormModal.tsx"},"region":{"startLine":250}}}],"partialFingerprints":{"codehealthFindingId/v1":"f1ea6165f9708446c16e96d7329e61cef269965b72a7e8ed9141d531bea55b35"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Clabel\u003E that labels no control: This \u003Clabel\u003E has no htmlFor and wraps no form control, so it names nothing: assistive tech never announces it, and clicking the caption focuses no field. Note that an id on the label is not an association \u2014 it is the TARGET of one, so a control still has to point at it. Give the label htmlFor=\u0022\u003Cthe control\u0027s id\u003E\u0022, move the control inside the label, or point the control\u0027s aria-labelledby at this label\u0027s id."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/common/AgentFormModal.tsx"},"region":{"startLine":262}}}],"partialFingerprints":{"codehealthFindingId/v1":"1246449f567737b6d0f8cb32f6e88ee59ee840ce9e89000bfa6bc9dc783f5de3"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Cbutton\u003E with no accessible text: A button with no text and no aria-label has no accessible name. Add visible text or an aria-label (an icon-only button still needs one)."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/common/AgentFormModal.tsx"},"region":{"startLine":265}}}],"partialFingerprints":{"codehealthFindingId/v1":"a12fc625350bdd4288bd5fbfe69ed9fd827ee344a6dab0b61a61bb51dc80afb9"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Clabel\u003E that labels no control: This \u003Clabel\u003E has no htmlFor and wraps no form control, so it names nothing: assistive tech never announces it, and clicking the caption focuses no field. Note that an id on the label is not an association \u2014 it is the TARGET of one, so a control still has to point at it. Give the label htmlFor=\u0022\u003Cthe control\u0027s id\u003E\u0022, move the control inside the label, or point the control\u0027s aria-labelledby at this label\u0027s id."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/common/AgentFormModal.tsx"},"region":{"startLine":285}}}],"partialFingerprints":{"codehealthFindingId/v1":"48128c4959f302c6211da9e37810f236bb9c504c5f88107fd5be5c170f998ee8"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Cbutton\u003E with no accessible text: A button with no text and no aria-label has no accessible name. Add visible text or an aria-label (an icon-only button still needs one)."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/common/AgentFormModal.tsx"},"region":{"startLine":288}}}],"partialFingerprints":{"codehealthFindingId/v1":"bdbcb127aacc32b98381ca95cfb1983292971108c3485a030cd64f83bcc4965f"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Clabel\u003E that labels no control: This \u003Clabel\u003E has no htmlFor and wraps no form control, so it names nothing: assistive tech never announces it, and clicking the caption focuses no field. Note that an id on the label is not an association \u2014 it is the TARGET of one, so a control still has to point at it. Give the label htmlFor=\u0022\u003Cthe control\u0027s id\u003E\u0022, move the control inside the label, or point the control\u0027s aria-labelledby at this label\u0027s id."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/common/AgentFormModal.tsx"},"region":{"startLine":344}}}],"partialFingerprints":{"codehealthFindingId/v1":"644d2cd0c6cf6bfc081c474cc199a9fd1ded96eb065df386becbed88bff4f3bb"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Cbutton\u003E with no accessible text: A button with no text and no aria-label has no accessible name. Add visible text or an aria-label (an icon-only button still needs one)."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/common/AgentFormModal.tsx"},"region":{"startLine":351}}}],"partialFingerprints":{"codehealthFindingId/v1":"17a148e784257f53f7a85371ba06d7ea55a9cf6f0b43a749dda16f685fb9f08e"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Cinput\u003E without a programmatic label: This control has only a placeholder \u2014 a placeholder is not a label (it vanishes on input and many AT ignore it). Add a \u003Clabel htmlFor\u003E, a wrapping \u003Clabel\u003E, or aria-label."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/common/AskUserQuestion.tsx"},"region":{"startLine":241}}}],"partialFingerprints":{"codehealthFindingId/v1":"7b337ca2a507265c9a2c10d4646e02f49bd539378b603621e061097ecfd0b64e"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Ctextarea\u003E without a programmatic label: This control has only a placeholder \u2014 a placeholder is not a label (it vanishes on input and many AT ignore it). Add a \u003Clabel htmlFor\u003E, a wrapping \u003Clabel\u003E, or aria-label."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/common/CommentPopover.tsx"},"region":{"startLine":143}}}],"partialFingerprints":{"codehealthFindingId/v1":"f9164eb32a9b73118d34a1e68840304718cdea70f62fc39c447494ca954c9a3f"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Clabel\u003E that labels no control: This \u003Clabel\u003E has no htmlFor and wraps no form control, so it names nothing: assistive tech never announces it, and clicking the caption focuses no field. Note that an id on the label is not an association \u2014 it is the TARGET of one, so a control still has to point at it. Give the label htmlFor=\u0022\u003Cthe control\u0027s id\u003E\u0022, move the control inside the label, or point the control\u0027s aria-labelledby at this label\u0027s id."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/common/Dropdown.tsx"},"region":{"startLine":70}}}],"partialFingerprints":{"codehealthFindingId/v1":"336ede4516774d602935d20cd804311872712d7b9014bd62aff72a2a1ec6055b"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Cinput\u003E without a programmatic label: This control has only a placeholder \u2014 a placeholder is not a label (it vanishes on input and many AT ignore it). Add a \u003Clabel htmlFor\u003E, a wrapping \u003Clabel\u003E, or aria-label."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/common/Dropdown.tsx"},"region":{"startLine":115}}}],"partialFingerprints":{"codehealthFindingId/v1":"fde2d0ed703020177abcca0eb0bac701fa6bdafebdc5dc2d5fe29b5a09651a1c"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Ctextarea\u003E without a programmatic label: This control has only a placeholder \u2014 a placeholder is not a label (it vanishes on input and many AT ignore it). Add a \u003Clabel htmlFor\u003E, a wrapping \u003Clabel\u003E, or aria-label."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/common/FileEditorCore.tsx"},"region":{"startLine":317}}}],"partialFingerprints":{"codehealthFindingId/v1":"1cb384484ffac4b068d7f6baad966397b9f5cb743f6267f42412d074d74c9e1e"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Cinput\u003E without a programmatic label: This control has only a placeholder \u2014 a placeholder is not a label (it vanishes on input and many AT ignore it). Add a \u003Clabel htmlFor\u003E, a wrapping \u003Clabel\u003E, or aria-label."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/common/FileEditorCore.tsx"},"region":{"startLine":562}}}],"partialFingerprints":{"codehealthFindingId/v1":"9a1e3394c329e5a5d6d9175c56649b8124a5c548aa8f01812c08ae5e73937c59"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Ctextarea\u003E without a programmatic label: This control has no associated label. Add a \u003Clabel htmlFor\u003E / wrapping \u003Clabel\u003E / aria-label / aria-labelledby so assistive tech can name it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/common/FileEditorCore.tsx"},"region":{"startLine":1853}}}],"partialFingerprints":{"codehealthFindingId/v1":"4082af1d59f1562b9b58097ef577571270fc3337463ffe052f4b986b7cbd1d56"}},{"ruleId":"AC2","level":"error","message":{"text":"Custom control with no accessible name on \u003Cdiv\u003E: This \u003Cdiv\u003E carries a click handler, which makes it a control, but it has no text, aria-label or labelled child (the icon-only case), so assistive tech has no name to announce for it. Note that switching it to \u003Cbutton type=\u0022button\u0022\u003E \u2014 the right fix for its keyboard operability \u2014 does not give it a name either: an icon-only button still needs one. Add visible text or an aria-label."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/common/MarkdownRenderer.tsx"},"region":{"startLine":215}}}],"partialFingerprints":{"codehealthFindingId/v1":"1ced952cea4c5dbb1eec5d354d628e4a870bd3a57463250a51a3cac0167871b7"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Cinput\u003E without a programmatic label: This control has no associated label. Add a \u003Clabel htmlFor\u003E / wrapping \u003Clabel\u003E / aria-label / aria-labelledby so assistive tech can name it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/common/MarkdownRenderer.tsx"},"region":{"startLine":870}}}],"partialFingerprints":{"codehealthFindingId/v1":"da76e88699fbb838eb9de1eccc0bcbfc19ef904925df1f258189bd9078ea2d6d"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Clabel\u003E that labels no control: This \u003Clabel\u003E has no htmlFor and wraps no form control, so it names nothing: assistive tech never announces it, and clicking the caption focuses no field. Note that an id on the label is not an association \u2014 it is the TARGET of one, so a control still has to point at it. Give the label htmlFor=\u0022\u003Cthe control\u0027s id\u003E\u0022, move the control inside the label, or point the control\u0027s aria-labelledby at this label\u0027s id."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/common/MultiSelect.tsx"},"region":{"startLine":91}}}],"partialFingerprints":{"codehealthFindingId/v1":"1ca0c7b9243abc09f51af9dfd394eedc1dad742c487cc6988d968e6c4b3e1e22"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Cinput\u003E without a programmatic label: This control has only a placeholder \u2014 a placeholder is not a label (it vanishes on input and many AT ignore it). Add a \u003Clabel htmlFor\u003E, a wrapping \u003Clabel\u003E, or aria-label."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/common/MultiSelect.tsx"},"region":{"startLine":150}}}],"partialFingerprints":{"codehealthFindingId/v1":"b27618a3b19d4f79644508c7ae58d53553dc818555bac34bf888e50e602d11b2"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Cinput\u003E without a programmatic label: This control has only a placeholder \u2014 a placeholder is not a label (it vanishes on input and many AT ignore it). Add a \u003Clabel htmlFor\u003E, a wrapping \u003Clabel\u003E, or aria-label."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/common/SearchBar.tsx"},"region":{"startLine":21}}}],"partialFingerprints":{"codehealthFindingId/v1":"6893918b2f4c87b8eafab8d901ec7320632bd45885f5851bb8ad46bcd056c5a1"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Clabel\u003E that labels no control: This \u003Clabel\u003E has no htmlFor and wraps no form control, so it names nothing: assistive tech never announces it, and clicking the caption focuses no field. Note that an id on the label is not an association \u2014 it is the TARGET of one, so a control still has to point at it. Give the label htmlFor=\u0022\u003Cthe control\u0027s id\u003E\u0022, move the control inside the label, or point the control\u0027s aria-labelledby at this label\u0027s id."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/common/ToolSelector.tsx"},"region":{"startLine":161}}}],"partialFingerprints":{"codehealthFindingId/v1":"7f6f059b1d720aa3ebe51b082565c4b9a943ec70268bc332d7dff1fcb23ee65b"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Cbutton\u003E with no accessible text: A button with no text and no aria-label has no accessible name. Add visible text or an aria-label (an icon-only button still needs one)."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/common/ToolSelector.tsx"},"region":{"startLine":193}}}],"partialFingerprints":{"codehealthFindingId/v1":"6fa65530c20d9abaaab1a639c3abc35f237750ef4def84c3b152a280c1c657ab"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Cbutton\u003E with no accessible text: A button with no text and no aria-label has no accessible name. Add visible text or an aria-label (an icon-only button still needs one)."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/common/ToolSelector.tsx"},"region":{"startLine":241}}}],"partialFingerprints":{"codehealthFindingId/v1":"005e96107ece041d207dbf626b127230a82a67b76efc1fb6d34134b3297f45fe"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Cselect\u003E without a programmatic label: This control has no associated label. Add a \u003Clabel htmlFor\u003E / wrapping \u003Clabel\u003E / aria-label / aria-labelledby so assistive tech can name it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/layout/BrainHub.tsx"},"region":{"startLine":233}}}],"partialFingerprints":{"codehealthFindingId/v1":"8553adb594b967bcf9357c5719e5d6cfe899ef6d547573266157c291f5e36786"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Cinput\u003E without a programmatic label: This control has only a placeholder \u2014 a placeholder is not a label (it vanishes on input and many AT ignore it). Add a \u003Clabel htmlFor\u003E, a wrapping \u003Clabel\u003E, or aria-label."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/layout/BrainHub.tsx"},"region":{"startLine":348}}}],"partialFingerprints":{"codehealthFindingId/v1":"53611c169bffb9c98f374136354e4a3c8322d131cb92993fca928787ddcba33f"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Cinput\u003E without a programmatic label: This control has only a placeholder \u2014 a placeholder is not a label (it vanishes on input and many AT ignore it). Add a \u003Clabel htmlFor\u003E, a wrapping \u003Clabel\u003E, or aria-label."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/layout/CMBrainOverlay.tsx"},"region":{"startLine":808}}}],"partialFingerprints":{"codehealthFindingId/v1":"7d8dc1aa905987e30badad316cf8dec87d0c3476368239514cfffd4fb00e82cc"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Cselect\u003E without a programmatic label: This control has no associated label. Add a \u003Clabel htmlFor\u003E / wrapping \u003Clabel\u003E / aria-label / aria-labelledby so assistive tech can name it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/layout/CommunityOverlay.tsx"},"region":{"startLine":453}}}],"partialFingerprints":{"codehealthFindingId/v1":"59b94ce39b75882f05eefe9e512d5834da8fbf10895d0e8c679a148bc0fa04c9"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Cinput\u003E without a programmatic label: This control has only a placeholder \u2014 a placeholder is not a label (it vanishes on input and many AT ignore it). Add a \u003Clabel htmlFor\u003E, a wrapping \u003Clabel\u003E, or aria-label."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/layout/CommunityOverlay.tsx"},"region":{"startLine":591}}}],"partialFingerprints":{"codehealthFindingId/v1":"987797d3c8eb6bfd28683c23db58e94292a6fc82ead4ad7841ce30db2e876ea3"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Cinput\u003E without a programmatic label: This control has only a placeholder \u2014 a placeholder is not a label (it vanishes on input and many AT ignore it). Add a \u003Clabel htmlFor\u003E, a wrapping \u003Clabel\u003E, or aria-label."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/layout/CommunityOverlay.tsx"},"region":{"startLine":656}}}],"partialFingerprints":{"codehealthFindingId/v1":"6072f279bbe1cb88a61cc3fcd3bc1c0deb48be30c05c2b8c4852ea9cef2949a1"}},{"ruleId":"AC3","level":"error","message":{"text":"Document without a \u003Ctitle\u003E: A page with no \u003Ctitle\u003E gives no name in the tab, history or screen-reader page list. Add a descriptive \u003Ctitle\u003E in \u003Chead\u003E."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"assets/SwarmAI-Architecture-Design-Doc.html"},"region":{"startLine":2}}}],"partialFingerprints":{"codehealthFindingId/v1":"91de04dcda8d435eb7ce7de95787484482bbdf715563e3492a8aa1a34db1698e"}},{"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":"assets/SwarmAI-Architecture-Design-Doc.html"},"region":{"startLine":2}}}],"partialFingerprints":{"codehealthFindingId/v1":"8ab7db93c52c77eca3c7461f8320d46bb824b8be7b7b1ae4b51ee6e77bf7a7a4"}},{"ruleId":"AC3","level":"warning","message":{"text":"Heading level jumps from h2 to h4: Skipping heading levels breaks the document outline assistive tech relies on. Don\u0027t jump levels \u2014 increase by at most one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"assets/SwarmAI-Architecture-Design-Doc.html"},"region":{"startLine":2896}}}],"partialFingerprints":{"codehealthFindingId/v1":"c5192f0e3eae0fa0399a4645594f252efc85f0a444dfa0c7a841a2473423ef86"}},{"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":"backend/skills/s_html-artifact/templates/code-review.html"},"region":{"startLine":2}}}],"partialFingerprints":{"codehealthFindingId/v1":"c30792276501c09e3e2860a4b2b3b0756b221e313ec90e3426197fff176c3bd5"}},{"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":"backend/skills/s_html-artifact/templates/comparison.html"},"region":{"startLine":2}}}],"partialFingerprints":{"codehealthFindingId/v1":"014288f997a9f60384cfbdc6ad39220c87e765e254e7d9760f93d3e8b2f2ce76"}},{"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":"backend/skills/s_html-artifact/templates/report.html"},"region":{"startLine":2}}}],"partialFingerprints":{"codehealthFindingId/v1":"b358e87b7efe7ce36c21e044ace3c7a1169c09448925d15bbad3f65ffdec3b43"}},{"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":"backend/skills/s_html-artifact/templates/scorecard.html"},"region":{"startLine":2}}}],"partialFingerprints":{"codehealthFindingId/v1":"3af05ef9f8b9e664878e5eee3b5365d9f7ccc189ab68a8bc5ad7cc86bb2190b3"}},{"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":"desktop/public/brain-hub-demo.html"},"region":{"startLine":2}}}],"partialFingerprints":{"codehealthFindingId/v1":"c2fe536c16e0d58aa0a6d578d0242fe905a24c43e7c5b5dc9319f11aed8b77c7"}},{"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":"desktop/src/components/layout/BottomBar.tsx"},"region":{"startLine":41}}}],"partialFingerprints":{"codehealthFindingId/v1":"0cee7dd5433c1957122585ef3fd401914c8391a56774023e19601198f9312740"}},{"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":"desktop/src/pages/EvalDashboard.tsx"},"region":{"startLine":624}}}],"partialFingerprints":{"codehealthFindingId/v1":"24027de1a5a0110337d02d50afaf37425615da8f18e87d52ba6d419df9cbee69"}},{"ruleId":"AC4","level":"error","message":{"text":"Click handler on a non-interactive \u003Cdiv\u003E: A click handler on a plain element isn\u0027t keyboard-operable. Use a \u003Cbutton\u003E, or add role \u002B tabindex=\u00220\u0022 \u002B a key handler."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/public/brain-hub-demo.html"},"region":{"startLine":270}}}],"partialFingerprints":{"codehealthFindingId/v1":"c41910e68433383eee83914c0d84ec58bb838f23d37a819cbd5000e6e47b8b93"}},{"ruleId":"AC4","level":"error","message":{"text":"Click handler on a non-interactive \u003Cdiv\u003E: A click handler on a plain element isn\u0027t keyboard-operable. Use a \u003Cbutton\u003E, or add role \u002B tabindex=\u00220\u0022 \u002B a key handler."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/public/brain-hub-demo.html"},"region":{"startLine":278}}}],"partialFingerprints":{"codehealthFindingId/v1":"8087d924222ca1822859354cdfa36a0c0142f2e0a098e3ae5740b815d6831fd7"}},{"ruleId":"AC4","level":"error","message":{"text":"Click handler on a non-interactive \u003Cdiv\u003E: A click handler on a plain element isn\u0027t keyboard-operable. Use a \u003Cbutton\u003E, or add role \u002B tabindex=\u00220\u0022 \u002B a key handler."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/public/brain-hub-demo.html"},"region":{"startLine":287}}}],"partialFingerprints":{"codehealthFindingId/v1":"cc9eca64566ded587d74b3d341e6767b4cd6d8afb45afb262898d997d04d1a8b"}},{"ruleId":"AC4","level":"error","message":{"text":"Click handler on a non-interactive \u003Cdiv\u003E: A click handler on a plain element isn\u0027t keyboard-operable. Use a \u003Cbutton\u003E, or add role \u002B tabindex=\u00220\u0022 \u002B a key handler."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/public/brain-hub-demo.html"},"region":{"startLine":308}}}],"partialFingerprints":{"codehealthFindingId/v1":"e689644f21016b5bef42471feaa4245b4bff1a8198c9398092b997748547c228"}},{"ruleId":"AC4","level":"error","message":{"text":"Click handler on a non-interactive \u003Cdiv\u003E: A click handler on a plain element isn\u0027t keyboard-operable. Use a \u003Cbutton\u003E, or add role \u002B tabindex=\u00220\u0022 \u002B a key handler."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/public/brain-hub-demo.html"},"region":{"startLine":309}}}],"partialFingerprints":{"codehealthFindingId/v1":"1f8909d4337469555d8e8b7ad5750ee34d4568aa78650b7ce17ad148852e2f90"}},{"ruleId":"AC4","level":"error","message":{"text":"Click handler on a non-interactive \u003Cdiv\u003E: A click handler on a plain element isn\u0027t keyboard-operable. Use a \u003Cbutton\u003E, or add role \u002B tabindex=\u00220\u0022 \u002B a key handler."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/public/brain-hub-demo.html"},"region":{"startLine":312}}}],"partialFingerprints":{"codehealthFindingId/v1":"176ceaf0ad96645900db3ad679ac2385a980cb8cdd108f7688f52fb34fa5c2bd"}},{"ruleId":"AC4","level":"error","message":{"text":"Click handler on a non-interactive \u003Cdiv\u003E: A click handler on a plain element isn\u0027t keyboard-operable. Use a \u003Cbutton\u003E, or add role \u002B tabindex=\u00220\u0022 \u002B a key handler."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/public/brain-hub-demo.html"},"region":{"startLine":313}}}],"partialFingerprints":{"codehealthFindingId/v1":"e29b7ec53b139e82ed22a6225dea1b96f1c99a797e62d84a048774cbc2acb216"}},{"ruleId":"AC4","level":"error","message":{"text":"Click handler on a non-interactive \u003Cdiv\u003E: A click handler on a plain element isn\u0027t keyboard-operable. Use a \u003Cbutton\u003E, or add role \u002B tabindex=\u00220\u0022 \u002B a key handler."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/public/brain-hub-demo.html"},"region":{"startLine":314}}}],"partialFingerprints":{"codehealthFindingId/v1":"2c41e155a394c9959157b1a1d3823a212fe33394a01e40bf97a439151e43c555"}},{"ruleId":"AC4","level":"error","message":{"text":"Click handler on a non-interactive \u003Cdiv\u003E: A click handler on a plain element isn\u0027t keyboard-operable. Use a \u003Cbutton\u003E, or add role \u002B tabindex=\u00220\u0022 \u002B a key handler."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/public/brain-hub-demo.html"},"region":{"startLine":315}}}],"partialFingerprints":{"codehealthFindingId/v1":"5cfc82013854fb75b5fb546a9065391d138be42c76c88f413a9b5ad06ac41d9f"}},{"ruleId":"AC4","level":"error","message":{"text":"Click handler on a non-interactive \u003Cdiv\u003E: A click handler on a plain element isn\u0027t keyboard-operable. Use a \u003Cbutton\u003E, or add role \u002B tabindex=\u00220\u0022 \u002B a key handler."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/public/brain-hub-demo.html"},"region":{"startLine":316}}}],"partialFingerprints":{"codehealthFindingId/v1":"3bae8d909ff134458f57626a25ee3948d009781bb2e85a4683b5d2ae3d0d6eef"}},{"ruleId":"AC4","level":"error","message":{"text":"Click handler on a non-interactive \u003Cdiv\u003E: A click handler on a plain element isn\u0027t keyboard-operable. Use a \u003Cbutton\u003E, or add role \u002B tabindex=\u00220\u0022 \u002B a key handler."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/public/brain-hub-demo.html"},"region":{"startLine":322}}}],"partialFingerprints":{"codehealthFindingId/v1":"ae87ea86a7e41c0cc2feb00e8daa480dda6ca2d15101be603d4872f3401ec597"}},{"ruleId":"AC4","level":"error","message":{"text":"Click handler on a non-interactive \u003Cdiv\u003E: A click handler on a plain element isn\u0027t keyboard-operable. Use a \u003Cbutton\u003E, or add role \u002B tabindex=\u00220\u0022 \u002B a key handler."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/public/brain-hub-demo.html"},"region":{"startLine":323}}}],"partialFingerprints":{"codehealthFindingId/v1":"0d9c2fe611b309635c418aac9d44f92c3037a4daef1e96c0ba5cac3b5078a9c4"}},{"ruleId":"AC4","level":"error","message":{"text":"Click handler on a non-interactive \u003Cdiv\u003E: A click handler on a plain element isn\u0027t keyboard-operable. Use a \u003Cbutton\u003E, or add role \u002B tabindex=\u00220\u0022 \u002B a key handler."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/public/brain-hub-demo.html"},"region":{"startLine":324}}}],"partialFingerprints":{"codehealthFindingId/v1":"878c3e12b9901d35142eaaf85153a6207a7f983a74c078c41afe544bfe81d13d"}},{"ruleId":"AC4","level":"error","message":{"text":"Click handler on a non-interactive \u003Cdiv\u003E: A click handler on a plain element isn\u0027t keyboard-operable. Use a \u003Cbutton\u003E, or add role \u002B tabindex=\u00220\u0022 \u002B a key handler."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/public/brain-hub-demo.html"},"region":{"startLine":327}}}],"partialFingerprints":{"codehealthFindingId/v1":"46cfc0e4b046f1e94b745c6303a161373128b901455f23a22d2e475b55cede8f"}},{"ruleId":"AC4","level":"error","message":{"text":"Click handler on a non-interactive \u003Cdiv\u003E: A click handler on a plain element isn\u0027t keyboard-operable. Use a \u003Cbutton\u003E, or add role \u002B tabindex=\u00220\u0022 \u002B a key handler."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/public/brain-hub-demo.html"},"region":{"startLine":330}}}],"partialFingerprints":{"codehealthFindingId/v1":"8b83f3408383cbffb0c0373b2d46fcf6289614f9d77333c793d292c68b7ed403"}},{"ruleId":"AC4","level":"error","message":{"text":"Click handler on a non-interactive \u003Cdiv\u003E: A click handler on a plain element isn\u0027t keyboard-operable. Use a \u003Cbutton\u003E, or add role \u002B tabindex=\u00220\u0022 \u002B a key handler."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/public/brain-hub-demo.html"},"region":{"startLine":331}}}],"partialFingerprints":{"codehealthFindingId/v1":"4814726937dd8a3e72f4a7ff1031e22cd4018fe73b6a5974c2b1ccbec8aaa8aa"}},{"ruleId":"AC4","level":"error","message":{"text":"Click handler on a non-interactive \u003Cspan\u003E: A click handler on a plain element isn\u0027t keyboard-operable. Use a \u003Cbutton\u003E, or add role \u002B tabindex=\u00220\u0022 \u002B a key handler."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/public/brain-hub-demo.html"},"region":{"startLine":398}}}],"partialFingerprints":{"codehealthFindingId/v1":"ae3f9984a45e437681ce2cbcde6f9f55ec0585800924bfe7307cfa9ea0257a03"}},{"ruleId":"AC4","level":"error","message":{"text":"Click handler on a non-interactive \u003Cdiv\u003E: A click handler on a plain element isn\u0027t keyboard-operable. Use a \u003Cbutton\u003E, or add role \u002B tabindex=\u00220\u0022 \u002B a key handler."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/public/brain-hub-demo.html"},"region":{"startLine":423}}}],"partialFingerprints":{"codehealthFindingId/v1":"27b044ccdf2b40a73829ae68e7d24534071b74d3e39c18326b72f250854dfb20"}},{"ruleId":"AC4","level":"error","message":{"text":"Click handler on a non-interactive \u003Cdiv\u003E: A click handler on a plain element isn\u0027t keyboard-operable. Use a \u003Cbutton\u003E, or add role \u002B tabindex=\u00220\u0022 \u002B a key handler."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/public/brain-hub-demo.html"},"region":{"startLine":424}}}],"partialFingerprints":{"codehealthFindingId/v1":"ab787e0e13adc30b737ef72c104467eb6419e5b81f0cc56fe4c83a9223e11f5d"}},{"ruleId":"AC4","level":"error","message":{"text":"Click handler on a non-interactive \u003Cdiv\u003E: A click handler on a plain element isn\u0027t keyboard-operable. Use a \u003Cbutton\u003E, or add role \u002B tabindex=\u00220\u0022 \u002B a key handler."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/public/brain-hub-demo.html"},"region":{"startLine":425}}}],"partialFingerprints":{"codehealthFindingId/v1":"8774dcb4fcf53c71679245e8f352284012a8bca08c5601deee5ad63aae384cc5"}},{"ruleId":"AC4","level":"error","message":{"text":"Click handler on a non-interactive \u003Cdiv\u003E: A click handler on a plain element isn\u0027t keyboard-operable. Use a \u003Cbutton\u003E, or add role \u002B tabindex=\u00220\u0022 \u002B a key handler."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/public/brain-hub-demo.html"},"region":{"startLine":426}}}],"partialFingerprints":{"codehealthFindingId/v1":"93c8bffa3fc42c2446509cf4ce0654e625fe75206bd23a2b65ce8d9f87a5de90"}},{"ruleId":"AC4","level":"error","message":{"text":"Click handler on a non-interactive \u003Cdiv\u003E: A click handler on a plain element isn\u0027t keyboard-operable. Use a \u003Cbutton\u003E, or add role \u002B tabindex=\u00220\u0022 \u002B a key handler."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/public/brain-hub-demo.html"},"region":{"startLine":427}}}],"partialFingerprints":{"codehealthFindingId/v1":"16b953e9cb834d9c16774d957703f662b13ee32c838d5664a86fdc8819f7cbad"}},{"ruleId":"AC4","level":"error","message":{"text":"Click handler on a non-interactive \u003Cspan\u003E: A click handler on a plain element isn\u0027t keyboard-operable. Use a \u003Cbutton\u003E, or add role \u002B tabindex=\u00220\u0022 \u002B a key handler."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/public/brain-hub-demo.html"},"region":{"startLine":432}}}],"partialFingerprints":{"codehealthFindingId/v1":"a615f0124b27a9f24cf612fa452c105a8af00570e7ca6840cd5f5af175ff51aa"}},{"ruleId":"AC4","level":"error","message":{"text":"Click handler on a non-interactive \u003Cspan\u003E: A click handler on a plain element isn\u0027t keyboard-operable. Use a \u003Cbutton\u003E, or add role \u002B tabindex=\u00220\u0022 \u002B a key handler."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/public/brain-hub-demo.html"},"region":{"startLine":433}}}],"partialFingerprints":{"codehealthFindingId/v1":"a2cc490bb3a22c9c8bd385707ab718f1e696920561495604276c3e725dd3d5b8"}},{"ruleId":"AC4","level":"error","message":{"text":"Click handler on a non-interactive \u003Cspan\u003E: A click handler on a plain element isn\u0027t keyboard-operable. Use a \u003Cbutton\u003E, or add role \u002B tabindex=\u00220\u0022 \u002B a key handler."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/public/brain-hub-demo.html"},"region":{"startLine":434}}}],"partialFingerprints":{"codehealthFindingId/v1":"a0798d7a9692b2f265ba042f46829b559d002682554da311c5015b43d4f1e020"}},{"ruleId":"AC4","level":"error","message":{"text":"Click handler on a non-interactive \u003Cdiv\u003E: A click handler on a plain element isn\u0027t keyboard-operable. Use a \u003Cbutton\u003E, or add role \u002B tabIndex={0} \u002B a key handler."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/chat/VoiceConversationIndicator.tsx"},"region":{"startLine":69}}}],"partialFingerprints":{"codehealthFindingId/v1":"bafaf0d9ac8ff159cdded68a0f8d9b892c7b024b657627237641218baf757354"}},{"ruleId":"AC4","level":"error","message":{"text":"Click handler on a non-interactive \u003Cdiv\u003E: A click handler on a plain element isn\u0027t keyboard-operable. Use a \u003Cbutton\u003E, or add role \u002B tabIndex={0} \u002B a key handler."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/common/Dropdown.tsx"},"region":{"startLine":73}}}],"partialFingerprints":{"codehealthFindingId/v1":"6481f991d9dd76c263d3dddef4fcf931f6ef559c9c4544435a0b569950d807fb"}},{"ruleId":"AC4","level":"error","message":{"text":"Click handler on a non-interactive \u003Cdiv\u003E: A click handler on a plain element isn\u0027t keyboard-operable. Use a \u003Cbutton\u003E, or add role \u002B tabIndex={0} \u002B a key handler."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/common/Dropdown.tsx"},"region":{"startLine":142}}}],"partialFingerprints":{"codehealthFindingId/v1":"f108882008cf444438eba2a36eaa01cc5b6b9e48364c53c76809ceded0f97cad"}},{"ruleId":"AC4","level":"error","message":{"text":"Click handler on a non-interactive \u003Cdiv\u003E: A click handler on a plain element with no role and no tabindex: even where another element\u0027s key handler can reach it, assistive tech can neither focus it nor announce what it is. Use a \u003Cbutton\u003E, or add role \u002B tabIndex={0}."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/common/MarkdownRenderer.tsx"},"region":{"startLine":215}}}],"partialFingerprints":{"codehealthFindingId/v1":"69c683e65c228aa590f1e131b09ecf95a8465b548e9145524c30ead9bdf50d78"}},{"ruleId":"AC4","level":"error","message":{"text":"Click handler on a non-interactive \u003Cdiv\u003E: A click handler on a plain element isn\u0027t keyboard-operable. Use a \u003Cbutton\u003E, or add role \u002B tabIndex={0} \u002B a key handler."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/common/MultiSelect.tsx"},"region":{"startLine":94}}}],"partialFingerprints":{"codehealthFindingId/v1":"3b8faf8baaa97491a1967ebcd78ce13df8715e52043fb2931719163008ac3800"}},{"ruleId":"AC4","level":"error","message":{"text":"Click handler on a non-interactive \u003Cdiv\u003E: A click handler on a plain element isn\u0027t keyboard-operable. Use a \u003Cbutton\u003E, or add role \u002B tabIndex={0} \u002B a key handler."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/common/MultiSelect.tsx"},"region":{"startLine":176}}}],"partialFingerprints":{"codehealthFindingId/v1":"a0fba558fd310869daf3b6482e1f683c7b6d7faf935e5119d20639d64a805ab4"}},{"ruleId":"AC4","level":"error","message":{"text":"Clickable role=\u0022button\u0022 that no keyboard user can reach: This \u003Cdiv\u003E announces itself as a role=\u0022button\u0022 and binds a click, but nothing can put focus on it: no tabIndex={0} in any spelling, no key handler, and nothing in this file moves focus or sets aria-activedescendant. The role tells assistive tech what the control IS; it does not make the control reachable, so a keyboard user cannot operate it at all (WCAG 2.1.1). Give it tabIndex={0}=\u00220\u0022 and an Enter/Space key handler, or make it a native \u003Cbutton\u003E. If a parent widget owns the keyboard model, that parent must move focus onto the active role=\u0022button\u0022 or point aria-activedescendant at it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/common/ReviewModeGutter.tsx"},"region":{"startLine":122}}}],"partialFingerprints":{"codehealthFindingId/v1":"ab402102b899e8362be99e4eb1daab515d16a110417e0184c1d5dc3bf628ec63"}},{"ruleId":"AC4","level":"error","message":{"text":"Click handler on a non-interactive \u003Cdiv\u003E: A click handler on a plain element isn\u0027t keyboard-operable. Use a \u003Cbutton\u003E, or add role \u002B tabIndex={0} \u002B a key handler."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/common/ToolSelector.tsx"},"region":{"startLine":175}}}],"partialFingerprints":{"codehealthFindingId/v1":"2c751b271d2e463e66f0fa27fb02403d004a8d1748b2b92955a286f6a44091a4"}},{"ruleId":"AC4","level":"error","message":{"text":"Click handler on a non-interactive \u003Cli\u003E: A click handler on a plain element isn\u0027t keyboard-operable. Use a \u003Cbutton\u003E, or add role \u002B tabIndex={0} \u002B a key handler."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/file-viewer/CanvasOutputRail.tsx"},"region":{"startLine":156}}}],"partialFingerprints":{"codehealthFindingId/v1":"37c4d15ed8adfdb3cbd3421180dcd4b778bf3ec11a8de043f51a92a1d8cd7d48"}},{"ruleId":"AC4","level":"error","message":{"text":"Click handler on a non-interactive \u003Cdiv\u003E: A click handler on a plain element isn\u0027t keyboard-operable. Use a \u003Cbutton\u003E, or add role \u002B tabIndex={0} \u002B a key handler."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/file-viewer/CanvasOutputRail.tsx"},"region":{"startLine":394}}}],"partialFingerprints":{"codehealthFindingId/v1":"c1809a93f542bafb6102d15c6a366a43432fb7bbf3977aa66999b83fdca3d804"}},{"ruleId":"AC4","level":"error","message":{"text":"Click handler on a \u003Cspan\u003E nested inside \u003Cbutton\u003E: This \u003Cspan\u003E carries its own click handler, but it sits inside a \u003Cbutton\u003E that performs a different action. A keyboard user reaches the \u003Cbutton\u003E and activating it runs the \u003Cbutton\u003E\u0027s handler, never this one, so this action has no keyboard path at all. Role and tabindex cannot supply one: HTML forbids a \u003Cbutton\u003E from containing interactive content or any descendant with a tabindex, so the browser will not put this element in the tab order however it is marked up. Move it out of the \u003Cbutton\u003E and make it a sibling \u003Cbutton\u003E, so each action has its own control."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/file-viewer/FileViewerTabBar.tsx"},"region":{"startLine":93}}}],"partialFingerprints":{"codehealthFindingId/v1":"e33487f2be5787bd287ba4212a2c2c074fa022f0d53dc0a595cdb56ac4b4323b"}},{"ruleId":"AC4","level":"error","message":{"text":"Click handler on a non-interactive \u003Cth\u003E: A click handler on a plain element isn\u0027t keyboard-operable. Use a \u003Cbutton\u003E, or add role \u002B tabIndex={0} \u002B a key handler."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/file-viewer/renderers/CsvRenderer.tsx"},"region":{"startLine":286}}}],"partialFingerprints":{"codehealthFindingId/v1":"fe636acd146a0efc5fc24a055befbc7fea9258616271995f64c7f3da37a202ed"}},{"ruleId":"AC4","level":"error","message":{"text":"Click handler on a non-interactive \u003Cdiv\u003E: A click handler on a plain element isn\u0027t keyboard-operable. Use a \u003Cbutton\u003E, or add role \u002B tabIndex={0} \u002B a key handler."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/layout/JobsRunsOverlay.tsx"},"region":{"startLine":257}}}],"partialFingerprints":{"codehealthFindingId/v1":"78d65fa4b03897e944b6760a88046f4512778a299e8f7b8b539f996ead341718"}},{"ruleId":"AC4","level":"error","message":{"text":"Click handler on a non-interactive \u003Cth\u003E: A click handler on a plain element isn\u0027t keyboard-operable. Use a \u003Cbutton\u003E, or add role \u002B tabIndex={0} \u002B a key handler."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/layout/ToDoOverlay.tsx"},"region":{"startLine":585}}}],"partialFingerprints":{"codehealthFindingId/v1":"f1fe5e0efd5d36c1036f5cf0a0c1c6ebd8002bb4d29894837e09487429ab75f1"}},{"ruleId":"AC4","level":"error","message":{"text":"Click handler on a non-interactive \u003Ctr\u003E: A click handler on a plain element isn\u0027t keyboard-operable. Use a \u003Cbutton\u003E, or add role \u002B tabIndex={0} \u002B a key handler."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/layout/ToDoOverlay.tsx"},"region":{"startLine":619}}}],"partialFingerprints":{"codehealthFindingId/v1":"22a34e99ee71861d17564ac0377cf064ecd92677a998134bddc60ba122359b00"}},{"ruleId":"AC7","level":"warning","message":{"text":"Accessibility enforcement below the top rung: No accessibility enforcement found \u2014 no a11y linter (eslint-plugin-jsx-a11y) and no axe/pa11y/Lighthouse in tests or CI. Start with the linter to catch issues at author time. What was searched, so you can tell an absence from a miss: the 186 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":"ADRs not easily discoverable: 2 ADR-shaped document(s) detected by content \u2014 \u0060backend/skills/s_narrative-writing/reference/templates/adr.md\u0060, \u0060backend/skills/s_project-manager/SKILL.md\u0060. They are not under a conventional ADR folder (docs/adr/) and are not named NNNN-title.md, and this check found them by their decision signature rather than by where they live \u2014 so a reader who does not already know these paths has no route to them. Detected by content signature only: records kept outside the repository, or written without a Status/Decision/Consequences shape, are not visible to this check and are not counted here."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"ea921cf64dae701abd877090b3279ff10d03c2e3250e26c8c299d7c5665e0d3f"}},{"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":"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 38191 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":"R10","level":"warning","message":{"text":"Duplication concentrated across 6 sibling directories (34 clone groups): 34 duplicated blocks under desktop/src/ have copies in at least two of the sibling directories components, contexts, hooks, pages, stores, utils \u2014 9 of them are reported below, and 25 are counted here but not reported individually: those copies match on shape but no longer clear R10\u0027s bar for an individually reported row \u2014 either they kept neither their own names nor their values, or what was copied is too small to stand on its own (it reports near-exact duplication only, and only of substantial extent). What this row states is the concentration, which the detector measured over all 34 and which does not depend on how exactly each block\u0027s copies still match. That concentration is one structural fact, not 34 local ones: the siblings replicate behaviour none of them owns, which is the shape of a missing shared module \u2014 a common library every sibling imports \u2014 rather than 34 separate extractions. Check first whether the siblings are deliberately standalone deliverables (scaffold templates, demo apps that must stay copy-pasteable); where they are, the duplication is the design and the per-block rows are the ones to act on."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/settings/BackupTab.tsx"},"region":{"startLine":22}}}],"partialFingerprints":{"codehealthFindingId/v1":"612add4fcf4b44bd8fb325b77c1d540e154e6b06394ebae3f4e3a8cc6bff3af1"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplication concentrated across 8 sibling directories (25 clone groups): 25 duplicated blocks under desktop/src/components/ have copies in at least two of the sibling directories common, file-viewer, layout, modals, settings, workspace (\u002B2 more sibling(s) not listed) \u2014 9 of them are reported below, and 16 are counted here but not reported individually: those copies match on shape but no longer clear R10\u0027s bar for an individually reported row \u2014 either they kept neither their own names nor their values, or what was copied is too small to stand on its own (it reports near-exact duplication only, and only of substantial extent). What this row states is the concentration, which the detector measured over all 25 and which does not depend on how exactly each block\u0027s copies still match. That concentration is one structural fact, not 25 local ones: the siblings replicate behaviour none of them owns, which is the shape of a missing shared module \u2014 a common library every sibling imports \u2014 rather than 25 separate extractions. Check first whether the siblings are deliberately standalone deliverables (scaffold templates, demo apps that must stay copy-pasteable); where they are, the duplication is the design and the per-block rows are the ones to act on."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/common/Modal.tsx"},"region":{"startLine":58}}}],"partialFingerprints":{"codehealthFindingId/v1":"2c10f7f5cd6244416b7b873ae2923c61eb0cd7b3b110d0ceb13da70b4ba15a4a"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block with local edits (126 matched lines \u00D7 2 locations): desktop/src/components/common/Dropdown.tsx:31 \u00B7 desktop/src/components/common/MultiSelect.tsx:36 \u2014 the two spans are one implementation copied and then locally edited \u2014 645 tokens are still identical, in the same order in both files, with only local edits between them. The copies have already begun to drift, which is this row\u0027s finding: an edit made to one and not the other changes behaviour silently. Diff the two spans first to learn what genuinely differs, then extract the shared core into one module both sites use, passing the differences in as parameters \u2014 or, if one copy exists only because the other could not be imported from its context, make one of them the single source the other is generated or re-exported from. If one copy is no longer reachable, delete it rather than letting it shadow the live one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/common/Dropdown.tsx"},"region":{"startLine":31}}}],"partialFingerprints":{"codehealthFindingId/v1":"c89228c0c559a86d78c86a5f86776818edf20328abf7d4901ce61f92a4f88d6f"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block with local edits (61 matched lines \u00D7 2 locations): desktop/src/components/settings/BackupTab.tsx:22 \u00B7 desktop/src/pages/OnboardingPage.tsx:355 \u2014 the two spans are one implementation copied and then locally edited \u2014 413 tokens are still identical, in the same order in both files, with only local edits between them. The copies have already begun to drift, which is this row\u0027s finding: an edit made to one and not the other changes behaviour silently. Diff the two spans first to learn what genuinely differs, then extract the shared core into one module both sites use, passing the differences in as parameters \u2014 or, if one copy exists only because the other could not be imported from its context, make one of them the single source the other is generated or re-exported from. If one copy is no longer reachable, delete it rather than letting it shadow the live one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/settings/BackupTab.tsx"},"region":{"startLine":22}}}],"partialFingerprints":{"codehealthFindingId/v1":"2d4889a9839d38ffd497095b220b833559ee7caa5e1244c4c0451f5c280f9bf8"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (59 lines \u00D7 2 locations): desktop/src/components/workspace/FileBrowser.tsx:159 \u00B7 desktop/src/components/workspace/FolderPickerModal.tsx:164 \u2014 the 2 copies are spread across 2 files, and the SHAPE of this repetition could not be determined. It is not a run of declarations, a listing, a declaration header, a type body or a slice through a construct \u2014 and it was not measured as a run of executable statements either, so this row cannot tell you whether a function can stand where these lines are. Read the two spans before acting, because the move is opposite in the two cases. Where they are statements, the ordinary answer holds: give the shared part one home and call it from each site. Where they turn out to be declarations, a literal\u0027s entries, or the cases of an enumeration, there is no call site to call anything from, and collapsing them would delete what each copy pins \u2014 a shared base type, a generated set, or one exported constant each site refers to is the move instead, and sometimes the honest answer is that there is nothing to extract at all. Reported because the copies drift apart the first time only one of them is edited, which is true whichever of those they are."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/workspace/FileBrowser.tsx"},"region":{"startLine":159}}}],"partialFingerprints":{"codehealthFindingId/v1":"71e233fa0f5afd5b77d1937d90b537183b512be025c049f5a97729aab88b6214"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block with local edits (57 matched lines \u00D7 2 locations): desktop/src/components/layout/HiveFleetOverlay.tsx:90 \u00B7 desktop/src/components/layout/JobsRunsOverlay.tsx:142 \u2014 the two spans are one implementation copied and then locally edited \u2014 396 tokens are still identical, in the same order in both files, with only local edits between them. The copies have already begun to drift, which is this row\u0027s finding: an edit made to one and not the other changes behaviour silently. Diff the two spans first to learn what genuinely differs, then extract the shared core into one module both sites use, passing the differences in as parameters \u2014 or, if one copy exists only because the other could not be imported from its context, make one of them the single source the other is generated or re-exported from. If one copy is no longer reachable, delete it rather than letting it shadow the live one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/layout/HiveFleetOverlay.tsx"},"region":{"startLine":90}}}],"partialFingerprints":{"codehealthFindingId/v1":"be054b9c6d65b3f42b58cda476a1f52a70160df67833388628f3ad21a63b347c"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block with local edits (53 matched lines \u00D7 2 locations): desktop/src/components/layout/PipelineOverlay.tsx:91 \u00B7 desktop/src/components/layout/PollinateOverlay.tsx:109 \u2014 the two spans are one implementation copied and then locally edited \u2014 407 tokens are still identical, in the same order in both files, with only local edits between them. The copies have already begun to drift, which is this row\u0027s finding: an edit made to one and not the other changes behaviour silently. Diff the two spans first to learn what genuinely differs, then extract the shared core into one module both sites use, passing the differences in as parameters \u2014 or, if one copy exists only because the other could not be imported from its context, make one of them the single source the other is generated or re-exported from. If one copy is no longer reachable, delete it rather than letting it shadow the live one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/layout/PipelineOverlay.tsx"},"region":{"startLine":91}}}],"partialFingerprints":{"codehealthFindingId/v1":"6bf711c769ff2c6d9489ba45a70a41ba529eaefc010a809fa55ce343878c1b73"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block with local edits (44 matched lines \u00D7 2 locations): desktop/src/components/layout/ThreeColumnLayout.tsx:393 \u00B7 desktop/src/components/layout/ThreeColumnLayout.tsx:466 \u2014 the two spans are one implementation copied and then locally edited \u2014 330 tokens are still identical, in the same order in both spans, with only local edits between them. The copies have already begun to drift, which is this row\u0027s finding: an edit made to one and not the other changes behaviour silently. Diff the two spans first to learn what genuinely differs, then extract the shared core into one module both sites use, passing the differences in as parameters \u2014 or, if one copy exists only because the other could not be imported from its context, make one of them the single source the other is generated or re-exported from. If one copy is no longer reachable, delete it rather than letting it shadow the live one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/layout/ThreeColumnLayout.tsx"},"region":{"startLine":393}}}],"partialFingerprints":{"codehealthFindingId/v1":"df26287e90f965c96a64c0b85bfa14d5db83e8218387d67fc2e142ee71502586"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block with local edits (42 matched lines \u00D7 2 locations): desktop/src/services/agents.ts:18 \u00B7 desktop/src/services/channels.ts:64 \u2014 the two spans are one implementation copied and then locally edited \u2014 401 tokens are still identical, in the same order in both files, with only local edits between them. The copies have already begun to drift, which is this row\u0027s finding: an edit made to one and not the other changes behaviour silently. Diff the two spans first to learn what genuinely differs, then extract the shared core into one module both sites use, passing the differences in as parameters \u2014 or, if one copy exists only because the other could not be imported from its context, make one of them the single source the other is generated or re-exported from. If one copy is no longer reachable, delete it rather than letting it shadow the live one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/services/agents.ts"},"region":{"startLine":18}}}],"partialFingerprints":{"codehealthFindingId/v1":"83d6a192e610d52ed4d2a2a74feb426b799b23ddd6c1b98a222693ef04e91070"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block with local edits (37 matched lines \u00D7 2 locations): desktop/src/components/common/CommentPopover.tsx:107 \u00B7 desktop/src/components/common/FileEditorCore.tsx:270 \u2014 the two spans are one implementation copied and then locally edited \u2014 198 tokens are still identical, in the same order in both files, with only local edits between them. The copies have already begun to drift, which is this row\u0027s finding: an edit made to one and not the other changes behaviour silently. Diff the two spans first to learn what genuinely differs, then extract the shared core into one module both sites use, passing the differences in as parameters \u2014 or, if one copy exists only because the other could not be imported from its context, make one of them the single source the other is generated or re-exported from. If one copy is no longer reachable, delete it rather than letting it shadow the live one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/common/CommentPopover.tsx"},"region":{"startLine":107}}}],"partialFingerprints":{"codehealthFindingId/v1":"6c31f993f7f61c1a0ce6df01e0706ee977d8ff5cf02c729e7e4b54ee1713c478"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block with local edits (37 matched lines \u00D7 2 locations): desktop/src/services/tasks.ts:18 \u00B7 desktop/src/services/todos.ts:31 \u2014 the two spans are one implementation copied and then locally edited \u2014 345 tokens are still identical, in the same order in both files, with only local edits between them. The copies have already begun to drift, which is this row\u0027s finding: an edit made to one and not the other changes behaviour silently. Diff the two spans first to learn what genuinely differs, then extract the shared core into one module both sites use, passing the differences in as parameters \u2014 or, if one copy exists only because the other could not be imported from its context, make one of them the single source the other is generated or re-exported from. If one copy is no longer reachable, delete it rather than letting it shadow the live one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/services/tasks.ts"},"region":{"startLine":18}}}],"partialFingerprints":{"codehealthFindingId/v1":"96154289104e6779b053bfe40cdc6411132b1987be4b715e7d908f9a9724a567"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (36 lines \u00D7 2 locations): desktop/src/hooks/useChatStreamingLifecycle.ts:2017 \u00B7 desktop/src/hooks/useStreamingActivity.ts:42 \u2014 the 2 copies sit in sibling files in one directory, so check first whether one of them (or an existing module there) already owns this behaviour and the others should call it; otherwise extract it into one module in that directory and have each site call it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/hooks/useChatStreamingLifecycle.ts"},"region":{"startLine":2017}}}],"partialFingerprints":{"codehealthFindingId/v1":"d4e7513b1bd85f9a1f5e85a9b70d6235edb9e23693f726e85e8684d619afbba3"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block with local edits (35 matched lines \u00D7 2 locations): desktop/src/components/common/Modal.tsx:58 \u00B7 desktop/src/components/layout/OverlayHost.tsx:100 \u2014 the two spans are one implementation copied and then locally edited \u2014 253 tokens are still identical, in the same order in both files, with only local edits between them. The copies have already begun to drift, which is this row\u0027s finding: an edit made to one and not the other changes behaviour silently. Diff the two spans first to learn what genuinely differs, then extract the shared core into one module both sites use, passing the differences in as parameters \u2014 or, if one copy exists only because the other could not be imported from its context, make one of them the single source the other is generated or re-exported from. If one copy is no longer reachable, delete it rather than letting it shadow the live one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/common/Modal.tsx"},"region":{"startLine":58}}}],"partialFingerprints":{"codehealthFindingId/v1":"602d7e70925548c56b0c5aa66739760e586d7c1ff02f8bfad833e9c27c2a2fb6"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (34 lines \u00D7 2 locations): desktop/src/pages/chat/components/ChatInput.tsx:809 \u00B7 desktop/src/pages/chat/components/ChatInput.tsx:849 \u2014 both copies are in the same file, so extract the block 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":"desktop/src/pages/chat/components/ChatInput.tsx"},"region":{"startLine":809}}}],"partialFingerprints":{"codehealthFindingId/v1":"37492747cb96aece7fff1517b1016c5c9373abb3fcdd5461b0e744f79d28cc6d"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block with local edits (32 matched lines \u00D7 2 locations): desktop/src/components/layout/CMBrainOverlay.tsx:1141 \u00B7 desktop/src/components/layout/LibraryOverlay.tsx:520 \u2014 the two spans are one implementation copied and then locally edited \u2014 193 tokens are still identical, in the same order in both files, with only local edits between them. The copies have already begun to drift, which is this row\u0027s finding: an edit made to one and not the other changes behaviour silently. Diff the two spans first to learn what genuinely differs, then extract the shared core into one module both sites use, passing the differences in as parameters \u2014 or, if one copy exists only because the other could not be imported from its context, make one of them the single source the other is generated or re-exported from. If one copy is no longer reachable, delete it rather than letting it shadow the live one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/layout/CMBrainOverlay.tsx"},"region":{"startLine":1141}}}],"partialFingerprints":{"codehealthFindingId/v1":"4fdf19436bc24f02ff33a23d71f6f6c0c5bbde36311bf583ad940c3e9846d54d"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (30 lines \u00D7 3 locations): desktop/src/pages/SkillsPage.tsx:469 \u00B7 desktop/src/pages/SkillsPage.tsx:579 \u00B7 desktop/src/pages/SkillsPage.tsx:743 \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":"desktop/src/pages/SkillsPage.tsx"},"region":{"startLine":469}}}],"partialFingerprints":{"codehealthFindingId/v1":"d3f405a090f231d62bb77b2aeaac3c28bbd9e504276460a4d53be6d40c67e09b"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (27 lines \u00D7 2 locations): desktop/src/components/file-viewer/renderers/AudioRenderer.tsx:14 \u00B7 desktop/src/components/file-viewer/renderers/VideoRenderer.tsx:14 \u2014 the 2 copies sit in sibling files in one directory, so check first whether one of them (or an existing module there) already owns this behaviour and the others should call it; otherwise extract it into one module in that directory and have each site call it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/file-viewer/renderers/AudioRenderer.tsx"},"region":{"startLine":14}}}],"partialFingerprints":{"codehealthFindingId/v1":"ee65c47f92690bee5c7e374dc4b29908f9281f200a87c7a9108cc87a0800f2fc"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (26 lines \u00D7 2 locations): backend/skills/s_pollinate/templates/remotion/components/ShortCTACard.tsx:10 \u00B7 backend/skills/s_pollinate/templates/remotion/components/ShortIntroCard.tsx:11 \u2014 the 2 copies are spread across 2 files, and the CITED SPAN is not a self-contained block \u2014 it runs from inside one construct into the next (the tail of a branch plus the head of the following one, a run of switch arms, the end of a declaration plus the list that follows it) rather than covering a whole unit. So do not lift these lines literally: no call can be substituted for a half-open construct. Extract the enclosing repeated UNIT instead \u2014 the whole function, component or branch these lines sit in \u2014 and where the repetition IS the construct (a run of switch arms, a stack of near-identical declarations) replace it with one table or registry looked up by key rather than a helper each arm calls. The copies still drift apart the first time only one of them is edited, which is why this is reported."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/skills/s_pollinate/templates/remotion/components/ShortCTACard.tsx"},"region":{"startLine":10}}}],"partialFingerprints":{"codehealthFindingId/v1":"f47e5a85419ff7fb169e812aa8bef8032bce75d02d3e1f563b121cb312a2bbb5"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (23 lines \u00D7 2 locations): desktop/src/hooks/useChatStreamingLifecycle.ts:546 \u00B7 desktop/src/hooks/useChatStreamingLifecycle.ts:577 \u2014 both copies are in the same file, so extract the block 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":"desktop/src/hooks/useChatStreamingLifecycle.ts"},"region":{"startLine":546}}}],"partialFingerprints":{"codehealthFindingId/v1":"d9cf845a1ce6eac156e0b55fcda69e94f2d67af685fbf431ac2487520475c437"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (23 lines \u00D7 2 locations): desktop/src/pages/SkillsPage.tsx:946 \u00B7 desktop/src/pages/SkillsPage.tsx:975 \u2014 all 2 copies are in the same file, and the SHAPE of this repetition could not be determined. It is not a run of declarations, a listing, a declaration header, a type body or a slice through a construct \u2014 and it was not measured as a run of executable statements either, so this row cannot tell you whether a function can stand where these lines are. Read the two spans before acting, because the move is opposite in the two cases. Where they are statements, the ordinary answer holds: give the shared part one home and call it from each site. Where they turn out to be declarations, a literal\u0027s entries, or the cases of an enumeration, there is no call site to call anything from, and collapsing them would delete what each copy pins \u2014 a shared base type, a generated set, or one exported constant each site refers to is the move instead, and sometimes the honest answer is that there is nothing to extract at all. Reported because the copies drift apart the first time only one of them is edited, which is true whichever of those they are."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/pages/SkillsPage.tsx"},"region":{"startLine":946}}}],"partialFingerprints":{"codehealthFindingId/v1":"fd7b19c14339148c8842153db85d431935e35fea8097abb26a7dd8cff41a4abc"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (23 lines \u00D7 2 locations): desktop/src/pages/chat/components/TSCCPanel.tsx:125 \u00B7 desktop/src/pages/chat/components/TSCCPanel.tsx:202 \u2014 both copies are in the same file, so extract the block 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":"desktop/src/pages/chat/components/TSCCPanel.tsx"},"region":{"startLine":125}}}],"partialFingerprints":{"codehealthFindingId/v1":"1bdd673ba00c471aaf602175d7778f05e0fd58a3be27c03f8a2a27fcd5e069a0"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (22 lines \u00D7 2 locations): backend/skills/s_pollinate/templates/remotion/components/DiagramReveal.tsx:293 \u00B7 backend/skills/s_pollinate/templates/remotion/components/FlowChart.tsx:30 \u2014 the 2 copies sit in sibling files in one directory, so check first whether one of them (or an existing module there) already owns this behaviour and the others should call it; otherwise extract it into one module in that directory and have each site call it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/skills/s_pollinate/templates/remotion/components/DiagramReveal.tsx"},"region":{"startLine":293}}}],"partialFingerprints":{"codehealthFindingId/v1":"aaca6dace11578bac8003933342f5a9af7545fa8a9c372b14cdf56c9566f415c"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (22 lines \u00D7 2 locations): desktop/src/components/common/AgentFormModal.tsx:256 \u00B7 desktop/src/components/common/AgentFormModal.tsx:279 \u2014 both copies are in the same file, so extract the block 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":"desktop/src/components/common/AgentFormModal.tsx"},"region":{"startLine":256}}}],"partialFingerprints":{"codehealthFindingId/v1":"f4cec4fc4942e70ddb3321ba7356888e95ccda861af744227b147ea1d72149d0"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (22 lines \u00D7 2 locations): desktop/src/components/layout/JobsRunsOverlay.tsx:189 \u00B7 desktop/src/components/layout/ToDoOverlay.tsx:749 \u2014 the 2 copies are spread across 2 files, and the CITED SPAN is not a self-contained block \u2014 it runs from inside one construct into the next (the tail of a branch plus the head of the following one, a run of switch arms, the end of a declaration plus the list that follows it) rather than covering a whole unit. So do not lift these lines literally: no call can be substituted for a half-open construct. Extract the enclosing repeated UNIT instead \u2014 the whole function, component or branch these lines sit in \u2014 and where the repetition IS the construct (a run of switch arms, a stack of near-identical declarations) replace it with one table or registry looked up by key rather than a helper each arm calls. The copies still drift apart the first time only one of them is edited, which is why this is reported."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/layout/JobsRunsOverlay.tsx"},"region":{"startLine":189}}}],"partialFingerprints":{"codehealthFindingId/v1":"3a7c8190159b0072369519b10ccc97d68c60b18893063503e6043b8b9a336c93"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (22 lines \u00D7 2 locations): desktop/src/hooks/useHealthMonitor.ts:371 \u00B7 desktop/src/hooks/useHealthMonitor.ts:479 \u2014 all 2 copies are in the same file, and the CITED SPAN is not a self-contained block \u2014 it runs from inside one construct into the next (the tail of a branch plus the head of the following one, a run of switch arms, the end of a declaration plus the list that follows it) rather than covering a whole unit. So do not lift these lines literally: no call can be substituted for a half-open construct. Extract the enclosing repeated UNIT instead \u2014 the whole function, component or branch these lines sit in \u2014 and where the repetition IS the construct (a run of switch arms, a stack of near-identical declarations) replace it with one table or registry looked up by key rather than a helper each arm calls. The copies still drift apart the first time only one of them is edited, which is why this is reported."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/hooks/useHealthMonitor.ts"},"region":{"startLine":371}}}],"partialFingerprints":{"codehealthFindingId/v1":"7136f22aec41e08036a3246a598567e20081e9330af574c8f8a48dcb0ea4295f"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (21 lines \u00D7 2 locations): desktop/src/components/settings/SettingsTabs.tsx:82 \u00B7 desktop/src/pages/EvalDashboard.tsx:253 \u2014 the 2 copies are spread across 2 files, and the SHAPE of this repetition could not be determined. It is not a run of declarations, a listing, a declaration header, a type body or a slice through a construct \u2014 and it was not measured as a run of executable statements either, so this row cannot tell you whether a function can stand where these lines are. Read the two spans before acting, because the move is opposite in the two cases. Where they are statements, the ordinary answer holds: give the shared part one home and call it from each site. Where they turn out to be declarations, a literal\u0027s entries, or the cases of an enumeration, there is no call site to call anything from, and collapsing them would delete what each copy pins \u2014 a shared base type, a generated set, or one exported constant each site refers to is the move instead, and sometimes the honest answer is that there is nothing to extract at all. Reported because the copies drift apart the first time only one of them is edited, which is true whichever of those they are."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/settings/SettingsTabs.tsx"},"region":{"startLine":82}}}],"partialFingerprints":{"codehealthFindingId/v1":"7ec03d54d1b82973826f0b582031a62c225e719dfb273dbb3436ad76274c47f4"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block with local edits (20 matched lines \u00D7 2 locations): desktop/src/components/common/BackendStartupOverlay.tsx:408 \u00B7 desktop/src/components/common/BackendStartupOverlay.tsx:460 \u2014 the two spans are one implementation copied and then locally edited \u2014 104 tokens are still identical, in the same order in both spans, with only local edits between them. The copies have already begun to drift, which is this row\u0027s finding: an edit made to one and not the other changes behaviour silently. Diff the two spans first to learn what genuinely differs, then extract the shared core into one module both sites use, passing the differences in as parameters \u2014 or, if one copy exists only because the other could not be imported from its context, make one of them the single source the other is generated or re-exported from. If one copy is no longer reachable, delete it rather than letting it shadow the live one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/common/BackendStartupOverlay.tsx"},"region":{"startLine":408}}}],"partialFingerprints":{"codehealthFindingId/v1":"5014f28a48ad20f40ea6a93eb048e729804ee09f76cf39b0f8465b28de58d4c6"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (19 lines \u00D7 2 locations): backend/skills/s_pollinate/templates/remotion/components/DiagramReveal.tsx:135 \u00B7 backend/skills/s_pollinate/templates/remotion/components/DiagramReveal.tsx:166 \u2014 all 2 copies are in the same file, and the CITED SPAN is not a self-contained block \u2014 it runs from inside one construct into the next (the tail of a branch plus the head of the following one, a run of switch arms, the end of a declaration plus the list that follows it) rather than covering a whole unit. So do not lift these lines literally: no call can be substituted for a half-open construct. Extract the enclosing repeated UNIT instead \u2014 the whole function, component or branch these lines sit in \u2014 and where the repetition IS the construct (a run of switch arms, a stack of near-identical declarations) replace it with one table or registry looked up by key rather than a helper each arm calls. The copies still drift apart the first time only one of them is edited, which is why this is reported."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/skills/s_pollinate/templates/remotion/components/DiagramReveal.tsx"},"region":{"startLine":135}}}],"partialFingerprints":{"codehealthFindingId/v1":"5f5012a97da3c3767cef09dbefefd5d831ccca30c2ad883330affe1685d4015d"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (19 lines \u00D7 2 locations): desktop/src/components/common/FileEditorCore.tsx:1380 \u00B7 desktop/src/components/common/FileEditorCore.tsx:1399 \u2014 all 2 copies are in the same file, and the SHAPE of this repetition could not be determined. It is not a run of declarations, a listing, a declaration header, a type body or a slice through a construct \u2014 and it was not measured as a run of executable statements either, so this row cannot tell you whether a function can stand where these lines are. Read the two spans before acting, because the move is opposite in the two cases. Where they are statements, the ordinary answer holds: give the shared part one home and call it from each site. Where they turn out to be declarations, a literal\u0027s entries, or the cases of an enumeration, there is no call site to call anything from, and collapsing them would delete what each copy pins \u2014 a shared base type, a generated set, or one exported constant each site refers to is the move instead, and sometimes the honest answer is that there is nothing to extract at all. Reported because the copies drift apart the first time only one of them is edited, which is true whichever of those they are."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/common/FileEditorCore.tsx"},"region":{"startLine":1380}}}],"partialFingerprints":{"codehealthFindingId/v1":"578a9a6cd9afab67a34fcf3cc67329dd375db812be504a682427b5068fd98828"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block with local edits (18 matched lines \u00D7 2 locations): desktop/src/components/chat/FileAttachmentButton.tsx:64 \u00B7 desktop/src/components/chat/ScreenshotButton.tsx:71 \u2014 the two spans are one implementation copied and then locally edited \u2014 53 tokens are still identical, in the same order in both files, with only local edits between them. The copies have already begun to drift, which is this row\u0027s finding: an edit made to one and not the other changes behaviour silently. Diff the two spans first to learn what genuinely differs, then extract the shared core into one module both sites use, passing the differences in as parameters \u2014 or, if one copy exists only because the other could not be imported from its context, make one of them the single source the other is generated or re-exported from. If one copy is no longer reachable, delete it rather than letting it shadow the live one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/chat/FileAttachmentButton.tsx"},"region":{"startLine":64}}}],"partialFingerprints":{"codehealthFindingId/v1":"ea6bacf451a43b866bd4bf7376c0f1ced097901753905e0422212a9c25d4fcbb"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (18 lines \u00D7 2 locations): desktop/src/hooks/useChatStreamingLifecycle.ts:483 \u00B7 desktop/src/hooks/useChatStreamingLifecycle.ts:504 \u2014 both copies are in the same file, so extract the block 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":"desktop/src/hooks/useChatStreamingLifecycle.ts"},"region":{"startLine":483}}}],"partialFingerprints":{"codehealthFindingId/v1":"f865bfa07d1e833d631ba646a752883d3b974d88e557a82561212f87c45e2fd8"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (18 lines \u00D7 2 locations): desktop/src/services/tscc.ts:133 \u00B7 desktop/src/services/tscc.ts:169 \u2014 both copies are in the same file, so extract the block 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":"desktop/src/services/tscc.ts"},"region":{"startLine":133}}}],"partialFingerprints":{"codehealthFindingId/v1":"e55633a066eb21d5e26f9b90a9f5765d953a1ea4edef80b4b897196169203dc1"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (17 lines \u00D7 2 locations): backend/skills/s_pollinate/templates/remotion/components/animations.tsx:134 \u00B7 backend/skills/s_pollinate/templates/remotion/components/animations.tsx:153 \u2014 both copies are in the same file, so extract the block 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":"backend/skills/s_pollinate/templates/remotion/components/animations.tsx"},"region":{"startLine":134}}}],"partialFingerprints":{"codehealthFindingId/v1":"b114248fdaae0de6da8e80e8d4f3a1ad5d91527967e2b17bccd75d004b3b5fb5"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (17 lines \u00D7 2 locations): desktop/src/components/common/FileEditorCore.tsx:1644 \u00B7 desktop/src/components/common/FileEditorCore.tsx:1674 \u2014 all 2 copies are in the same file, and the CITED SPAN is not a self-contained block \u2014 it runs from inside one construct into the next (the tail of a branch plus the head of the following one, a run of switch arms, the end of a declaration plus the list that follows it) rather than covering a whole unit. So do not lift these lines literally: no call can be substituted for a half-open construct. Extract the enclosing repeated UNIT instead \u2014 the whole function, component or branch these lines sit in \u2014 and where the repetition IS the construct (a run of switch arms, a stack of near-identical declarations) replace it with one table or registry looked up by key rather than a helper each arm calls. The copies still drift apart the first time only one of them is edited, which is why this is reported."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/common/FileEditorCore.tsx"},"region":{"startLine":1644}}}],"partialFingerprints":{"codehealthFindingId/v1":"204cca6bb92b1a8e16862e146115320c2a9f8bbdc0af479a79bf05b5b28eb9c2"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (17 lines \u00D7 2 locations): desktop/src/components/layout/CMBrainOverlay.tsx:899 \u00B7 desktop/src/components/layout/CMBrainOverlay.tsx:939 \u2014 all 2 copies are in the same file, and the CITED SPAN is not a self-contained block \u2014 it runs from inside one construct into the next (the tail of a branch plus the head of the following one, a run of switch arms, the end of a declaration plus the list that follows it) rather than covering a whole unit. So do not lift these lines literally: no call can be substituted for a half-open construct. Extract the enclosing repeated UNIT instead \u2014 the whole function, component or branch these lines sit in \u2014 and where the repetition IS the construct (a run of switch arms, a stack of near-identical declarations) replace it with one table or registry looked up by key rather than a helper each arm calls. The copies still drift apart the first time only one of them is edited, which is why this is reported."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/layout/CMBrainOverlay.tsx"},"region":{"startLine":899}}}],"partialFingerprints":{"codehealthFindingId/v1":"ed31c6388689fe59a54ecf40042e4ba45e0b601a4d12451c154e44fe168c1ba2"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (16 lines \u00D7 2 locations): backend/skills/s_pollinate/templates/remotion/Video.tsx:118 \u00B7 backend/skills/s_pollinate/templates/remotion/Video.tsx:258 \u2014 all 2 copies are in the same file, and what repeats is a LIST OF ENTRIES rather than behaviour \u2014 the same entries written out more than once. Extract them into one shared, exported constant and spread that constant into each site, rather than into a function the sites call: a list like this often lives in declarative metadata (a decorator\u0027s options object, a static configuration table) that a build step must be able to read statically, where a function call is not allowed. Adding an entry to one copy and not the other is the failure this prevents."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/skills/s_pollinate/templates/remotion/Video.tsx"},"region":{"startLine":118}}}],"partialFingerprints":{"codehealthFindingId/v1":"18ccebb9398cae742bdf8d183cd48f0b817a9218664f1d8d8a1e6f09e6bd1ac1"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (16 lines \u00D7 2 locations): desktop/src/hooks/streaming-machine.ts:134 \u00B7 desktop/src/hooks/streaming-machine.ts:241 \u2014 all 2 copies are in the same file, and the CITED SPAN is not a self-contained block \u2014 it runs from inside one construct into the next (the tail of a branch plus the head of the following one, a run of switch arms, the end of a declaration plus the list that follows it) rather than covering a whole unit. So do not lift these lines literally: no call can be substituted for a half-open construct. Extract the enclosing repeated UNIT instead \u2014 the whole function, component or branch these lines sit in \u2014 and where the repetition IS the construct (a run of switch arms, a stack of near-identical declarations) replace it with one table or registry looked up by key rather than a helper each arm calls. The copies still drift apart the first time only one of them is edited, which is why this is reported."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/hooks/streaming-machine.ts"},"region":{"startLine":134}}}],"partialFingerprints":{"codehealthFindingId/v1":"199fd84943678532e8c716c510451c731cef8f45a991ef0f04628fc42b8b7d87"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (16 lines \u00D7 2 locations): desktop/src/hooks/useUnifiedAttachments.ts:167 \u00B7 desktop/src/hooks/useUnifiedAttachments.ts:301 \u2014 all 2 copies are in the same file, and the CITED SPAN is not a self-contained block \u2014 it runs from inside one construct into the next (the tail of a branch plus the head of the following one, a run of switch arms, the end of a declaration plus the list that follows it) rather than covering a whole unit. So do not lift these lines literally: no call can be substituted for a half-open construct. Extract the enclosing repeated UNIT instead \u2014 the whole function, component or branch these lines sit in \u2014 and where the repetition IS the construct (a run of switch arms, a stack of near-identical declarations) replace it with one table or registry looked up by key rather than a helper each arm calls. The copies still drift apart the first time only one of them is edited, which is why this is reported."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/hooks/useUnifiedAttachments.ts"},"region":{"startLine":167}}}],"partialFingerprints":{"codehealthFindingId/v1":"21bfafff123fb2a3e61835a80d27af9cec8520efeec56dc44b1cc93f7a22416d"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (15 lines \u00D7 2 locations): backend/skills/s_pollinate/templates/remotion/Video.tsx:152 \u00B7 backend/skills/s_pollinate/templates/remotion/Video.tsx:202 \u2014 all 2 copies are in the same file, and the CITED SPAN is not a self-contained block \u2014 it runs from inside one construct into the next (the tail of a branch plus the head of the following one, a run of switch arms, the end of a declaration plus the list that follows it) rather than covering a whole unit. So do not lift these lines literally: no call can be substituted for a half-open construct. Extract the enclosing repeated UNIT instead \u2014 the whole function, component or branch these lines sit in \u2014 and where the repetition IS the construct (a run of switch arms, a stack of near-identical declarations) replace it with one table or registry looked up by key rather than a helper each arm calls. The copies still drift apart the first time only one of them is edited, which is why this is reported."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/skills/s_pollinate/templates/remotion/Video.tsx"},"region":{"startLine":152}}}],"partialFingerprints":{"codehealthFindingId/v1":"c02057a925649b894fc4bb7429d4fb22fe3a57034e0f1cb4a200478daebc2cae"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (15 lines \u00D7 2 locations): desktop/src/components/layout/CMBrainOverlay.tsx:328 \u00B7 desktop/src/components/layout/CMBrainOverlay.tsx:1004 \u2014 both copies are in the same file, so extract the block 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":"desktop/src/components/layout/CMBrainOverlay.tsx"},"region":{"startLine":328}}}],"partialFingerprints":{"codehealthFindingId/v1":"9e1515a415f0b356bd1b2b301899208e7c84363dbabf13e6a8893cbad9f26374"}},{"ruleId":"R2","level":"warning","message":{"text":"Complex function (anonymous) (cyclomatic 308, cognitive 576): (anonymous) has cyclomatic complexity 308 and cognitive complexity 576; this row is raised above a cyclomatic bar of 10. The two numbers answer different questions and the gap between them is what decides whether to act: cyclomatic counts the independent arms through the body, cognitive counts what it costs to hold them in your head, so nesting and mixed boolean chains raise it while a flat run of independent arms does not. Cognitive is at or above cyclomatic here, so the branching is nested or entangled rather than laid out side by side \u2014 extracting each decision into its own named function is the change that pays. Measured by this repository\u0027s own parse of the file, so a body assembled at runtime, or generated, is counted as written rather than as it executes."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/hooks/useChatStreamingLifecycle.ts"},"region":{"startLine":2302}}}],"partialFingerprints":{"codehealthFindingId/v1":"053e8d59e257c2355fb82625a7dd98a0d77f815eb1a8f24df0c437501fb84511"}},{"ruleId":"R2","level":"warning","message":{"text":"Complex function FileEditorCore (cyclomatic 96, cognitive 83): FileEditorCore has cyclomatic complexity 96 and cognitive complexity 83; this row is raised above a cyclomatic bar of 10. The two numbers answer different questions and the gap between them is what decides whether to act: cyclomatic counts the independent arms through the body, cognitive counts what it costs to hold them in your head, so nesting and mixed boolean chains raise it while a flat run of independent arms does not. Cognitive sits below cyclomatic here, so much of the count is breadth \u2014 arms side by side rather than stacked \u2014 and splitting per arm would leave a function per arm; group the work between the checks into named steps instead. Measured by this repository\u0027s own parse of the file, so a body assembled at runtime, or generated, is counted as written rather than as it executes."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/common/FileEditorCore.tsx"},"region":{"startLine":606}}}],"partialFingerprints":{"codehealthFindingId/v1":"a780123d17a51d80f6468306682b04d488497679675f8209b5c5460e3ee4282f"}},{"ruleId":"R2","level":"warning","message":{"text":"Complex function main (cyclomatic 93, cognitive 115): main has cyclomatic complexity 93 and cognitive complexity 115; this row is raised above a cyclomatic bar of 10. The two numbers answer different questions and the gap between them is what decides whether to act: cyclomatic counts the independent arms through the body, cognitive counts what it costs to hold them in your head, so nesting and mixed boolean chains raise it while a flat run of independent arms does not. Cognitive is at or above cyclomatic here, so the branching is nested or entangled rather than laid out side by side \u2014 extracting each decision into its own named function is the change that pays. Measured by this repository\u0027s own parse of the file, so a body assembled at runtime, or generated, is counted as written rather than as it executes."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/skills/s_browser-agent/browser-agent.mjs"},"region":{"startLine":304}}}],"partialFingerprints":{"codehealthFindingId/v1":"84a424a5f37f6f581e791c37a90618f57e121b972db5b6008e70f4d143bdca24"}},{"ruleId":"R2","level":"warning","message":{"text":"Complex function (anonymous) (cyclomatic 76, cognitive 128): (anonymous) has cyclomatic complexity 76 and cognitive complexity 128; this row is raised above a cyclomatic bar of 10. The two numbers answer different questions and the gap between them is what decides whether to act: cyclomatic counts the independent arms through the body, cognitive counts what it costs to hold them in your head, so nesting and mixed boolean chains raise it while a flat run of independent arms does not. Cognitive is at or above cyclomatic here, so the branching is nested or entangled rather than laid out side by side \u2014 extracting each decision into its own named function is the change that pays. Measured by this repository\u0027s own parse of the file, so a body assembled at runtime, or generated, is counted as written rather than as it executes."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/skills/s_pptx/scripts/html2pptx.js"},"region":{"startLine":534}}}],"partialFingerprints":{"codehealthFindingId/v1":"274da65015cd7644ac82ec37af2051d71b784278bdf0657b91253dac097f0b8e"}},{"ruleId":"R2","level":"warning","message":{"text":"Complex function reconcile (cyclomatic 69, cognitive 138): reconcile has cyclomatic complexity 69 and cognitive complexity 138; this row is raised above a cyclomatic bar of 10. The two numbers answer different questions and the gap between them is what decides whether to act: cyclomatic counts the independent arms through the body, cognitive counts what it costs to hold them in your head, so nesting and mixed boolean chains raise it while a flat run of independent arms does not. Cognitive is at or above cyclomatic here, so the branching is nested or entangled rather than laid out side by side \u2014 extracting each decision into its own named function is the change that pays. Measured by this repository\u0027s own parse of the file, so a body assembled at runtime, or generated, is counted as written rather than as it executes."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/hooks/useChatStreamingLifecycle.ts"},"region":{"startLine":1235}}}],"partialFingerprints":{"codehealthFindingId/v1":"950244f2763b24c990992d363236df4962827d41e8311e60db882fc4f0072400"}},{"ruleId":"R2","level":"warning","message":{"text":"Complex function (anonymous) (cyclomatic 60, cognitive 90): (anonymous) has cyclomatic complexity 60 and cognitive complexity 90; this row is raised above a cyclomatic bar of 10. The two numbers answer different questions and the gap between them is what decides whether to act: cyclomatic counts the independent arms through the body, cognitive counts what it costs to hold them in your head, so nesting and mixed boolean chains raise it while a flat run of independent arms does not. Cognitive is at or above cyclomatic here, so the branching is nested or entangled rather than laid out side by side \u2014 extracting each decision into its own named function is the change that pays. Measured by this repository\u0027s own parse of the file, so a body assembled at runtime, or generated, is counted as written rather than as it executes."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/pages/ChatPage.tsx"},"region":{"startLine":2156}}}],"partialFingerprints":{"codehealthFindingId/v1":"18c688a2a9d334c14208db209c94fe4d57ab8c874558a54bd43a26e8dad4bb3b"}},{"ruleId":"R2","level":"warning","message":{"text":"Complex function ChatInput (cyclomatic 57, cognitive 53): ChatInput has cyclomatic complexity 57 and cognitive complexity 53; this row is raised above a cyclomatic bar of 10. The two numbers answer different questions and the gap between them is what decides whether to act: cyclomatic counts the independent arms through the body, cognitive counts what it costs to hold them in your head, so nesting and mixed boolean chains raise it while a flat run of independent arms does not. Cognitive sits below cyclomatic here, so much of the count is breadth \u2014 arms side by side rather than stacked \u2014 and splitting per arm would leave a function per arm; group the work between the checks into named steps instead. Measured by this repository\u0027s own parse of the file, so a body assembled at runtime, or generated, is counted as written rather than as it executes."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/pages/chat/components/ChatInput.tsx"},"region":{"startLine":164}}}],"partialFingerprints":{"codehealthFindingId/v1":"31de4f756f2ad48be1f280c5ddcb29e6cf3b002b3813ec211bd6055f3d5134cc"}},{"ruleId":"R2","level":"warning","message":{"text":"Complex function streamingReducer (cyclomatic 53, cognitive 35): streamingReducer has cyclomatic complexity 53 and cognitive complexity 35; this row is raised above a cyclomatic bar of 10. The two numbers answer different questions and the gap between them is what decides whether to act: cyclomatic counts the independent arms through the body, cognitive counts what it costs to hold them in your head, so nesting and mixed boolean chains raise it while a flat run of independent arms does not. Cognitive sits below cyclomatic here, so much of the count is breadth \u2014 arms side by side rather than stacked \u2014 and splitting per arm would leave a function per arm; group the work between the checks into named steps instead. Measured by this repository\u0027s own parse of the file, so a body assembled at runtime, or generated, is counted as written rather than as it executes."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/hooks/streaming-machine.ts"},"region":{"startLine":110}}}],"partialFingerprints":{"codehealthFindingId/v1":"ca252db7fbac5e021bfba538c861495a14a61cf32d1c0c925ab86fc53afbc8cd"}},{"ruleId":"R2","level":"warning","message":{"text":"Complex function (anonymous) (cyclomatic 50, cognitive 52): (anonymous) has cyclomatic complexity 50 and cognitive complexity 52; this row is raised above a cyclomatic bar of 10. The two numbers answer different questions and the gap between them is what decides whether to act: cyclomatic counts the independent arms through the body, cognitive counts what it costs to hold them in your head, so nesting and mixed boolean chains raise it while a flat run of independent arms does not. Cognitive is at or above cyclomatic here, so the branching is nested or entangled rather than laid out side by side \u2014 extracting each decision into its own named function is the change that pays. Measured by this repository\u0027s own parse of the file, so a body assembled at runtime, or generated, is counted as written rather than as it executes."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/hooks/useChatStreamingLifecycle.ts"},"region":{"startLine":3756}}}],"partialFingerprints":{"codehealthFindingId/v1":"732cbbf47615cc38d1ac26f43bde6d8b24eb757905019341b2b1e61c10fcaf22"}},{"ruleId":"R2","level":"warning","message":{"text":"Complex function AssistantMessageView (cyclomatic 48, cognitive 38): AssistantMessageView has cyclomatic complexity 48 and cognitive complexity 38; this row is raised above a cyclomatic bar of 10. The two numbers answer different questions and the gap between them is what decides whether to act: cyclomatic counts the independent arms through the body, cognitive counts what it costs to hold them in your head, so nesting and mixed boolean chains raise it while a flat run of independent arms does not. Cognitive sits below cyclomatic here, so much of the count is breadth \u2014 arms side by side rather than stacked \u2014 and splitting per arm would leave a function per arm; group the work between the checks into named steps instead. Measured by this repository\u0027s own parse of the file, so a body assembled at runtime, or generated, is counted as written rather than as it executes."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/pages/chat/components/AssistantMessageView.tsx"},"region":{"startLine":77}}}],"partialFingerprints":{"codehealthFindingId/v1":"4836bda79015a365ebbb1bfbbf07caae67ad15c433fe9980b2d1e72717f13efc"}},{"ruleId":"R2","level":"warning","message":{"text":"Complex function (anonymous) (cyclomatic 44, cognitive 93): (anonymous) has cyclomatic complexity 44 and cognitive complexity 93; this row is raised above a cyclomatic bar of 10. The two numbers answer different questions and the gap between them is what decides whether to act: cyclomatic counts the independent arms through the body, cognitive counts what it costs to hold them in your head, so nesting and mixed boolean chains raise it while a flat run of independent arms does not. Cognitive is at or above cyclomatic here, so the branching is nested or entangled rather than laid out side by side \u2014 extracting each decision into its own named function is the change that pays. Measured by this repository\u0027s own parse of the file, so a body assembled at runtime, or generated, is counted as written rather than as it executes."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/hooks/useChatStreamingLifecycle.ts"},"region":{"startLine":372}}}],"partialFingerprints":{"codehealthFindingId/v1":"8dc744121d9ee8acb9988e0ebdbd6066a3f416837c35f934990cfae8745b512e"}},{"ruleId":"R2","level":"warning","message":{"text":"Complex function flattenTree (cyclomatic 42, cognitive 50): flattenTree has cyclomatic complexity 42 and cognitive complexity 50; this row is raised above a cyclomatic bar of 10. The two numbers answer different questions and the gap between them is what decides whether to act: cyclomatic counts the independent arms through the body, cognitive counts what it costs to hold them in your head, so nesting and mixed boolean chains raise it while a flat run of independent arms does not. Cognitive is at or above cyclomatic here, so the branching is nested or entangled rather than laid out side by side \u2014 extracting each decision into its own named function is the change that pays. Measured by this repository\u0027s own parse of the file, so a body assembled at runtime, or generated, is counted as written rather than as it executes."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/workspace-explorer/VirtualizedTree.tsx"},"region":{"startLine":255}}}],"partialFingerprints":{"codehealthFindingId/v1":"b129b3612e266e16fe6e1205561bd9d398c1f34dc66289922e4b0b4e55192149"}},{"ruleId":"R2","level":"warning","message":{"text":"Complex function compress (cyclomatic 40, cognitive 54): compress has cyclomatic complexity 40 and cognitive complexity 54; this row is raised above a cyclomatic bar of 10. The two numbers answer different questions and the gap between them is what decides whether to act: cyclomatic counts the independent arms through the body, cognitive counts what it costs to hold them in your head, so nesting and mixed boolean chains raise it while a flat run of independent arms does not. Cognitive is at or above cyclomatic here, so the branching is nested or entangled rather than laid out side by side \u2014 extracting each decision into its own named function is the change that pays. Measured by this repository\u0027s own parse of the file, so a body assembled at runtime, or generated, is counted as written rather than as it executes."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/skills/s_browser-agent/browser-agent.mjs"},"region":{"startLine":199}}}],"partialFingerprints":{"codehealthFindingId/v1":"5747cd10f37bb9ee41335db6af2828d6d3bcc508bd3836b882ce8007046cf24a"}},{"ruleId":"R2","level":"warning","message":{"text":"Complex function EngineMetricsTab (cyclomatic 40, cognitive 39): EngineMetricsTab has cyclomatic complexity 40 and cognitive complexity 39; this row is raised above a cyclomatic bar of 10. The two numbers answer different questions and the gap between them is what decides whether to act: cyclomatic counts the independent arms through the body, cognitive counts what it costs to hold them in your head, so nesting and mixed boolean chains raise it while a flat run of independent arms does not. Cognitive sits below cyclomatic here, so much of the count is breadth \u2014 arms side by side rather than stacked \u2014 and splitting per arm would leave a function per arm; group the work between the checks into named steps instead. Measured by this repository\u0027s own parse of the file, so a body assembled at runtime, or generated, is counted as written rather than as it executes."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/settings/EngineMetricsTab.tsx"},"region":{"startLine":54}}}],"partialFingerprints":{"codehealthFindingId/v1":"dda564d14f67aeff3b9df6f7a4915cd035a47b2d7f031f55a52889fdd60fadab"}},{"ruleId":"R2","level":"warning","message":{"text":"Complex function fetchFileContent (cyclomatic 39, cognitive 66): fetchFileContent has cyclomatic complexity 39 and cognitive complexity 66; this row is raised above a cyclomatic bar of 10. The two numbers answer different questions and the gap between them is what decides whether to act: cyclomatic counts the independent arms through the body, cognitive counts what it costs to hold them in your head, so nesting and mixed boolean chains raise it while a flat run of independent arms does not. Cognitive is at or above cyclomatic here, so the branching is nested or entangled rather than laid out side by side \u2014 extracting each decision into its own named function is the change that pays. Measured by this repository\u0027s own parse of the file, so a body assembled at runtime, or generated, is counted as written rather than as it executes."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/file-viewer/FileViewer.tsx"},"region":{"startLine":262}}}],"partialFingerprints":{"codehealthFindingId/v1":"0aaf561a341eab967192f7e1ad21acfec92d25f48b69f3386d293185ea83d3ed"}},{"ruleId":"R2","level":"warning","message":{"text":"Complex function FileViewerPanelImpl (cyclomatic 38, cognitive 37): FileViewerPanelImpl has cyclomatic complexity 38 and cognitive complexity 37; this row is raised above a cyclomatic bar of 10. The two numbers answer different questions and the gap between them is what decides whether to act: cyclomatic counts the independent arms through the body, cognitive counts what it costs to hold them in your head, so nesting and mixed boolean chains raise it while a flat run of independent arms does not. Cognitive sits below cyclomatic here, so much of the count is breadth \u2014 arms side by side rather than stacked \u2014 and splitting per arm would leave a function per arm; group the work between the checks into named steps instead. Measured by this repository\u0027s own parse of the file, so a body assembled at runtime, or generated, is counted as written rather than as it executes."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/file-viewer/FileViewerPanel.tsx"},"region":{"startLine":139}}}],"partialFingerprints":{"codehealthFindingId/v1":"b0790a9695b54ad5f0726ca937f96450bf12e0561d7454d4d0b129123d1e866a"}},{"ruleId":"R2","level":"warning","message":{"text":"Complex function (anonymous) (cyclomatic 34, cognitive 56): (anonymous) has cyclomatic complexity 34 and cognitive complexity 56; this row is raised above a cyclomatic bar of 10. The two numbers answer different questions and the gap between them is what decides whether to act: cyclomatic counts the independent arms through the body, cognitive counts what it costs to hold them in your head, so nesting and mixed boolean chains raise it while a flat run of independent arms does not. Cognitive is at or above cyclomatic here, so the branching is nested or entangled rather than laid out side by side \u2014 extracting each decision into its own named function is the change that pays. Measured by this repository\u0027s own parse of the file, so a body assembled at runtime, or generated, is counted as written rather than as it executes."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/skills/s_pptx/scripts/html2pptx.js"},"region":{"startLine":422}}}],"partialFingerprints":{"codehealthFindingId/v1":"b8d9cfa29dafb9f722776c1232e1da69478af08ed177bfe0fc59ada3b091cd6a"}},{"ruleId":"R2","level":"warning","message":{"text":"Complex function step (cyclomatic 34, cognitive 45): step has cyclomatic complexity 34 and cognitive complexity 45; this row is raised above a cyclomatic bar of 10. The two numbers answer different questions and the gap between them is what decides whether to act: cyclomatic counts the independent arms through the body, cognitive counts what it costs to hold them in your head, so nesting and mixed boolean chains raise it while a flat run of independent arms does not. Cognitive is at or above cyclomatic here, so the branching is nested or entangled rather than laid out side by side \u2014 extracting each decision into its own named function is the change that pays. Measured by this repository\u0027s own parse of the file, so a body assembled at runtime, or generated, is counted as written rather than as it executes."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/vite.config.js"},"region":{"startLine":14}}}],"partialFingerprints":{"codehealthFindingId/v1":"4bcf797fd4fbabf3dadf9a363bc63eb3b1ba8ceb99c9515db6e91d3f1c5319e7"}},{"ruleId":"R2","level":"warning","message":{"text":"Complex function (anonymous) (cyclomatic 33, cognitive 49): (anonymous) has cyclomatic complexity 33 and cognitive complexity 49; this row is raised above a cyclomatic bar of 10. The two numbers answer different questions and the gap between them is what decides whether to act: cyclomatic counts the independent arms through the body, cognitive counts what it costs to hold them in your head, so nesting and mixed boolean chains raise it while a flat run of independent arms does not. Cognitive is at or above cyclomatic here, so the branching is nested or entangled rather than laid out side by side \u2014 extracting each decision into its own named function is the change that pays. Measured by this repository\u0027s own parse of the file, so a body assembled at runtime, or generated, is counted as written rather than as it executes."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/pages/ChatPage.tsx"},"region":{"startLine":940}}}],"partialFingerprints":{"codehealthFindingId/v1":"846dec21b5663e97697c7d301b66c4598dcd71650b9762b4aded58bca4ae478c"}},{"ruleId":"R3","level":"warning","message":{"text":"Large Files: 45 file(s) over 400 lines (counted as significant lines \u2014 blank lines excluded \u2014 over production source only, tests excluded), largest first: desktop/src/hooks/useChatStreamingLifecycle.ts (4285), desktop/src/pages/ChatPage.tsx (3303), desktop/src/pages/EvalDashboard.tsx (2359), desktop/src/components/common/FileEditorCore.tsx (1915), desktop/src/components/layout/BrainHub.tsx (1329), desktop/src/stores/MessageStore.ts (1226) (\u002B39 more)."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"cecee31b569df4f07e06db732f1ca037af27b5afef9023da51f9673d931a142f"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/pages/SkillsPage.tsx"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"1d5671b8e0993cbdf618f5b9c3a92dd950f45384413c5516f5e945590e8fc15b"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/skills/s_pptx/scripts/html2pptx.js"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"7d9e846ca30cec01c551fe879faba6087e428bb644dad78cb3a400c7a8c8471a"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/skills/s_browser-agent/browser-agent.mjs"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"da0b220ab164e35601ee6ffe626f983e6fb4951cf691425974c570c4c5233b74"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/skills/s_pollinate/templates/remotion/components/SectionLayouts.tsx"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"eb876cd8db5e82cf25e95b7674e108926b6c9a6a617a8400709059f7d34a64c6"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/skills/s_pollinate/templates/html-deck/shared/deck-stage.js"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"5904e7511b268a256df98352e899669bfd0b9fe93ed1327a9d0ccce6f0d789de"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/skills/s_pollinate/templates/remotion/components/DiagramReveal.tsx"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"91cf6b5697376f7256a5d713b3ad067bf04278d39a456776166813ead0a26ba3"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/skills/s_pollinate/templates/remotion/Video.tsx"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"f150ea0da9f68ee7bc9232973f6806e3b37ebd60ec705c23d81977812f034825"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/workspace/FolderPickerModal.tsx"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"ad319f3507c6ea218cfbfae77a2cc1654e352e82fd86eeb7db65ae2d80be2712"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/workspace/FileBrowser.tsx"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"313f7c6069af7cf854d4b1d54d14a6836f5a021e6a5adbbb6cd0fce66260ddd8"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/skills/s_pollinate/templates/remotion/components/animations.tsx"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"7185779b58c8904b6a21bc532253af22312e5f53d112c14c8090d32b49f55f7a"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/skills/s_pollinate/templates/remotion/components/AnimatedBackground.tsx"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"9da584a69ab52ee746e6ef7e4f60d467c049bafd4c7af0a85fa251f6ff5ac4a0"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/skills/s_pollinate/templates/remotion/Root.tsx"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"24355b6580ac37b17387fa5859fbac4bae06eb10efa6d1daa333b25d5142a58f"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/skills/s_pollinate/templates/remotion/components/FlowChart.tsx"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"2c902a50a401a0721bed46e81e5fa33813588473a1bca09ccdf8d549e91140f0"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/skills/s_pollinate/templates/remotion/components/Subtitles.tsx"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"22567a229a3d7b98b96269beae07ccd0050b96d3467363708a59fdcde4c5453e"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/skills/s_pollinate/templates/remotion/components/Timeline.tsx"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"152f825b157fb21392fb49361feb54c6429340cd482f4bda54878e47d9e3636f"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/skills/s_pollinate/templates/remotion/components/AudioWaveform.tsx"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"49d7e9bc96484e94ecd74a656cedc67642cd4206d345165cc0777286ccbd556f"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/skills/s_pollinate/templates/remotion/components/MediaSection.tsx"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"3026611fb48e0117b4e0bd9facb0ae2d741cd35d8954c9117a2b5e9d2af0c8a6"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"scripts/generate-update-manifest.js"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"4d472c483e3c90455126a9fc4033a4973d776316988ef0c60d0ddf908d29723a"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/skills/s_pollinate/templates/remotion/components/ChapterProgressBar.tsx"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"cc4de175bb446ca5bf59c3517e214027653c41a38f38281e0001c10a71ddd008"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/services/logForwarder.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"3bb2ce242ffc452f8d3a4736d87b774b7c9132d1c4a2a32f500ca9e879c6bf38"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/skills/s_pollinate/templates/remotion/Thumbnail.tsx"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"65e750b41f8143bb56120f5a3f131afb4cbc1adc3e112124cdc6fb4f30bd11a2"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/skills/s_pollinate/templates/remotion/components/LottieAnimation.tsx"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"bbab7ef01d92302ef4ceb2fc10442bf95bf4ebbab73e1d42a27ec099fbd27c3b"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/modals/ConvertToTaskModal.tsx"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"6eb6d464a6ac3f93ab0fe02eeff256406647e17562fd15a9e618f81744817826"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/pages/chat/components/radar/EvolutionBadge.tsx"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"ecdc2bb0c9d7861a1f62c31a1197d8dd354391428feb17be317cb7364631cbf5"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/skills/s_pollinate/templates/remotion/components/Icon.tsx"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"19e866567c2b3993f69523aad7b1b1df86c949578278b1933898925bfbf8faa3"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/skills/s_pollinate/templates/remotion/components/DataTable.tsx"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"9a97a67adb3181d6b2e2b8e4bbde54fe72be5283a9a8ccd068606a71b038b92a"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/skills/s_pollinate/templates/remotion/components/useTiming.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"934e36f8c2a5c846c9c72ccf63930d90a58b4448aab8154a3a4a1e4575f6909b"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/skills/s_pollinate/templates/remotion/components/ComparisonCard.tsx"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"4092ea4d396e2aee08666e1fbd8d65d2510f59cabb8d57e20a020cb0e0fff867"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/skills/s_pollinate/templates/remotion/components/ErrorBoundary.tsx"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"cfe9136ce0986d2b29a9949cd895d56e0b0fca82499833cd39ddcab38e23c731"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/skills/s_pollinate/templates/remotion/components/ShortIntroCard.tsx"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"6c1d2b15dd3bef8fc52f0a6c7fa18709cf2743846208370180df2bbd0ca7cf5d"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/skills/s_pollinate/templates/remotion/components/layouts.tsx"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"f38ccafe4a1cc1fdd417747b655c1cd6645220baadbada83949f8789918166ba"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/skills/s_pollinate/templates/remotion/components/FeatureGrid.tsx"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"ef8727cc7d78d4562b823556bf8d9b7df540e847e6d14dcd1ff90b0fa6af44c8"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/skills/s_pollinate/templates/remotion/components/QuoteBlock.tsx"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"43dff03b7a1ae27dff07372fb6f1cf8fe642b5caba369597f05e72cf273422d6"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/skills/s_pollinate/templates/remotion/components/StatCounter.tsx"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"1811dd297290d20624724bc42a23ee07d495cdab7dd317e486e94535fc5bc48a"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/skills/s_pollinate/templates/remotion/components/IconCard.tsx"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"20d28a22f13bbae02cda7e7d72841ecc89f404bad1871f3d5a374b4c2b6ad5a1"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/skills/s_pollinate/templates/remotion/components/DataBar.tsx"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"0be5bd3e2c956e06c0b0ec575bc9135f9ac25fe26f39d26686f659fb618a5531"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/main.tsx"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"70a0c832da41e235b217a5038f0c5a541f7fc5aa9ace6303495c277a2724a161"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/skills/s_pollinate/templates/remotion/components/CodeBlock.tsx"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"f73cfd3f2abe6017695287ea154f8e716cdad0f70c4de4f7a5960428f9a15bef"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/skills/s_pollinate/templates/remotion/components/ShortCTACard.tsx"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"94f0579ce4e5d3a7c25cf91b1b163f93c69dc1414f24636bfc75f621ac7b9609"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/services/radar.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"d65dcd86b686f84a83ae526e1e7f63b4006acb6eccdb293160614212f9cbf170"}},{"ruleId":"R7","level":"warning","message":{"text":"Dead file (~1074 LoC): no import path from any entry point (60 application, 13 tooling, 253 test roots considered), but 1 in-repo import(s) from 1 other file(s) do name it (desktop/src/components/settings/SkillsTab.tsx) \u2014 every one of those referrers is itself unreachable, so this file is dead only as a member of that cluster: if any referrer is in fact alive, this row falls with it"},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/pages/SkillsPage.tsx"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"dabc7ede787b97f0bf36728e2aca2d4df3323659d9973dfe4ee4e58c09865ebc"}},{"ruleId":"R7","level":"warning","message":{"text":"Dead file (~979 LoC): no import path from any entry point (60 application, 13 tooling, 253 test roots considered), and no other file in the scanned tree imports it \u2014 nothing in-repo names this module at all, which is the strongest form of this claim the import graph can make"},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/skills/s_pptx/scripts/html2pptx.js"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"47cc0355710b2e96c174e8219f6e185488b0f5df386ada01c7f1e74c61057e8c"}},{"ruleId":"R7","level":"warning","message":{"text":"Dead file (~322 LoC): no import path from any entry point (60 application, 13 tooling, 253 test roots considered), and no other file in the scanned tree imports it \u2014 nothing in-repo names this module at all, which is the strongest form of this claim the import graph can make"},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/workspace/FolderPickerModal.tsx"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"24e21678000cc8bce46a82f7272c8e062286a3714a21d48bf2e83ab13fca5c1b"}},{"ruleId":"R7","level":"warning","message":{"text":"Dead file (~272 LoC): no import path from any entry point (60 application, 13 tooling, 253 test roots considered), and no other file in the scanned tree imports it \u2014 nothing in-repo names this module at all, which is the strongest form of this claim the import graph can make"},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/workspace/FileBrowser.tsx"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"d7772b88ea6773431dad5a299902faa18b089ef2518f8a437b2455cb98ca7c29"}},{"ruleId":"R7","level":"warning","message":{"text":"Dead file (~101 LoC): no import path from any entry point (60 application, 13 tooling, 253 test roots considered), and no other file in the scanned tree imports it \u2014 nothing in-repo names this module at all, which is the strongest form of this claim the import graph can make"},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/modals/ConvertToTaskModal.tsx"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"00f353660f9d6161bd23d28017f8df81ba4c242497e6b1207dd318a711ea7337"}},{"ruleId":"R7","level":"warning","message":{"text":"Dead file (~91 LoC): no import path from any entry point (60 application, 13 tooling, 253 test roots considered), and no other file in the scanned tree imports it \u2014 nothing in-repo names this module at all, which is the strongest form of this claim the import graph can make"},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/pages/chat/components/radar/EvolutionBadge.tsx"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"cc8531e1d1fe838edd072387a848fe95d55ff98236eb82ae19d67caa017aa4a7"}},{"ruleId":"R7","level":"warning","message":{"text":"Dead file (~39 LoC): no import path from any entry point (60 application, 13 tooling, 253 test roots considered), and no other file in the scanned tree imports it \u2014 nothing in-repo names this module at all, which is the strongest form of this claim the import graph can make"},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/services/radar.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"85de5e4582be59b1ae60db25000be88feeab09b888c390434efad481e39cd64c"}},{"ruleId":"R7","level":"warning","message":{"text":"Dead file (~18 LoC): no import path from any entry point (60 application, 13 tooling, 253 test roots considered), and no other file in the scanned tree imports it \u2014 nothing in-repo names this module at all, which is the strongest form of this claim the import graph can make"},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/settings/SkillsTab.tsx"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"d45b1927bb442528d4a3048ec17a604288ba71e9cc6b198b790794837efd88af"}},{"ruleId":"R7","level":"warning","message":{"text":"Dead file (~13 LoC): no import path from any entry point (60 application, 13 tooling, 253 test roots considered), and no other file in the scanned tree imports it \u2014 nothing in-repo names this module at all, which is the strongest form of this claim the import graph can make"},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/modals/index.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"4fd56d9dd6e5f4333370da5a26e6dc46d2932a43fd038328822194538839a0db"}},{"ruleId":"R7","level":"warning","message":{"text":"Dead file (~12 LoC): no import path from any entry point (60 application, 13 tooling, 253 test roots considered), and no other file in the scanned tree imports it \u2014 nothing in-repo names this module at all, which is the strongest form of this claim the import graph can make"},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/settings/MCPServersTab.tsx"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"ffe74cb9d84f4f1255578cb849e0a139206482733b58f701cc60b419c4f805c2"}},{"ruleId":"R7","level":"warning","message":{"text":"Dead file (~12 LoC): no import path from any entry point (60 application, 13 tooling, 253 test roots considered), and no other file in the scanned tree imports it \u2014 nothing in-repo names this module at all, which is the strongest form of this claim the import graph can make"},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/stores/index.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"d0f9bcde8e33e48384374a56b7148557740e59aba1c044f9f9c323b888c8ac71"}},{"ruleId":"R7","level":"warning","message":{"text":"Dead file (~9 LoC): no import path from any entry point (60 application, 13 tooling, 253 test roots considered), and no other file in the scanned tree imports it \u2014 nothing in-repo names this module at all, which is the strongest form of this claim the import graph can make"},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/layout/index.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"7bde9c2aa1bb09742bd5445c3273597f9300092d50e29effd668f0ee06d53af0"}},{"ruleId":"R7","level":"note","message":{"text":"Unused export \u0027default\u0027: Nothing imports this binding \u2014 it is safe to review for removal."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/skills/s_pollinate/templates/remotion/Thumbnail.tsx"},"region":{"startLine":105}}}],"partialFingerprints":{"codehealthFindingId/v1":"9553300b53c28dfd51aee6921de34b3979a0576344ba51db17fbc470a19f7e0c"}},{"ruleId":"R7","level":"note","message":{"text":"Unused export \u0027default\u0027: Nothing imports this binding \u2014 it is safe to review for removal."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/skills/s_pollinate/templates/remotion/Video.tsx"},"region":{"startLine":360}}}],"partialFingerprints":{"codehealthFindingId/v1":"e230424bc1c9e1c539b6837184bb506084c855220022196cffa46983d83349c6"}},{"ruleId":"R7","level":"note","message":{"text":"Unused export \u0027AudioWaveform\u0027: Nothing ultimately consumes this binding: its only referrer is the re-export in backend/skills/s_pollinate/templates/remotion/components/index.ts, whose re-exported name has no consumer either. Removing it is therefore not a one-file change \u2014 drop the re-export line in backend/skills/s_pollinate/templates/remotion/components/index.ts in the same commit, or the barrel will import a name that no longer exists."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/skills/s_pollinate/templates/remotion/components/AudioWaveform.tsx"},"region":{"startLine":19}}}],"partialFingerprints":{"codehealthFindingId/v1":"0d34dd1de8c4f47920363337a2d1d2824a9471fd3c12834ba1ae00899db3d732"}},{"ruleId":"R7","level":"note","message":{"text":"Unused export \u0027CodeBlock\u0027: Nothing ultimately consumes this binding: its only referrer is the re-export in backend/skills/s_pollinate/templates/remotion/components/index.ts, whose re-exported name has no consumer either. Removing it is therefore not a one-file change \u2014 drop the re-export line in backend/skills/s_pollinate/templates/remotion/components/index.ts in the same commit, or the barrel will import a name that no longer exists."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/skills/s_pollinate/templates/remotion/components/CodeBlock.tsx"},"region":{"startLine":5}}}],"partialFingerprints":{"codehealthFindingId/v1":"86819517dd8f23e0882de69aa39c2814361957dad681b05a90c2a084cd5c5d11"}},{"ruleId":"R7","level":"note","message":{"text":"Unused export \u0027ComparisonCard\u0027: Nothing ultimately consumes this binding: its only referrer is the re-export in backend/skills/s_pollinate/templates/remotion/components/index.ts, whose re-exported name has no consumer either. Removing it is therefore not a one-file change \u2014 drop the re-export line in backend/skills/s_pollinate/templates/remotion/components/index.ts in the same commit, or the barrel will import a name that no longer exists."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/skills/s_pollinate/templates/remotion/components/ComparisonCard.tsx"},"region":{"startLine":5}}}],"partialFingerprints":{"codehealthFindingId/v1":"575bd3bb4214d2758985b24cc4f6b609364293a8a4e8bc9f4a521f7b8d45fdf9"}},{"ruleId":"R7","level":"note","message":{"text":"Unused export \u0027DataBar\u0027: Nothing ultimately consumes this binding: its only referrer is the re-export in backend/skills/s_pollinate/templates/remotion/components/index.ts, whose re-exported name has no consumer either. Removing it is therefore not a one-file change \u2014 drop the re-export line in backend/skills/s_pollinate/templates/remotion/components/index.ts in the same commit, or the barrel will import a name that no longer exists."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/skills/s_pollinate/templates/remotion/components/DataBar.tsx"},"region":{"startLine":5}}}],"partialFingerprints":{"codehealthFindingId/v1":"f97ef71bc67c7279dbbfb0763a76e3647ee60f8ff19786f1c1ac05e18c42c9e6"}},{"ruleId":"R7","level":"note","message":{"text":"Unused export \u0027DataTable\u0027: Nothing ultimately consumes this binding: its only referrer is the re-export in backend/skills/s_pollinate/templates/remotion/components/index.ts, whose re-exported name has no consumer either. Removing it is therefore not a one-file change \u2014 drop the re-export line in backend/skills/s_pollinate/templates/remotion/components/index.ts in the same commit, or the barrel will import a name that no longer exists."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/skills/s_pollinate/templates/remotion/components/DataTable.tsx"},"region":{"startLine":5}}}],"partialFingerprints":{"codehealthFindingId/v1":"97b2db494875c247713694c6ebaf07fbc577f0f812cd8544968e954605a0681e"}},{"ruleId":"R7","level":"note","message":{"text":"Unused export \u0027DiagramReveal\u0027: Nothing ultimately consumes this binding: its only referrer is the re-export in backend/skills/s_pollinate/templates/remotion/components/index.ts, whose re-exported name has no consumer either. Removing it is therefore not a one-file change \u2014 drop the re-export line in backend/skills/s_pollinate/templates/remotion/components/index.ts in the same commit, or the barrel will import a name that no longer exists."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/skills/s_pollinate/templates/remotion/components/DiagramReveal.tsx"},"region":{"startLine":390}}}],"partialFingerprints":{"codehealthFindingId/v1":"0d404889e46da89d9948df21089f9a6a9d987d2590984ec213c4888085bd5074"}},{"ruleId":"R7","level":"note","message":{"text":"Unused export \u0027ErrorBoundary\u0027: Nothing ultimately consumes this binding: its only referrer is the re-export in backend/skills/s_pollinate/templates/remotion/components/index.ts, whose re-exported name has no consumer either. Removing it is therefore not a one-file change \u2014 drop the re-export line in backend/skills/s_pollinate/templates/remotion/components/index.ts in the same commit, or the barrel will import a name that no longer exists."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/skills/s_pollinate/templates/remotion/components/ErrorBoundary.tsx"},"region":{"startLine":15}}}],"partialFingerprints":{"codehealthFindingId/v1":"b1d1be6393f8c79fd6986834bd1f1eef513cb28b67c00011cd25db8b6a512275"}},{"ruleId":"R7","level":"note","message":{"text":"Unused export \u0027FeatureGrid\u0027: Nothing ultimately consumes this binding: its only referrer is the re-export in backend/skills/s_pollinate/templates/remotion/components/index.ts, whose re-exported name has no consumer either. Removing it is therefore not a one-file change \u2014 drop the re-export line in backend/skills/s_pollinate/templates/remotion/components/index.ts in the same commit, or the barrel will import a name that no longer exists."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/skills/s_pollinate/templates/remotion/components/FeatureGrid.tsx"},"region":{"startLine":5}}}],"partialFingerprints":{"codehealthFindingId/v1":"d05a703ff7b79f50238f4152056647208963e762dedf9d4b87492d8ebcc45947"}},{"ruleId":"R7","level":"note","message":{"text":"Unused export \u0027FlowChart\u0027: Nothing ultimately consumes this binding: its only referrer is the re-export in backend/skills/s_pollinate/templates/remotion/components/index.ts, whose re-exported name has no consumer either. Removing it is therefore not a one-file change \u2014 drop the re-export line in backend/skills/s_pollinate/templates/remotion/components/index.ts in the same commit, or the barrel will import a name that no longer exists."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/skills/s_pollinate/templates/remotion/components/FlowChart.tsx"},"region":{"startLine":130}}}],"partialFingerprints":{"codehealthFindingId/v1":"d1cbf14d2ae31a27508d6a1902e0838f88986087772e3bce5a2be48368b0b866"}},{"ruleId":"R7","level":"note","message":{"text":"Unused export \u0027LottieAnimation\u0027: Nothing ultimately consumes this binding: its only referrer is the re-export in backend/skills/s_pollinate/templates/remotion/components/index.ts, whose re-exported name has no consumer either. Removing it is therefore not a one-file change \u2014 drop the re-export line in backend/skills/s_pollinate/templates/remotion/components/index.ts in the same commit, or the barrel will import a name that no longer exists."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/skills/s_pollinate/templates/remotion/components/LottieAnimation.tsx"},"region":{"startLine":23}}}],"partialFingerprints":{"codehealthFindingId/v1":"2f2ab1cad3124c6b6062ec6aecca90600c05e5aded9e627b4ca3a9a2fad150a4"}},{"ruleId":"R7","level":"note","message":{"text":"Unused export \u0027MediaGrid\u0027: Nothing ultimately consumes this binding: its only referrer is the re-export in backend/skills/s_pollinate/templates/remotion/components/index.ts, whose re-exported name has no consumer either. Removing it is therefore not a one-file change \u2014 drop the re-export line in backend/skills/s_pollinate/templates/remotion/components/index.ts in the same commit, or the barrel will import a name that no longer exists."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/skills/s_pollinate/templates/remotion/components/MediaSection.tsx"},"region":{"startLine":83}}}],"partialFingerprints":{"codehealthFindingId/v1":"e23f207a8ea348d78bc15f47e2f70a9e1b2b2be53bee5f5df14c1d6a15606804"}},{"ruleId":"R7","level":"note","message":{"text":"Unused export \u0027QuoteBlock\u0027: Nothing ultimately consumes this binding: its only referrer is the re-export in backend/skills/s_pollinate/templates/remotion/components/index.ts, whose re-exported name has no consumer either. Removing it is therefore not a one-file change \u2014 drop the re-export line in backend/skills/s_pollinate/templates/remotion/components/index.ts in the same commit, or the barrel will import a name that no longer exists."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/skills/s_pollinate/templates/remotion/components/QuoteBlock.tsx"},"region":{"startLine":5}}}],"partialFingerprints":{"codehealthFindingId/v1":"11cbfb6b24a101f01232e2ec3dad727bc10feb35c3fd2dc5fe894785e084efbe"}},{"ruleId":"R7","level":"note","message":{"text":"Unused export \u0027SplitLayout\u0027: Nothing ultimately consumes this binding: its only referrer is the re-export in backend/skills/s_pollinate/templates/remotion/components/index.ts, whose re-exported name has no consumer either. Removing it is therefore not a one-file change \u2014 drop the re-export line in backend/skills/s_pollinate/templates/remotion/components/index.ts in the same commit, or the barrel will import a name that no longer exists."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/skills/s_pollinate/templates/remotion/components/SectionLayouts.tsx"},"region":{"startLine":30}}}],"partialFingerprints":{"codehealthFindingId/v1":"bffebd7eca3be06b7df5ee2be8796219e06b8447639cd3f3a29539c1fa176eee"}},{"ruleId":"R7","level":"note","message":{"text":"Unused export \u0027StatHighlight\u0027: Nothing ultimately consumes this binding: its only referrer is the re-export in backend/skills/s_pollinate/templates/remotion/components/index.ts, whose re-exported name has no consumer either. Removing it is therefore not a one-file change \u2014 drop the re-export line in backend/skills/s_pollinate/templates/remotion/components/index.ts in the same commit, or the barrel will import a name that no longer exists."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/skills/s_pollinate/templates/remotion/components/SectionLayouts.tsx"},"region":{"startLine":124}}}],"partialFingerprints":{"codehealthFindingId/v1":"83a136ef55f1e405392fb242c95f52f516e4358f75313b4b4445cb12f44dddc8"}},{"ruleId":"R7","level":"note","message":{"text":"Unused export \u0027ZigzagCards\u0027: Nothing ultimately consumes this binding: its only referrer is the re-export in backend/skills/s_pollinate/templates/remotion/components/index.ts, whose re-exported name has no consumer either. Removing it is therefore not a one-file change \u2014 drop the re-export line in backend/skills/s_pollinate/templates/remotion/components/index.ts in the same commit, or the barrel will import a name that no longer exists."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/skills/s_pollinate/templates/remotion/components/SectionLayouts.tsx"},"region":{"startLine":206}}}],"partialFingerprints":{"codehealthFindingId/v1":"a505d2a6a2dac2149a8da0595d4ed8d5dc363505aafbd28fe7c1cfbff11bb8fd"}},{"ruleId":"R7","level":"note","message":{"text":"Unused export \u0027CenteredShowcase\u0027: Nothing ultimately consumes this binding: its only referrer is the re-export in backend/skills/s_pollinate/templates/remotion/components/index.ts, whose re-exported name has no consumer either. Removing it is therefore not a one-file change \u2014 drop the re-export line in backend/skills/s_pollinate/templates/remotion/components/index.ts in the same commit, or the barrel will import a name that no longer exists."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/skills/s_pollinate/templates/remotion/components/SectionLayouts.tsx"},"region":{"startLine":318}}}],"partialFingerprints":{"codehealthFindingId/v1":"4222b38b893b3eaf9bdaa4e5d60e8f12180ba25f0245a3e22da0036480f14e9f"}},{"ruleId":"R7","level":"note","message":{"text":"Unused export \u0027MetricsRow\u0027: Nothing ultimately consumes this binding: its only referrer is the re-export in backend/skills/s_pollinate/templates/remotion/components/index.ts, whose re-exported name has no consumer either. Removing it is therefore not a one-file change \u2014 drop the re-export line in backend/skills/s_pollinate/templates/remotion/components/index.ts in the same commit, or the barrel will import a name that no longer exists."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/skills/s_pollinate/templates/remotion/components/SectionLayouts.tsx"},"region":{"startLine":387}}}],"partialFingerprints":{"codehealthFindingId/v1":"b030d8c498a3b64cc47fed1876d7e2e3babb79ee1ae94dfb442ba1baf257a614"}},{"ruleId":"R7","level":"note","message":{"text":"Unused export \u0027StepProgress\u0027: Nothing ultimately consumes this binding: its only referrer is the re-export in backend/skills/s_pollinate/templates/remotion/components/index.ts, whose re-exported name has no consumer either. Removing it is therefore not a one-file change \u2014 drop the re-export line in backend/skills/s_pollinate/templates/remotion/components/index.ts in the same commit, or the barrel will import a name that no longer exists."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/skills/s_pollinate/templates/remotion/components/SectionLayouts.tsx"},"region":{"startLine":511}}}],"partialFingerprints":{"codehealthFindingId/v1":"aa7cb6b4b79bdbee0011843f0ac3c5c37989dda1aa0b00d79dee7137700b8ebe"}},{"ruleId":"R7","level":"note","message":{"text":"Unused export \u0027ShortCTACard\u0027: Nothing ultimately consumes this binding: its only referrer is the re-export in backend/skills/s_pollinate/templates/remotion/components/index.ts, whose re-exported name has no consumer either. Removing it is therefore not a one-file change \u2014 drop the re-export line in backend/skills/s_pollinate/templates/remotion/components/index.ts in the same commit, or the barrel will import a name that no longer exists."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/skills/s_pollinate/templates/remotion/components/ShortCTACard.tsx"},"region":{"startLine":5}}}],"partialFingerprints":{"codehealthFindingId/v1":"ca769d8080d79920ff1ad140f428f7fa1b9aef9a48ae032f780052547fbc0832"}},{"ruleId":"R7","level":"note","message":{"text":"Unused export \u0027ShortIntroCard\u0027: Nothing ultimately consumes this binding: its only referrer is the re-export in backend/skills/s_pollinate/templates/remotion/components/index.ts, whose re-exported name has no consumer either. Removing it is therefore not a one-file change \u2014 drop the re-export line in backend/skills/s_pollinate/templates/remotion/components/index.ts in the same commit, or the barrel will import a name that no longer exists."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/skills/s_pollinate/templates/remotion/components/ShortIntroCard.tsx"},"region":{"startLine":4}}}],"partialFingerprints":{"codehealthFindingId/v1":"b394e553b9897d375a295c00ae2e0bef40b863fe9db0ce22b5401bdfa0d3e1f1"}},{"ruleId":"R7","level":"note","message":{"text":"Unused export \u0027StatCounter\u0027: Nothing ultimately consumes this binding: its only referrer is the re-export in backend/skills/s_pollinate/templates/remotion/components/index.ts, whose re-exported name has no consumer either. Removing it is therefore not a one-file change \u2014 drop the re-export line in backend/skills/s_pollinate/templates/remotion/components/index.ts in the same commit, or the barrel will import a name that no longer exists."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/skills/s_pollinate/templates/remotion/components/StatCounter.tsx"},"region":{"startLine":6}}}],"partialFingerprints":{"codehealthFindingId/v1":"962ddc36daad8a18e4ab78e9577791ee8e0f9986d2d6cfa7d6d1ca74b11578c0"}},{"ruleId":"R7","level":"note","message":{"text":"Unused export \u0027Timeline\u0027: Nothing ultimately consumes this binding: its only referrer is the re-export in backend/skills/s_pollinate/templates/remotion/components/index.ts, whose re-exported name has no consumer either. Removing it is therefore not a one-file change \u2014 drop the re-export line in backend/skills/s_pollinate/templates/remotion/components/index.ts in the same commit, or the barrel will import a name that no longer exists."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/skills/s_pollinate/templates/remotion/components/Timeline.tsx"},"region":{"startLine":79}}}],"partialFingerprints":{"codehealthFindingId/v1":"e18974f5ec2efd810969e402f480c921f22379533ae867d2ee0378a0ed981288"}},{"ruleId":"R7","level":"note","message":{"text":"Unused export \u0027useExit\u0027: Nothing ultimately consumes this binding: its only referrer is the re-export in backend/skills/s_pollinate/templates/remotion/components/index.ts, whose re-exported name has no consumer either. Removing it is therefore not a one-file change \u2014 drop the re-export line in backend/skills/s_pollinate/templates/remotion/components/index.ts in the same commit, or the barrel will import a name that no longer exists."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/skills/s_pollinate/templates/remotion/components/animations.tsx"},"region":{"startLine":40}}}],"partialFingerprints":{"codehealthFindingId/v1":"7deff6d55f28a9be59c72e126e82df9289a13d8088a4728efa2a1e0e6f20eedf"}},{"ruleId":"R7","level":"note","message":{"text":"Unused export \u0027useTextReveal\u0027: Nothing ultimately consumes this binding: its only referrer is the re-export in backend/skills/s_pollinate/templates/remotion/components/index.ts, whose re-exported name has no consumer either. Removing it is therefore not a one-file change \u2014 drop the re-export line in backend/skills/s_pollinate/templates/remotion/components/index.ts in the same commit, or the barrel will import a name that no longer exists."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/skills/s_pollinate/templates/remotion/components/animations.tsx"},"region":{"startLine":134}}}],"partialFingerprints":{"codehealthFindingId/v1":"6892b0c1c214dafb19be3c85277a669782041c2e306ede81300a8c8f4836e74d"}},{"ruleId":"R8","level":"warning","message":{"text":"Unused dependency \u0027@tauri-apps/plugin-notification\u0027: Declared in desktop/package.json but never imported anywhere in that package or its workspace members \u2014 no static import reaches it. Usually that is dead weight and attack surface, but two shapes are indistinguishable from source and are NOT dead: an optional or native peer that another dependency loads dynamically at runtime, and a package a build, docs or test step installs and invokes separately. Confirm which of the three this is before removing it."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"7525efbc83b6d3c4d092f7eea3ca34a7d6d5d04ec8827b85449067f8a4e08e51"}},{"ruleId":"R8","level":"warning","message":{"text":"Unused dependency \u0027@tauri-apps/plugin-shell\u0027: Declared in desktop/package.json but never imported anywhere in that package or its workspace members \u2014 no static import reaches it. Usually that is dead weight and attack surface, but two shapes are indistinguishable from source and are NOT dead: an optional or native peer that another dependency loads dynamically at runtime, and a package a build, docs or test step installs and invokes separately. Confirm which of the three this is before removing it."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"90f8ee99b754d9c2cafe1d1112f44c2d413bb99f13601cd251b7573da553a3da"}},{"ruleId":"R9","level":"error","message":{"text":"Import cycle (2 files): desktop/src/components/common/FileEditorCore.tsx \u2192 desktop/src/components/common/FileEditorModal.tsx \u2192 desktop/src/components/common/FileEditorCore.tsx"},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/common/FileEditorCore.tsx"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"f474d46bd0f637b24b719e3d8427b2a4fd3bfd71a5cab27d8b5ec2ce180b0468"}},{"ruleId":"R9","level":"error","message":{"text":"Import cycle (2 files): desktop/src/components/workspace-explorer/TreeNodeRow.tsx \u2192 desktop/src/components/workspace-explorer/VirtualizedTree.tsx \u2192 desktop/src/components/workspace-explorer/TreeNodeRow.tsx"},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"desktop/src/components/workspace-explorer/TreeNodeRow.tsx"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"9e4eafdaac5e7832f9a15d47518d5aea8d7e3325689acf806e2f85ee14cf9bef"}},{"ruleId":"S1","level":"note","message":{"text":"No security response headers detected: No Content-Security-Policy / X-Frame-Options / X-Content-Type-Options configuration found \u2014 defense in depth, even when a reverse proxy could set them. This is reported because \u0060Caddyfile\u0060 is committed to this repository and declares the server that serves it, so the configuration that would carry these headers is in this repository and was read in full. (\u22122.0 on this card.)"},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"hive/Caddyfile"},"region":{"startLine":19}}}],"partialFingerprints":{"codehealthFindingId/v1":"5ac68d009b03e7274e76af1184f62e2ad068e48931443c6a3b0153407d668ee9"}}],"taxonomies":[{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d","organization":"MITRE","informationUri":"https://cwe.mitre.org/","isComprehensive":false,"shortDescription":{"text":"The MITRE Common Weakness Enumeration (CWE)."},"taxa":[{"id":"CWE-1059","guid":"a2381a08-60f6-9554-a8b8-f3018cfaaca5","name":"Insufficient Technical Documentation","shortDescription":{"text":"Insufficient Technical Documentation"},"helpUri":"https://cwe.mitre.org/data/definitions/1059.html"},{"id":"CWE-1357","guid":"e4d2e772-757e-0a5c-bd7d-77052949d866","name":"Reliance on Insufficiently Trustworthy Component","shortDescription":{"text":"Reliance on Insufficiently Trustworthy Component"},"helpUri":"https://cwe.mitre.org/data/definitions/1357.html"},{"id":"CWE-1395","guid":"800e09e7-c11a-8654-9fa6-86f398995fed","name":"Dependency on Vulnerable Third-Party Component","shortDescription":{"text":"Dependency on Vulnerable Third-Party Component"},"helpUri":"https://cwe.mitre.org/data/definitions/1395.html"},{"id":"CWE-259","guid":"ae9ad959-fbb6-9d5e-892d-3dca66da0b69","name":"Use of Hard-coded Password","shortDescription":{"text":"Use of Hard-coded Password"},"helpUri":"https://cwe.mitre.org/data/definitions/259.html"},{"id":"CWE-327","guid":"e51910ff-67b5-3c51-aa3d-92837d9eab90","name":"CWE-327","shortDescription":{"text":"CWE-327"},"helpUri":"https://cwe.mitre.org/data/definitions/327.html"},{"id":"CWE-345","guid":"d80d4b65-bbbe-b65d-958e-7ac466af18f9","name":"CWE-345","shortDescription":{"text":"CWE-345"},"helpUri":"https://cwe.mitre.org/data/definitions/345.html"},{"id":"CWE-353","guid":"09d7e902-d4ee-f05d-ae6c-0a1554d0c18f","name":"CWE-353","shortDescription":{"text":"CWE-353"},"helpUri":"https://cwe.mitre.org/data/definitions/353.html"},{"id":"CWE-494","guid":"b8a65e0d-e459-4a55-a931-fc1136482375","name":"Download of Code Without Integrity Check","shortDescription":{"text":"Download of Code Without Integrity Check"},"helpUri":"https://cwe.mitre.org/data/definitions/494.html"},{"id":"CWE-506","guid":"401d6455-56e3-0552-9a39-f77461673e3f","name":"CWE-506","shortDescription":{"text":"CWE-506"},"helpUri":"https://cwe.mitre.org/data/definitions/506.html"},{"id":"CWE-522","guid":"71fb233e-ce6a-ae57-9419-ef8373540b09","name":"CWE-522","shortDescription":{"text":"CWE-522"},"helpUri":"https://cwe.mitre.org/data/definitions/522.html"},{"id":"CWE-532","guid":"1cd8877a-76e8-ce54-b40b-779af23364a0","name":"CWE-532","shortDescription":{"text":"CWE-532"},"helpUri":"https://cwe.mitre.org/data/definitions/532.html"},{"id":"CWE-552","guid":"3492436b-eca2-9c54-9ba3-5dade427c903","name":"CWE-552","shortDescription":{"text":"CWE-552"},"helpUri":"https://cwe.mitre.org/data/definitions/552.html"},{"id":"CWE-611","guid":"1afbae66-ea29-2d59-aaa2-134e3ae2e85a","name":"CWE-611","shortDescription":{"text":"CWE-611"},"helpUri":"https://cwe.mitre.org/data/definitions/611.html"},{"id":"CWE-77","guid":"332c8ade-6612-9f56-a06b-d8d90b1a8750","name":"Command Injection","shortDescription":{"text":"Command Injection"},"helpUri":"https://cwe.mitre.org/data/definitions/77.html"},{"id":"CWE-78","guid":"2e31ceaf-c7ae-2e5e-9661-cfb1362789cf","name":"OS Command Injection","shortDescription":{"text":"OS Command Injection"},"helpUri":"https://cwe.mitre.org/data/definitions/78.html"},{"id":"CWE-79","guid":"fd45580b-e8c4-fc5e-8c2f-aa8fab0b4dbf","name":"Cross-site Scripting (XSS)","shortDescription":{"text":"Cross-site Scripting (XSS)"},"helpUri":"https://cwe.mitre.org/data/definitions/79.html"},{"id":"CWE-798","guid":"5e8f057d-fee3-995a-a0cb-9fc5b0d174d1","name":"Use of Hard-coded Credentials","shortDescription":{"text":"Use of Hard-coded Credentials"},"helpUri":"https://cwe.mitre.org/data/definitions/798.html"},{"id":"CWE-829","guid":"13c33925-97fb-5a5e-b40c-56d328b8a4d7","name":"CWE-829","shortDescription":{"text":"CWE-829"},"helpUri":"https://cwe.mitre.org/data/definitions/829.html"},{"id":"CWE-89","guid":"6d08fdad-37eb-c150-bbf0-d7d946863407","name":"SQL Injection","shortDescription":{"text":"SQL Injection"},"helpUri":"https://cwe.mitre.org/data/definitions/89.html"},{"id":"CWE-937","guid":"16f316ae-415c-b354-a59b-1f7905f756e9","name":"Using Components with Known Vulnerabilities","shortDescription":{"text":"Using Components with Known Vulnerabilities"},"helpUri":"https://cwe.mitre.org/data/definitions/937.html"},{"id":"CWE-939","guid":"12397742-f2c4-8254-8012-482c3356c551","name":"CWE-939","shortDescription":{"text":"CWE-939"},"helpUri":"https://cwe.mitre.org/data/definitions/939.html"},{"id":"CWE-94","guid":"75e7f50c-6c2f-dd52-bf40-bf6c52b861fd","name":"Code Injection","shortDescription":{"text":"Code Injection"},"helpUri":"https://cwe.mitre.org/data/definitions/94.html"}]}],"properties":{"codehealthPublication":{"public":true,"notice":"This is the PUBLIC form of this artifact. Findings are listed in full, but the details of SECURITY findings \u2014 which rule fired, in which file, on which line, and how to fix it \u2014 are deliberately withheld, and any secret-scanner results are excluded entirely. Where detail is absent here it was REMOVED FOR PUBLICATION; it is not missing from the analysis. The complete artifact is available from the repository owner.","securityFindingsRedacted":142,"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."]}]}