{"$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":"D9","name":"Test Distribution","shortDescription":{"text":"Test Distribution"},"helpUri":"https://codehealth.canine.dev/dimensions/D9"},{"id":"D11","name":"Test Reliability","shortDescription":{"text":"Test Reliability"},"helpUri":"https://codehealth.canine.dev/dimensions/D11"},{"id":"D13","name":"Secret Scanning","shortDescription":{"text":"Secret Scanning"},"helpUri":"https://codehealth.canine.dev/dimensions/D13","relationships":[{"target":{"id":"CWE-798","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},"kinds":["relevant"]},{"target":{"id":"CWE-259","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},"kinds":["relevant"]}],"properties":{"cwe":["CWE-798","CWE-259"]}},{"id":"D14","name":"License Compliance","shortDescription":{"text":"License Compliance"},"helpUri":"https://codehealth.canine.dev/dimensions/D14"},{"id":"D15","name":"Churn \u00D7 Complexity Hotspots","shortDescription":{"text":"Churn \u00D7 Complexity Hotspots"},"helpUri":"https://codehealth.canine.dev/dimensions/D15"},{"id":"D16","name":"Bus Factor","shortDescription":{"text":"Bus Factor"},"helpUri":"https://codehealth.canine.dev/dimensions/D16"},{"id":"D17","name":"Explicit Debt","shortDescription":{"text":"Explicit Debt"},"helpUri":"https://codehealth.canine.dev/dimensions/D17"},{"id":"D19","name":"Documentation Quality","shortDescription":{"text":"Documentation Quality"},"helpUri":"https://codehealth.canine.dev/dimensions/D19"},{"id":"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":"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":"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":"AX10","name":"Code composition","shortDescription":{"text":"Code composition"},"helpUri":"https://codehealth.canine.dev/dimensions/AX10"},{"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":"P6","name":"Release Hygiene","shortDescription":{"text":"Release Hygiene"},"helpUri":"https://codehealth.canine.dev/dimensions/P6"},{"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":"candidates.decide_dreamer_candidate (cyclomatic 204): candidates.decide_dreamer_candidate has cyclomatic complexity 204 (threshold 15). To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"core_memory/runtime/dreamer/candidates.py"},"region":{"startLine":334}}}],"partialFingerprints":{"codehealthFindingId/v1":"86fa1ddfe2b9caa67c5d4c6c3a8ea118ae7e28e6816a1269808870c16d0e5a41"}},{"ruleId":"D1","level":"warning","message":{"text":"management.maintain (cyclomatic 173): management.maintain has cyclomatic complexity 173 (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":"core_memory/management/__init__.py"},"region":{"startLine":829}}}],"partialFingerprints":{"codehealthFindingId/v1":"9ef690b89109de2486fe9cef0a19ee30ade6d65f462ff9017204e027d890ef40"}},{"ruleId":"D1","level":"warning","message":{"text":"canonical.search_request (cyclomatic 150): canonical.search_request has cyclomatic complexity 150 (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":"core_memory/retrieval/pipeline/canonical.py"},"region":{"startLine":891}}}],"partialFingerprints":{"codehealthFindingId/v1":"cdb6942224ad621cfbcc7dfd48e499b64fe12b559ec2bfa37dfd61da2b7da51d"}},{"ruleId":"D1","level":"warning","message":{"text":"store_validation_helpers.required_field_issues_for_store (cyclomatic 127): store_validation_helpers.required_field_issues_for_store has cyclomatic complexity 127 (threshold 15). To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"core_memory/persistence/store_validation_helpers.py"},"region":{"startLine":42}}}],"partialFingerprints":{"codehealthFindingId/v1":"0483f641792758e24b1693da824865a0f45b5e2679b2cb55578b9bf03370714d"}},{"ruleId":"D1","level":"warning","message":{"text":"canonical.trace_request (cyclomatic 121): canonical.trace_request has cyclomatic complexity 121 (threshold 15). To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"core_memory/retrieval/pipeline/canonical.py"},"region":{"startLine":1180}}}],"partialFingerprints":{"codehealthFindingId/v1":"7220a52f5a3a838ad4ff49020b809d20bdfe673ecf03731ddf3112c460f48bbb"}},{"ruleId":"D1","level":"warning","message":{"text":"crawler_contract.apply_crawler_updates (cyclomatic 110): crawler_contract.apply_crawler_updates has cyclomatic complexity 110 (threshold 15). To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"core_memory/association/crawler_contract.py"},"region":{"startLine":767}}}],"partialFingerprints":{"codehealthFindingId/v1":"1194fbdb316f5f07fc94ad795562e31032b900c0436e198c44fbb1de4a1fc81a"}},{"ruleId":"D1","level":"warning","message":{"text":"management._validate_action (cyclomatic 110): management._validate_action has cyclomatic complexity 110 (threshold 15). To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"core_memory/management/__init__.py"},"region":{"startLine":396}}}],"partialFingerprints":{"codehealthFindingId/v1":"9b22d1b0c5ff1b4144068d0a87bdc3e1c4f5ddc8090db6be53f2e28d1553641e"}},{"ruleId":"D1","level":"warning","message":{"text":"memory_reason.memory_reason (cyclomatic 109): memory_reason.memory_reason has cyclomatic complexity 109 (threshold 15). To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"core_memory/retrieval/tools/memory_reason.py"},"region":{"startLine":762}}}],"partialFingerprints":{"codehealthFindingId/v1":"a3e47026609eae3ab3596c9eced796c24d0dc9ca941bd607186b4c04d7beedd2"}},{"ruleId":"D1","level":"warning","message":{"text":"canonical.execute_request (cyclomatic 108): canonical.execute_request has cyclomatic complexity 108 (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":"core_memory/retrieval/pipeline/canonical.py"},"region":{"startLine":1444}}}],"partialFingerprints":{"codehealthFindingId/v1":"cf16f9952f3418fe2e37fb44ed915c057e04430bfeffe026da560c8278208999"}},{"ruleId":"D1","level":"warning","message":{"text":"side_effect_queue.process_side_effect_event (cyclomatic 105): side_effect_queue.process_side_effect_event has cyclomatic complexity 105 (threshold 15). To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"core_memory/runtime/queue/side_effect_queue.py"},"region":{"startLine":117}}}],"partialFingerprints":{"codehealthFindingId/v1":"1eb6e537617f217f8f0dfc87fc7295b289af2376a41dfb08b834f615242bacef"}},{"ruleId":"D1","level":"warning","message":{"text":"flush_flow.process_flush_impl (cyclomatic 103): flush_flow.process_flush_impl has cyclomatic complexity 103 (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":"core_memory/runtime/flush/flush_flow.py"},"region":{"startLine":29}}}],"partialFingerprints":{"codehealthFindingId/v1":"757e8306b8c89d820f772af9ae7eaf3119353c9bfda8d51418293d4133b9c674"}},{"ruleId":"D1","level":"warning","message":{"text":"turn_flow.process_turn_finalized_impl (cyclomatic 99): turn_flow.process_turn_finalized_impl has cyclomatic complexity 99 (threshold 15). To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"core_memory/runtime/turn/turn_flow.py"},"region":{"startLine":29}}}],"partialFingerprints":{"codehealthFindingId/v1":"b01c6bfd62b42bb2e809501dd1ea7546e7f15c1f7a15fbe18003a905e4501df5"}},{"ruleId":"D1","level":"warning","message":{"text":"crawler_contract.merge_crawler_updates (cyclomatic 93): crawler_contract.merge_crawler_updates has cyclomatic complexity 93 (threshold 15). To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"core_memory/association/crawler_contract.py"},"region":{"startLine":435}}}],"partialFingerprints":{"codehealthFindingId/v1":"e4bda068c7c6d880a22f8781275fe516f3fb5eba88634f16c67da16259b1bf52"}},{"ruleId":"D1","level":"warning","message":{"text":"enrichment.run_turn_enrichment (cyclomatic 91): enrichment.run_turn_enrichment has cyclomatic complexity 91 (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":"core_memory/runtime/passes/enrichment.py"},"region":{"startLine":115}}}],"partialFingerprints":{"codehealthFindingId/v1":"4c3219e5d56acb93b8a9c5d009172068a40285c36bfba777d13da731e02b995f"}},{"ruleId":"D1","level":"warning","message":{"text":"search.search_typed (cyclomatic 86): search.search_typed has cyclomatic complexity 86 (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":"core_memory/retrieval/pipeline/search.py"},"region":{"startLine":36}}}],"partialFingerprints":{"codehealthFindingId/v1":"0739a45e8cb2fa35e27ba422bcc10219e552ab61527579cebe5defaac510b658"}},{"ruleId":"D1","level":"warning","message":{"text":"semantic_index.semantic_lookup (cyclomatic 85): semantic_index.semantic_lookup has cyclomatic complexity 85 (threshold 15). To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"core_memory/retrieval/semantic_index.py"},"region":{"startLine":1546}}}],"partialFingerprints":{"codehealthFindingId/v1":"8230d17c5fe4095ea8ef479bec573671dc1e36537caef5fe2a4d6dd12a5666bf"}},{"ruleId":"D1","level":"warning","message":{"text":"session_enrichment_delta.crawler_updates_to_delta (cyclomatic 81): session_enrichment_delta.crawler_updates_to_delta has cyclomatic complexity 81 (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":"core_memory/runtime/session/session_enrichment_delta.py"},"region":{"startLine":422}}}],"partialFingerprints":{"codehealthFindingId/v1":"bd81cbeee5c5aee4348a45c628e8fec72ef53616a3d43cd10a43c01ed8e171cb"}},{"ruleId":"D1","level":"warning","message":{"text":"candidates.enqueue_dreamer_candidates (cyclomatic 79): candidates.enqueue_dreamer_candidates has cyclomatic complexity 79 (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":"core_memory/runtime/dreamer/candidates.py"},"region":{"startLine":93}}}],"partialFingerprints":{"codehealthFindingId/v1":"47082411d60cbf003953f57b0f399d49bf8f5c8d7403fac0c796e2a62eb37e85"}},{"ruleId":"D1","level":"warning","message":{"text":"summary._build_light_cone (cyclomatic 78): summary._build_light_cone has cyclomatic complexity 78 (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":"core_memory/soul/summary.py"},"region":{"startLine":603}}}],"partialFingerprints":{"codehealthFindingId/v1":"22188521272bf0d9bcee8e0b3c53f5bcc46db70ea8c88a132a2875f9ba530188"}},{"ruleId":"D1","level":"warning","message":{"text":"sync_transcript_snapshot.sync_transcript_snapshot_handler (cyclomatic 68): sync_transcript_snapshot.sync_transcript_snapshot_handler has cyclomatic complexity 68 (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":"core_memory/integrations/mcp/tools/sync_transcript_snapshot.py"},"region":{"startLine":217}}}],"partialFingerprints":{"codehealthFindingId/v1":"dace15c54d508c01ebc097f3c2a4895faf5d0f73a0c171c0acdd13db1f03b717"}},{"ruleId":"D1","level":"warning","message":{"text":"dreamer_bridge.propose_soul_from_dreamer (cyclomatic 68): dreamer_bridge.propose_soul_from_dreamer has cyclomatic complexity 68 (threshold 15). To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"core_memory/soul/dreamer_bridge.py"},"region":{"startLine":536}}}],"partialFingerprints":{"codehealthFindingId/v1":"cdf432d416248f6bc182f4ef7635a7c9c53ba3bd7834c6f468f37a97fcdd28a8"}},{"ruleId":"D1","level":"warning","message":{"text":"memory_reason._plan_why (cyclomatic 67): memory_reason._plan_why has cyclomatic complexity 67 (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":"core_memory/retrieval/tools/memory_reason.py"},"region":{"startLine":525}}}],"partialFingerprints":{"codehealthFindingId/v1":"4f786c9d3aa569351ad3a50152399d108c640ef01f68e5be2d9d922c4b0cffb5"}},{"ruleId":"D1","level":"warning","message":{"text":"coverage._apply_judge_result (cyclomatic 67): coverage._apply_judge_result has cyclomatic complexity 67 (threshold 15). To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"core_memory/runtime/associations/coverage.py"},"region":{"startLine":1862}}}],"partialFingerprints":{"codehealthFindingId/v1":"99bbd7c8e756748c83b9b266fc8a4744e05df7d929c6b554dae8cecb4db94143"}},{"ruleId":"D1","level":"warning","message":{"text":"hybrid.hybrid_lookup (cyclomatic 66): hybrid.hybrid_lookup has cyclomatic complexity 66 (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":"core_memory/retrieval/hybrid.py"},"region":{"startLine":101}}}],"partialFingerprints":{"codehealthFindingId/v1":"02090b728b84b349fb054539833aee61e7ccdb09a75b63bd457105fe8920c55c"}},{"ruleId":"D1","level":"warning","message":{"text":"agent_authored_contract.validate_agent_authored_updates (cyclomatic 65): agent_authored_contract.validate_agent_authored_updates 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":"core_memory/runtime/passes/agent_authored_contract.py"},"region":{"startLine":93}}}],"partialFingerprints":{"codehealthFindingId/v1":"5cc7f47d024aaa0852ca3fe3f9a2a2e9a8d130f65d303533ad9d25b1879722fa"}},{"ruleId":"D1","level":"warning","message":{"text":"summary._build_tensions (cyclomatic 65): summary._build_tensions has cyclomatic complexity 65 (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":"core_memory/soul/summary.py"},"region":{"startLine":957}}}],"partialFingerprints":{"codehealthFindingId/v1":"74cf6e19186c6ce50da3ca648fcc5ffc2cab9be0821665fd5bf32567a3f36028"}},{"ruleId":"D1","level":"warning","message":{"text":"transcript_ingest.normalize_transcript_payload (cyclomatic 65): transcript_ingest.normalize_transcript_payload has cyclomatic complexity 65 (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":"core_memory/transcript_ingest.py"},"region":{"startLine":192}}}],"partialFingerprints":{"codehealthFindingId/v1":"2a679886821e9c99b5e76f1c4c87fd3a81578a70b2a5ae362a9593bd57a96ae6"}},{"ruleId":"D1","level":"warning","message":{"text":"canonical._apply_typed_filters (cyclomatic 61): canonical._apply_typed_filters 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":"core_memory/retrieval/pipeline/canonical.py"},"region":{"startLine":699}}}],"partialFingerprints":{"codehealthFindingId/v1":"b830234178a0cdfc991eb5611b0cea232ee8eaad47dac4073e48f6c1065ebe0f"}},{"ruleId":"D1","level":"warning","message":{"text":"coverage.run_association_coverage (cyclomatic 61): coverage.run_association_coverage has cyclomatic complexity 61 (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":"core_memory/runtime/associations/coverage.py"},"region":{"startLine":2483}}}],"partialFingerprints":{"codehealthFindingId/v1":"5a271273671517c96dfced1f1cef4b3913107feea9515c666df376755f7d4b19"}},{"ruleId":"D1","level":"warning","message":{"text":"api.inspect_state (cyclomatic 60): api.inspect_state has cyclomatic complexity 60 (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":"core_memory/integrations/api.py"},"region":{"startLine":349}}}],"partialFingerprints":{"codehealthFindingId/v1":"76a5f815bbad10915e5eca09ec1c75ea5e1d423ca354717730a55269c75e195f"}},{"ruleId":"D1","level":"warning","message":{"text":"contracts.recall_result_from_memory_execute (cyclomatic 59): contracts.recall_result_from_memory_execute has cyclomatic complexity 59 (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":"core_memory/retrieval/contracts.py"},"region":{"startLine":306}}}],"partialFingerprints":{"codehealthFindingId/v1":"7e276b272364d6f9a29ec6fedb0323c808b3633ea1f8a01137a74b5d7db574fe"}},{"ruleId":"D1","level":"warning","message":{"text":"coverage.decide_association_candidate (cyclomatic 58): coverage.decide_association_candidate 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":"core_memory/runtime/associations/coverage.py"},"region":{"startLine":2925}}}],"partialFingerprints":{"codehealthFindingId/v1":"337c5cb3dc8c7acda703a0fc588bf4024c9d86242bf34c7e89b05861630749f4"}},{"ruleId":"D1","level":"warning","message":{"text":"core.backfill_causal_links (cyclomatic 55): core.backfill_causal_links has cyclomatic complexity 55 (threshold 15). To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"core_memory/graph/core.py"},"region":{"startLine":257}}}],"partialFingerprints":{"codehealthFindingId/v1":"a7950eeeb203ddb03d8e4e67cbb5534d387bd47ff0fbd3db9b8352c2d8710ea3"}},{"ruleId":"D1","level":"warning","message":{"text":"roadmap.roadmap_watershed_attribution (cyclomatic 55): roadmap.roadmap_watershed_attribution has cyclomatic complexity 55 (threshold 15). To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"core_memory/graph/roadmap.py"},"region":{"startLine":486}}}],"partialFingerprints":{"codehealthFindingId/v1":"5802c5de302107c2c4a5cec6f912fbb96d0d9157cda7cca5c76802ca01e3f6b6"}},{"ruleId":"D1","level":"warning","message":{"text":"core.sync_structural_pipeline (cyclomatic 54): core.sync_structural_pipeline has cyclomatic complexity 54 (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":"core_memory/graph/core.py"},"region":{"startLine":391}}}],"partialFingerprints":{"codehealthFindingId/v1":"7077d25590d417b13cfed70a745193add53c08c50cca6c650e08bf68a88df6bf"}},{"ruleId":"D1","level":"warning","message":{"text":"ingest.ingest_handler (cyclomatic 54): ingest.ingest_handler has cyclomatic complexity 54 (threshold 15). To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"core_memory/integrations/mcp/tools/ingest.py"},"region":{"startLine":196}}}],"partialFingerprints":{"codehealthFindingId/v1":"09576a89102218e4c3c2e8b39351fe54a2ec6be49c45489bfdb1ff7ab3fad3a4"}},{"ruleId":"D1","level":"warning","message":{"text":"crawler_contract._normalize_review_rows (cyclomatic 53): crawler_contract._normalize_review_rows has cyclomatic complexity 53 (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":"core_memory/association/crawler_contract.py"},"region":{"startLine":35}}}],"partialFingerprints":{"codehealthFindingId/v1":"ca28ea596a25a33a2afb7948f2bd97aad350e62b5a5bd339e88efeff9fa2d717"}},{"ruleId":"D1","level":"warning","message":{"text":"metrics.handle_metrics_command (cyclomatic 53): metrics.handle_metrics_command has cyclomatic complexity 53 (threshold 15). To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"core_memory/cli/handlers/metrics.py"},"region":{"startLine":14}}}],"partialFingerprints":{"codehealthFindingId/v1":"da792117c195872c13fe983c45d82bc627936c25b6b39563314da33d60e653ca"}},{"ruleId":"D1","level":"warning","message":{"text":"canonical._claim_anchors_from_state (cyclomatic 52): canonical._claim_anchors_from_state 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":"core_memory/retrieval/pipeline/canonical.py"},"region":{"startLine":184}}}],"partialFingerprints":{"codehealthFindingId/v1":"3a47a9c9d1d4d5440b41ed1c5f992558fea2b319b6d45f407a1c2dee0df869f0"}},{"ruleId":"D1","level":"warning","message":{"text":"agent.recall (cyclomatic 51): agent.recall has cyclomatic complexity 51 (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":"core_memory/retrieval/agent.py"},"region":{"startLine":817}}}],"partialFingerprints":{"codehealthFindingId/v1":"9ab2ebc0de48c0716234d4b9df0daa33f6c42fa960954c03b52039d712c39942"}},{"ruleId":"D1","level":"warning","message":{"text":"reauthoring._cohort_metrics (cyclomatic 51): reauthoring._cohort_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":"core_memory/runtime/turn/reauthoring.py"},"region":{"startLine":209}}}],"partialFingerprints":{"codehealthFindingId/v1":"55ee58eaf15926377ae33f7047d20dccf7aa6d45496c3f5e39e297dc384e25e8"}},{"ruleId":"D1","level":"warning","message":{"text":"Neo4jClient.upsert_projection (cyclomatic 50): Neo4jClient.upsert_projection has cyclomatic complexity 50 (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":"core_memory/integrations/neo4j/client.py"},"region":{"startLine":121}}}],"partialFingerprints":{"codehealthFindingId/v1":"15e66d65e553ef7bbd0e8711f0458b25ba6572549f090b482fd24599992019ce"}},{"ruleId":"D1","level":"warning","message":{"text":"agent._expand_via_association_hops (cyclomatic 49): agent._expand_via_association_hops has cyclomatic complexity 49 (threshold 15). To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"core_memory/retrieval/agent.py"},"region":{"startLine":599}}}],"partialFingerprints":{"codehealthFindingId/v1":"362836f64888e48e82e3ab4140219769939ddff8b5273c6e816137b44bd952e2"}},{"ruleId":"D1","level":"warning","message":{"text":"session_enrichment_delta.canonical_session_projection (cyclomatic 47): session_enrichment_delta.canonical_session_projection has cyclomatic complexity 47 (threshold 15). To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"core_memory/runtime/session/session_enrichment_delta.py"},"region":{"startLine":802}}}],"partialFingerprints":{"codehealthFindingId/v1":"35354dfe7e7e754be6d7ccabe51f8dddd2481d43f0aa01affcc5e19fbd98ee6b"}},{"ruleId":"D1","level":"warning","message":{"text":"semantic_index.apply_semantic_delta (cyclomatic 46): semantic_index.apply_semantic_delta has cyclomatic complexity 46 (threshold 15). To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"core_memory/retrieval/semantic_index.py"},"region":{"startLine":1348}}}],"partialFingerprints":{"codehealthFindingId/v1":"97caf5db73ea4ffe2023fae5cf4846a9a5060fb6670a8865f3269256522b997b"}},{"ruleId":"D1","level":"warning","message":{"text":"models._normalize_bead_payload (cyclomatic 46): models._normalize_bead_payload has cyclomatic complexity 46 (threshold 15). To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"core_memory/schema/models.py"},"region":{"startLine":310}}}],"partialFingerprints":{"codehealthFindingId/v1":"6e020633b9fe05bf6e7011da1aad405338368c63308256148fb93faff65ca812"}},{"ruleId":"D1","level":"warning","message":{"text":"memory_reason._radius1_structural_fallback (cyclomatic 45): memory_reason._radius1_structural_fallback 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":"core_memory/retrieval/tools/memory_reason.py"},"region":{"startLine":371}}}],"partialFingerprints":{"codehealthFindingId/v1":"50ed6575fc249dda0e9f79c5fe85f67e3a2c2921c983be429643a5a6510c6abd"}},{"ruleId":"D1","level":"warning","message":{"text":"coverage.enqueue_association_coverage (cyclomatic 45): coverage.enqueue_association_coverage has cyclomatic complexity 45 (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":"core_memory/runtime/associations/coverage.py"},"region":{"startLine":2192}}}],"partialFingerprints":{"codehealthFindingId/v1":"5ea75fcd2519a47ced869e104075285830e05419adec23e5ed96d74ffcc30f00"}},{"ruleId":"D1","level":"warning","message":{"text":"crawler_contract._normalize_creation_rows_with_diagnostics (cyclomatic 43): crawler_contract._normalize_creation_rows_with_diagnostics 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":"core_memory/association/crawler_contract.py"},"region":{"startLine":156}}}],"partialFingerprints":{"codehealthFindingId/v1":"b900ef12c9510229b007535d7b108e69096c34866028b43f2ef5dbfcdbedbcf3"}},{"ruleId":"D1","level":"warning","message":{"text":"core.build_graph (cyclomatic 43): core.build_graph 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":"core_memory/graph/core.py"},"region":{"startLine":673}}}],"partialFingerprints":{"codehealthFindingId/v1":"b5636699bc99b67ca4b72c23b5fec13ba46ace0e239fd06c7d790ec0018fddc7"}},{"ruleId":"D1","level":"warning","message":{"text":"summary._build_divergence (cyclomatic 43): summary._build_divergence has cyclomatic complexity 43 (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":"core_memory/soul/summary.py"},"region":{"startLine":829}}}],"partialFingerprints":{"codehealthFindingId/v1":"31d2cbd386bda13b018acb5ada9e9fe4be7bd56fe942b4ca2f427f7559252ca8"}},{"ruleId":"D1","level":"warning","message":{"text":"health.association_pending_judge_health (cyclomatic 42): health.association_pending_judge_health has cyclomatic complexity 42 (threshold 15). To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"core_memory/association/health.py"},"region":{"startLine":29}}}],"partialFingerprints":{"codehealthFindingId/v1":"33ec355c203f211c5fcc52d1767cb85268af8b55f87c2a918e076a50bfc42ba3"}},{"ruleId":"D1","level":"warning","message":{"text":"answer_signals.compute_answer_signals (cyclomatic 42): answer_signals.compute_answer_signals has cyclomatic complexity 42 (threshold 15). To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"core_memory/claim/answer_signals.py"},"region":{"startLine":15}}}],"partialFingerprints":{"codehealthFindingId/v1":"489dbb7770d8d735f19f431349d3baf99d529c62fa2528c26ee362c0e683639a"}},{"ruleId":"D1","level":"warning","message":{"text":"graph.handle_graph_command (cyclomatic 42): graph.handle_graph_command has cyclomatic complexity 42 (threshold 15). To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"core_memory/cli/handlers/graph.py"},"region":{"startLine":20}}}],"partialFingerprints":{"codehealthFindingId/v1":"1d1d05990d0810cc30b84b9607a4ffc5e84d1157607642c11fb1688e01ebfb83"}},{"ruleId":"D1","level":"warning","message":{"text":"semantic_index.build_semantic_index (cyclomatic 42): semantic_index.build_semantic_index has cyclomatic complexity 42 (threshold 15). To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"core_memory/retrieval/semantic_index.py"},"region":{"startLine":1104}}}],"partialFingerprints":{"codehealthFindingId/v1":"09006b57a4b40c608410a763106df086b1622df5d1df9ab0fb30cbf052dcb91f"}},{"ruleId":"D1","level":"warning","message":{"text":"reviewer_quick_value.reviewer_quick_value_v2 (cyclomatic 42): reviewer_quick_value.reviewer_quick_value_v2 has cyclomatic complexity 42 (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":"core_memory/runtime/observability/reviewer_quick_value.py"},"region":{"startLine":61}}}],"partialFingerprints":{"codehealthFindingId/v1":"6eaf42ee912f93295f20ad9ee576046d3098fe8b549334356ca4eb3e84035327"}},{"ruleId":"D1","level":"warning","message":{"text":"compat.apply_grouped_aliases (cyclomatic 41): compat.apply_grouped_aliases has cyclomatic complexity 41 (threshold 15). To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"core_memory/cli/compat.py"},"region":{"startLine":63}}}],"partialFingerprints":{"codehealthFindingId/v1":"e95b7ed69969cf6a4764550ea8aa2dcd11bc41b0243e73403a3b91c714b16df5"}},{"ruleId":"D1","level":"warning","message":{"text":"agent_end_bridge.process_agent_end_event (cyclomatic 41): agent_end_bridge.process_agent_end_event has cyclomatic complexity 41 (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":"core_memory/integrations/openclaw/agent_end_bridge.py"},"region":{"startLine":182}}}],"partialFingerprints":{"codehealthFindingId/v1":"d638cf5310a4dee85593468a4773e6fc96c4d5a557b62e85442bbe439b038974"}},{"ruleId":"D1","level":"warning","message":{"text":"agent._collect_extra_seeds (cyclomatic 41): agent._collect_extra_seeds has cyclomatic complexity 41 (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":"core_memory/retrieval/agent.py"},"region":{"startLine":473}}}],"partialFingerprints":{"codehealthFindingId/v1":"a0a73bc4682688c08f9d6a67d581351c4bbb7e90f888c307352136cf34c4f13f"}},{"ruleId":"D1","level":"warning","message":{"text":"canonical._claim_answer_candidate (cyclomatic 41): canonical._claim_answer_candidate has cyclomatic complexity 41 (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":"core_memory/retrieval/pipeline/canonical.py"},"region":{"startLine":310}}}],"partialFingerprints":{"codehealthFindingId/v1":"81ca905e95fa78791c009caf0d372e9e62368528da487ab8386d488fd8eb8dbc"}},{"ruleId":"D1","level":"warning","message":{"text":"memory_execute_eval.main (cyclomatic 41): memory_execute_eval.main has cyclomatic complexity 41 (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":"eval/memory_execute_eval.py"},"region":{"startLine":44}}}],"partialFingerprints":{"codehealthFindingId/v1":"6b8cf5efadc100feb7edf7b0e92da576400eb6096981df81be027a31e356db4c"}},{"ruleId":"D1","level":"warning","message":{"text":"retrieval_feedback.record_retrieval_feedback (cyclomatic 40): retrieval_feedback.record_retrieval_feedback has cyclomatic complexity 40 (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":"core_memory/persistence/retrieval_feedback.py"},"region":{"startLine":76}}}],"partialFingerprints":{"codehealthFindingId/v1":"bd52bc9cb681a44b0aa3d74a0144a918f9a9efc2104a638a0d32c88a7863e69c"}},{"ruleId":"D1","level":"warning","message":{"text":"coverage._normalized_candidate_rows (cyclomatic 40): coverage._normalized_candidate_rows 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":"core_memory/runtime/associations/coverage.py"},"region":{"startLine":490}}}],"partialFingerprints":{"codehealthFindingId/v1":"2cc83b88ab0e84699afbcfa9050718e7b5d2b1ae94935bc8b0377283baa611cd"}},{"ruleId":"D1","level":"warning","message":{"text":"eval.dreamer_eval_report (cyclomatic 40): eval.dreamer_eval_report has cyclomatic complexity 40 (threshold 15). To reduce it, split the body: these branches sit side by side rather than nested inside one another, so extracting each one on its own would leave a function per branch. Group the statements between the checks into named steps and move each step into its own function, so the body reads as a short sequence of named stages."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"core_memory/runtime/dreamer/eval.py"},"region":{"startLine":261}}}],"partialFingerprints":{"codehealthFindingId/v1":"ee5d739322db3aa6ec0d0fc031f3ff77066799550723addca097895c74fa4b74"}},{"ruleId":"D1","level":"warning","message":{"text":"side_effect_queue.drain_side_effect_queue (cyclomatic 40): side_effect_queue.drain_side_effect_queue 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":"core_memory/runtime/queue/side_effect_queue.py"},"region":{"startLine":582}}}],"partialFingerprints":{"codehealthFindingId/v1":"1f08d7d2bb7c30416e141cf68291c5888020d0ef0a394874d6a089dadabd2423"}},{"ruleId":"D1","level":"warning","message":{"text":"semantic_task_verifier.verify_semantic_task_output (cyclomatic 39): semantic_task_verifier.verify_semantic_task_output has cyclomatic complexity 39 (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":"core_memory/policy/semantic_task_verifier.py"},"region":{"startLine":182}}}],"partialFingerprints":{"codehealthFindingId/v1":"ee4f05bd156086f81f9931ed2b9b5d02bd55f33ff3fb56fd157d5fa4b2f2bfb7"}},{"ruleId":"D1","level":"warning","message":{"text":"coverage._pair_signals (cyclomatic 39): coverage._pair_signals 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":"core_memory/runtime/associations/coverage.py"},"region":{"startLine":1056}}}],"partialFingerprints":{"codehealthFindingId/v1":"78186683f8d0650ef296151b614043274584743dca6cc558db39af27be262ca8"}},{"ruleId":"D1","level":"warning","message":{"text":"engine._resolve_reviewed_updates (cyclomatic 39): engine._resolve_reviewed_updates 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":"core_memory/runtime/engine.py"},"region":{"startLine":302}}}],"partialFingerprints":{"codehealthFindingId/v1":"773de62e65b3a23f5b17de8e2909d670c809f184b4d925a0f216d280360c27be"}},{"ruleId":"D1","level":"warning","message":{"text":"receipt.build_turn_finalized_receipt (cyclomatic 39): receipt.build_turn_finalized_receipt has cyclomatic complexity 39 (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":"core_memory/runtime/turn/receipt.py"},"region":{"startLine":129}}}],"partialFingerprints":{"codehealthFindingId/v1":"1509429822f84ebaf6ecbe196b7be7bf3a0012d457e87ec9696f807218ed2a8e"}},{"ruleId":"D1","level":"warning","message":{"text":"root_cause._parameterized_best_first_search (cyclomatic 38): root_cause._parameterized_best_first_search 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":"core_memory/graph/root_cause.py"},"region":{"startLine":554}}}],"partialFingerprints":{"codehealthFindingId/v1":"218ef715ff97db2416ca031781d53dc96616c50c6c29d8bc8d83e3b0158ebd5f"}},{"ruleId":"D1","level":"warning","message":{"text":"events.rebuild_index (cyclomatic 38): events.rebuild_index 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":"core_memory/persistence/events.py"},"region":{"startLine":163}}}],"partialFingerprints":{"codehealthFindingId/v1":"0a9c0f6b89ad7ae09dada24c431148b872617605fc5ace60de6672b9d8a0dda7"}},{"ruleId":"D1","level":"warning","message":{"text":"refinement.refine_pending_candidates (cyclomatic 38): refinement.refine_pending_candidates has cyclomatic complexity 38 (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":"core_memory/runtime/dreamer/refinement.py"},"region":{"startLine":145}}}],"partialFingerprints":{"codehealthFindingId/v1":"1d046095632a3c5d37b122a99868045615fcbfb3a36b65ef5fcf453e9e3ec11c"}},{"ruleId":"D1","level":"warning","message":{"text":"core.causal_traverse (cyclomatic 37): core.causal_traverse 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":"core_memory/graph/core.py"},"region":{"startLine":816}}}],"partialFingerprints":{"codehealthFindingId/v1":"088d543a46b233db8ed7d0374b6abb856420392ef2626ad83fe4151a3b494616"}},{"ruleId":"D1","level":"warning","message":{"text":"traversal._build_adjacency (cyclomatic 37): traversal._build_adjacency 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":"core_memory/graph/traversal.py"},"region":{"startLine":37}}}],"partialFingerprints":{"codehealthFindingId/v1":"c4c335cb764dba06a30e84f497c4c232089b1c5688f7b9fb12199a724ef81b8f"}},{"ruleId":"D1","level":"warning","message":{"text":"canonical._apply_hint_boosts (cyclomatic 37): canonical._apply_hint_boosts 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":"core_memory/retrieval/pipeline/canonical.py"},"region":{"startLine":811}}}],"partialFingerprints":{"codehealthFindingId/v1":"7ed047bb7cafb0ea547f0c4fb8fc7f825b4f72cd407a362fc25a8e18b73c1bf5"}},{"ruleId":"D1","level":"warning","message":{"text":"bead_projection.build_retrieval_text (cyclomatic 37): bead_projection.build_retrieval_text 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":"core_memory/schema/bead_projection.py"},"region":{"startLine":79}}}],"partialFingerprints":{"codehealthFindingId/v1":"fb85792264210cb35384f62763749da868044599258beb086e236fbaca22e053"}},{"ruleId":"D1","level":"warning","message":{"text":"register (cyclomatic 37): register has cyclomatic complexity 37 (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":"plugins/openclaw-core-memory-bridge/index.js"},"region":{"startLine":19}}}],"partialFingerprints":{"codehealthFindingId/v1":"76c0a67370e66ea77b0302aef902dc17db909596fc6931f8f8bfd6b8e7a75548"}},{"ruleId":"D1","level":"warning","message":{"text":"myelination.compute_myelination_bonus_map (cyclomatic 36): myelination.compute_myelination_bonus_map 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":"core_memory/runtime/observability/myelination.py"},"region":{"startLine":57}}}],"partialFingerprints":{"codehealthFindingId/v1":"6556118f27fc34a58ad9b34f2000395c01c2a114386f1004a59800c9a0a731a5"}},{"ruleId":"D1","level":"warning","message":{"text":"agent_authored_updates._validate_json_value (cyclomatic 36): agent_authored_updates._validate_json_value 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":"core_memory/schema/agent_authored_updates.py"},"region":{"startLine":506}}}],"partialFingerprints":{"codehealthFindingId/v1":"7a1ecad60f48023c2a99131835636d00383522d527117530a554047cb9d6faa5"}},{"ruleId":"D1","level":"warning","message":{"text":"ingest_discord.ingest_discord_handler (cyclomatic 35): ingest_discord.ingest_discord_handler 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":"core_memory/integrations/mcp/tools/ingest_discord.py"},"region":{"startLine":79}}}],"partialFingerprints":{"codehealthFindingId/v1":"90b4e657d0ae45bb92f85d5c208b8d1986e9366c81e07c1829e5bdb696ccefb3"}},{"ruleId":"D1","level":"warning","message":{"text":"entity_registry.upsert_canonical_entity (cyclomatic 35): entity_registry.upsert_canonical_entity has cyclomatic complexity 35 (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":"core_memory/persistence/entity_registry.py"},"region":{"startLine":112}}}],"partialFingerprints":{"codehealthFindingId/v1":"cb61946fb38c7d1af7d462a90b0af658aa7a50940dd5c420f4172dcc9eb07ec9"}},{"ruleId":"D1","level":"warning","message":{"text":"store_claim_ops.resolve_current_state (cyclomatic 35): store_claim_ops.resolve_current_state has cyclomatic complexity 35 (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":"core_memory/persistence/store_claim_ops.py"},"region":{"startLine":448}}}],"partialFingerprints":{"codehealthFindingId/v1":"0d0f0ce70b096f89b690905b341cd2de28abe06a73fa130a51e02167ae3a1c06"}},{"ruleId":"D1","level":"warning","message":{"text":"evidence_scoring.rerank_semantic_rows (cyclomatic 35): evidence_scoring.rerank_semantic_rows 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":"core_memory/retrieval/evidence_scoring.py"},"region":{"startLine":105}}}],"partialFingerprints":{"codehealthFindingId/v1":"b58d5d20e99ef541236cc004458ddbca87ba8417d70c79c320a28d1e9347758d"}},{"ruleId":"D1","level":"warning","message":{"text":"progress._evaluate_pair (cyclomatic 35): progress._evaluate_pair has cyclomatic complexity 35 (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":"core_memory/runtime/goals/progress.py"},"region":{"startLine":231}}}],"partialFingerprints":{"codehealthFindingId/v1":"353b53ca9ac3c7e60408be16b4c5693c9834dddcb5931cd2973df0100c385587"}},{"ruleId":"D1","level":"warning","message":{"text":"turn_prep.normalize_turn_request (cyclomatic 35): turn_prep.normalize_turn_request has cyclomatic complexity 35 (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":"core_memory/runtime/turn/turn_prep.py"},"region":{"startLine":25}}}],"partialFingerprints":{"codehealthFindingId/v1":"dedb21b0f5f006364383e78b16a83feb708bf3a33a17970200b7c7c240c57e95"}},{"ruleId":"D1","level":"warning","message":{"text":"dreamer_bridge._run_soul_proposal_task (cyclomatic 35): dreamer_bridge._run_soul_proposal_task has cyclomatic complexity 35 (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":"core_memory/soul/dreamer_bridge.py"},"region":{"startLine":421}}}],"partialFingerprints":{"codehealthFindingId/v1":"c6ea1db75d0d85e05a559226cc749dfd2611da2258fb989f73566ba7d330ac93"}},{"ruleId":"D1","level":"warning","message":{"text":"transcript_ingest._resolve_envelope_speakers (cyclomatic 35): transcript_ingest._resolve_envelope_speakers has cyclomatic complexity 35 (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":"core_memory/transcript_ingest.py"},"region":{"startLine":467}}}],"partialFingerprints":{"codehealthFindingId/v1":"e115f888beb99f5c713a1f17a50f66b75b5ba4cfa3964728e9d57b9fe9521ad9"}},{"ruleId":"D1","level":"warning","message":{"text":"promotion_service.promotion_kpis_for_store (cyclomatic 34): promotion_service.promotion_kpis_for_store has cyclomatic complexity 34 (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":"core_memory/persistence/promotion_service.py"},"region":{"startLine":528}}}],"partialFingerprints":{"codehealthFindingId/v1":"36ecaf828872d2d0622ea2e75f2f48616069fe839ae4bd6ffb39c587105bfb4b"}},{"ruleId":"D1","level":"warning","message":{"text":"store_add_bead_ops.add_bead_for_store (cyclomatic 34): store_add_bead_ops.add_bead_for_store 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":"core_memory/persistence/store_add_bead_ops.py"},"region":{"startLine":33}}}],"partialFingerprints":{"codehealthFindingId/v1":"a6a3a844d2201a74bc4a3583c44e9e9c6ca4895d24ca8170ed9e45a91fde3026"}},{"ruleId":"D1","level":"warning","message":{"text":"store_retrieval_context.retrieve_with_context_for_store (cyclomatic 34): store_retrieval_context.retrieve_with_context_for_store 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":"core_memory/persistence/store_retrieval_context.py"},"region":{"startLine":6}}}],"partialFingerprints":{"codehealthFindingId/v1":"fa43dc019651461cde7228c7591d69cbb8bd10d4871a303f6a5a16aa149cb3b6"}},{"ruleId":"D1","level":"warning","message":{"text":"coverage.apply_association_proposals (cyclomatic 34): coverage.apply_association_proposals 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":"core_memory/runtime/associations/coverage.py"},"region":{"startLine":3270}}}],"partialFingerprints":{"codehealthFindingId/v1":"b69185a47019e6d8d048ffcdb90954e903df8165dcf36de4bdcb2def40e35378"}},{"ruleId":"D1","level":"warning","message":{"text":"research._apply_candidate_refinements (cyclomatic 34): research._apply_candidate_refinements has cyclomatic complexity 34 (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":"core_memory/runtime/dreamer/research.py"},"region":{"startLine":243}}}],"partialFingerprints":{"codehealthFindingId/v1":"824f086c1c8826869b652de2fe8bce76e5167c23ca926ceb914e1ece56a605af"}},{"ruleId":"D1","level":"warning","message":{"text":"research.run_dreamer_research (cyclomatic 34): research.run_dreamer_research has cyclomatic complexity 34 (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":"core_memory/runtime/dreamer/research.py"},"region":{"startLine":303}}}],"partialFingerprints":{"codehealthFindingId/v1":"cc117f74030a5cb033289322bb61c9fbc44bf739d42ece62285c48c76088bdc2"}},{"ruleId":"D1","level":"warning","message":{"text":"health.association_health_report (cyclomatic 33): health.association_health_report has cyclomatic complexity 33 (threshold 15). To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"core_memory/association/health.py"},"region":{"startLine":120}}}],"partialFingerprints":{"codehealthFindingId/v1":"f226d9a19b7b1462a9362476804118b1c4776d53b69a18faccc812998e595fac"}},{"ruleId":"D1","level":"warning","message":{"text":"cli.main (cyclomatic 33): cli.main has cyclomatic complexity 33 (threshold 15). To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"core_memory/cli/__init__.py"},"region":{"startLine":100}}}],"partialFingerprints":{"codehealthFindingId/v1":"0afe96d68cef09a645b9277af4a0f2bfc8e0e6481d8075f29290a4cc8d6bdf62"}},{"ruleId":"D1","level":"warning","message":{"text":"core.backfill_structural_edges (cyclomatic 32): core.backfill_structural_edges 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":"core_memory/graph/core.py"},"region":{"startLine":488}}}],"partialFingerprints":{"codehealthFindingId/v1":"de0da0266c714763cbc2516509fe763de76b8087f702ac662f29df46427630e4"}},{"ruleId":"D1","level":"warning","message":{"text":"core.infer_structural_edges (cyclomatic 32): core.infer_structural_edges 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":"core_memory/graph/core.py"},"region":{"startLine":582}}}],"partialFingerprints":{"codehealthFindingId/v1":"26546ba4e90117bd7113d3a7c7999eea3ed33d43427c111fcd77e0e5cd34c2dd"}},{"ruleId":"D1","level":"warning","message":{"text":"chunk_evidence.resolve_semantic_hits (cyclomatic 32): chunk_evidence.resolve_semantic_hits 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":"core_memory/retrieval/chunk_evidence.py"},"region":{"startLine":190}}}],"partialFingerprints":{"codehealthFindingId/v1":"27e2f4bf9e5a7fb0a6646cdf985b8d8a85219de8c140b3f3c7676417846d7cf1"}},{"ruleId":"D1","level":"warning","message":{"text":"context_recall.retrieve_with_context (cyclomatic 32): context_recall.retrieve_with_context 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":"core_memory/retrieval/context_recall.py"},"region":{"startLine":15}}}],"partialFingerprints":{"codehealthFindingId/v1":"9d9f1b9c6d8e75b5e1a3ba0237c41a1ef547bfa7f61d3340d09447c089c6f437"}},{"ruleId":"D1","level":"warning","message":{"text":"semantic_index.load_cached_bead_embeddings (cyclomatic 32): semantic_index.load_cached_bead_embeddings 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":"core_memory/retrieval/semantic_index.py"},"region":{"startLine":945}}}],"partialFingerprints":{"codehealthFindingId/v1":"0260dba9217906f4dc6666a76889c0c47d19e228242bb328f84454ee37851566"}},{"ruleId":"D1","level":"warning","message":{"text":"progress.run_goal_progress_tasks (cyclomatic 32): progress.run_goal_progress_tasks has cyclomatic complexity 32 (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":"core_memory/runtime/goals/progress.py"},"region":{"startLine":436}}}],"partialFingerprints":{"codehealthFindingId/v1":"b314165d012ab0e05d15ae8203c701f5eb4746b54537395aa0c4e245b7420e07"}},{"ruleId":"D1","level":"warning","message":{"text":"tension_meter.compute_tension_resolution_meter (cyclomatic 32): tension_meter.compute_tension_resolution_meter has cyclomatic complexity 32 (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":"core_memory/runtime/observability/tension_meter.py"},"region":{"startLine":108}}}],"partialFingerprints":{"codehealthFindingId/v1":"d06104311a79445993af46762ed8a3655c38a327600a0337cfe17da14fe14ad9"}},{"ruleId":"D1","level":"warning","message":{"text":"store.handle_store_commands (cyclomatic 31): store.handle_store_commands has cyclomatic complexity 31 (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":"core_memory/cli/handlers/store.py"},"region":{"startLine":14}}}],"partialFingerprints":{"codehealthFindingId/v1":"4688d53683a33be3c2fc87e725f8000963a91afe43b4ae578f60f5f06ab1a612"}},{"ruleId":"D1","level":"warning","message":{"text":"traversal.filter_chains_to_active_edges (cyclomatic 31): traversal.filter_chains_to_active_edges 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":"core_memory/graph/traversal.py"},"region":{"startLine":106}}}],"partialFingerprints":{"codehealthFindingId/v1":"782930e6b1dc35dca7935707caf3f28e029b01ab1b3c75ff1f1770ebb21585df"}},{"ruleId":"D1","level":"warning","message":{"text":"ingest_zoom.ingest_zoom_handler (cyclomatic 31): ingest_zoom.ingest_zoom_handler 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":"core_memory/integrations/mcp/tools/ingest_zoom.py"},"region":{"startLine":129}}}],"partialFingerprints":{"codehealthFindingId/v1":"976692fd7efb84bc3e348ddfcdf870ae9c357b23cc24b25617eb7d436ec84e12"}},{"ruleId":"D1","level":"warning","message":{"text":"calibration.compute_calibration_curve (cyclomatic 31): calibration.compute_calibration_curve 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":"core_memory/persistence/calibration.py"},"region":{"startLine":182}}}],"partialFingerprints":{"codehealthFindingId/v1":"2e3e4786d7200b2a860b7eb5d6ea0cbdf67c1e92becc9602132047a60209c2e1"}},{"ruleId":"D1","level":"warning","message":{"text":"store_reporting.schema_quality_report_for_store (cyclomatic 31): store_reporting.schema_quality_report_for_store has cyclomatic complexity 31 (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":"core_memory/persistence/store_reporting.py"},"region":{"startLine":127}}}],"partialFingerprints":{"codehealthFindingId/v1":"90aee33865fb279f34ff19c531cdf1b36ebc4150065389af00ded005cabbba1f"}},{"ruleId":"D1","level":"warning","message":{"text":"agent._conflicts_for_result (cyclomatic 31): agent._conflicts_for_result 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":"core_memory/retrieval/agent.py"},"region":{"startLine":241}}}],"partialFingerprints":{"codehealthFindingId/v1":"fc685336dd9fdfdec13331fd93cb9e81e25b2b21be7bf0191e8994f4b870384b"}},{"ruleId":"D1","level":"warning","message":{"text":"coverage.judge_association_candidates (cyclomatic 31): coverage.judge_association_candidates has cyclomatic complexity 31 (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":"core_memory/runtime/associations/coverage.py"},"region":{"startLine":3137}}}],"partialFingerprints":{"codehealthFindingId/v1":"4e35cd8121575a87da2d227dbfe3340c27949725fdff5c6da4fcc12635acd314"}},{"ruleId":"D1","level":"warning","message":{"text":"external_evidence._find_existing_external_bead (cyclomatic 31): external_evidence._find_existing_external_bead 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":"core_memory/runtime/ingest/external_evidence.py"},"region":{"startLine":242}}}],"partialFingerprints":{"codehealthFindingId/v1":"65ab0c10246443a0da75e8ac42e4fff8f827f754fdad025fb6c187b6a424cf37"}},{"ruleId":"D1","level":"warning","message":{"text":"root_cause.segment_frontier_between (cyclomatic 30): root_cause.segment_frontier_between 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":"core_memory/graph/root_cause.py"},"region":{"startLine":1168}}}],"partialFingerprints":{"codehealthFindingId/v1":"92ce99a8bfa5a22d4b961f22702a896d85d8eddde3ff6c559d0c3625ab0f7731"}},{"ruleId":"D1","level":"warning","message":{"text":"store_relationship_ops.promote_for_store (cyclomatic 30): store_relationship_ops.promote_for_store 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":"core_memory/persistence/store_relationship_ops.py"},"region":{"startLine":18}}}],"partialFingerprints":{"codehealthFindingId/v1":"b564e7c85a5d180dbe12f400f28dca83a9e3fcffa1b6eaafb399c90c93ed5a6e"}},{"ruleId":"D1","level":"warning","message":{"text":"analysis._structural_signal_pack (cyclomatic 30): analysis._structural_signal_pack has cyclomatic complexity 30 (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":"core_memory/runtime/dreamer/analysis.py"},"region":{"startLine":204}}}],"partialFingerprints":{"codehealthFindingId/v1":"50f2395ad3f756844f00e737dffa69dd6cad86980e44d681c4d3d797d611fd26"}},{"ruleId":"D1","level":"warning","message":{"text":"geometry.build_geometry_manifest (cyclomatic 30): geometry.build_geometry_manifest has cyclomatic complexity 30 (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":"core_memory/runtime/dreamer/geometry.py"},"region":{"startLine":68}}}],"partialFingerprints":{"codehealthFindingId/v1":"e1971b42adf31f0a07caa6367af3f846598daade61acdf0dd21c05c348b857ea"}},{"ruleId":"D1","level":"warning","message":{"text":"engine.process_turn_finalized (cyclomatic 30): engine.process_turn_finalized 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":"core_memory/runtime/engine.py"},"region":{"startLine":576}}}],"partialFingerprints":{"codehealthFindingId/v1":"74462f0e4c58a022d4c7ade3bbc5000d8063a8fa8d71ab3f4b357e838b73473f"}},{"ruleId":"D1","level":"warning","message":{"text":"reauthoring.reauthor_memory (cyclomatic 30): reauthoring.reauthor_memory 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":"core_memory/runtime/turn/reauthoring.py"},"region":{"startLine":618}}}],"partialFingerprints":{"codehealthFindingId/v1":"39a215b2f19767577b5377aaff07cf73afe51c307bb6816ba00c74a1339313cd"}},{"ruleId":"D1","level":"warning","message":{"text":"diagnostics.doctor_report (cyclomatic 29): diagnostics.doctor_report has cyclomatic complexity 29 (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":"core_memory/cli/diagnostics.py"},"region":{"startLine":71}}}],"partialFingerprints":{"codehealthFindingId/v1":"3c6b099aa241a6787508ff43604af9e614fbb1ec673c819826bff088014f3646"}},{"ruleId":"D1","level":"warning","message":{"text":"memory.handle_memory_command (cyclomatic 29): memory.handle_memory_command 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":"core_memory/cli/handlers/memory.py"},"region":{"startLine":8}}}],"partialFingerprints":{"codehealthFindingId/v1":"c32e8484131f244192ef83c38f1907fd99f430800fec2daac1d41eaea5377cac"}},{"ruleId":"D1","level":"warning","message":{"text":"storylines.derive_storylines (cyclomatic 29): storylines.derive_storylines 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":"core_memory/graph/storylines.py"},"region":{"startLine":66}}}],"partialFingerprints":{"codehealthFindingId/v1":"af3fdd7a81afe9fb9a133e004e3399210f63a24d44e161f1ef509893808977d7"}},{"ruleId":"D1","level":"warning","message":{"text":"sync._collect_prune_keep_assoc_ids (cyclomatic 29): sync._collect_prune_keep_assoc_ids 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":"core_memory/integrations/neo4j/sync.py"},"region":{"startLine":199}}}],"partialFingerprints":{"codehealthFindingId/v1":"d753e825dbbb2bf79e311412d46c1a8e5524370522878c928759e67985607d3d"}},{"ruleId":"D1","level":"warning","message":{"text":"goal_lifecycle_v2.transition_goal_state_for_store (cyclomatic 29): goal_lifecycle_v2.transition_goal_state_for_store 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":"core_memory/persistence/goal_lifecycle_v2.py"},"region":{"startLine":77}}}],"partialFingerprints":{"codehealthFindingId/v1":"c134513d52053381124f90346f0f4a3373f13ed9a2758c7625ffff550f426f99"}},{"ruleId":"D1","level":"warning","message":{"text":"promotion_service.decide_promotion_for_store (cyclomatic 29): promotion_service.decide_promotion_for_store has cyclomatic complexity 29 (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":"core_memory/persistence/promotion_service.py"},"region":{"startLine":155}}}],"partialFingerprints":{"codehealthFindingId/v1":"4264fa5673dcbb812f4513d1155b55c2718def07051073a9771e6ad7234950e6"}},{"ruleId":"D1","level":"warning","message":{"text":"store_add_helpers.find_recent_duplicate_bead_id_for_store (cyclomatic 29): store_add_helpers.find_recent_duplicate_bead_id_for_store has cyclomatic complexity 29 (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":"core_memory/persistence/store_add_helpers.py"},"region":{"startLine":121}}}],"partialFingerprints":{"codehealthFindingId/v1":"3ccb78b4e8c12b6c47fcd8a14efa706aaa5015e8cff6469d5fa736ab7bea132c"}},{"ruleId":"D1","level":"warning","message":{"text":"store_management_ops.remove_beads_for_store (cyclomatic 29): store_management_ops.remove_beads_for_store 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":"core_memory/persistence/store_management_ops.py"},"region":{"startLine":322}}}],"partialFingerprints":{"codehealthFindingId/v1":"6a5651ecb95145eb3778ef26220cb43b058c0ddf48f548c5529bb017fcf6132f"}},{"ruleId":"D1","level":"warning","message":{"text":"coverage.enqueue_goal_progress_candidate (cyclomatic 29): coverage.enqueue_goal_progress_candidate 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":"core_memory/runtime/associations/coverage.py"},"region":{"startLine":615}}}],"partialFingerprints":{"codehealthFindingId/v1":"ab856c3cc34f3d24a9270b6c390f6284f8116753e0267ad66e1fd20a30ac2c73"}},{"ruleId":"D1","level":"warning","message":{"text":"coverage._write_association_if_missing (cyclomatic 29): coverage._write_association_if_missing has cyclomatic complexity 29 (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":"core_memory/runtime/associations/coverage.py"},"region":{"startLine":1271}}}],"partialFingerprints":{"codehealthFindingId/v1":"07f0628aed00d7b4cd69624ac659894cf5f7f06afcecba12cbb25a8406b8f448"}},{"ruleId":"D1","level":"warning","message":{"text":"engine._ensure_turn_creation_update (cyclomatic 29): engine._ensure_turn_creation_update 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":"core_memory/runtime/engine.py"},"region":{"startLine":483}}}],"partialFingerprints":{"codehealthFindingId/v1":"831f887079cda9122dacc8a2c208c8f35199c912b92fec2892ff263d690489e1"}},{"ruleId":"D1","level":"warning","message":{"text":"ingress.maybe_emit_finalize_memory_event (cyclomatic 29): ingress.maybe_emit_finalize_memory_event 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":"core_memory/runtime/turn/ingress.py"},"region":{"startLine":80}}}],"partialFingerprints":{"codehealthFindingId/v1":"dd748dcddebe268a7dcc322bd6743b50fc26a3aac781df103823a262a015f238"}},{"ruleId":"D1","level":"warning","message":{"text":"paraphrase_eval.main (cyclomatic 29): paraphrase_eval.main has cyclomatic complexity 29 (threshold 15). To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"eval/paraphrase_eval.py"},"region":{"startLine":51}}}],"partialFingerprints":{"codehealthFindingId/v1":"74a73e08aa49f47c975ce38d4317ebf59769f83a7e641b7a802d9fd460bfbe5d"}},{"ruleId":"D1","level":"warning","message":{"text":"answer_policy.decide_answer_outcome (cyclomatic 28): answer_policy.decide_answer_outcome has cyclomatic complexity 28 (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":"core_memory/claim/answer_policy.py"},"region":{"startLine":22}}}],"partialFingerprints":{"codehealthFindingId/v1":"d835978710a2b7cc09076cae52e38e962bcd5a6af59a479667f53681978bb0f0"}},{"ruleId":"D1","level":"warning","message":{"text":"core._sync_associations_to_links (cyclomatic 28): core._sync_associations_to_links 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":"core_memory/graph/core.py"},"region":{"startLine":188}}}],"partialFingerprints":{"codehealthFindingId/v1":"e8a033278db95fb6d569f9183365091c7e28d68600e14845e54955880de38f86"}},{"ruleId":"D1","level":"warning","message":{"text":"junctions.derive_junction_projection (cyclomatic 28): junctions.derive_junction_projection 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":"core_memory/graph/junctions.py"},"region":{"startLine":323}}}],"partialFingerprints":{"codehealthFindingId/v1":"46b8844fe2f8c8592fa3dd9cdc635fd111604b25292a09cb459d0e7c1bc4c08f"}},{"ruleId":"D1","level":"warning","message":{"text":"roadmap.build_junction_roadmap (cyclomatic 28): roadmap.build_junction_roadmap 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":"core_memory/graph/roadmap.py"},"region":{"startLine":774}}}],"partialFingerprints":{"codehealthFindingId/v1":"4b8ce134d5b648e35c9caf4918bc3b77e088988e35344e8cea6a2ab60a02c07e"}},{"ruleId":"D1","level":"warning","message":{"text":"entity_merge_flow.apply_entity_merge_for_index (cyclomatic 28): entity_merge_flow.apply_entity_merge_for_index has cyclomatic complexity 28 (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":"core_memory/persistence/entity_merge_flow.py"},"region":{"startLine":133}}}],"partialFingerprints":{"codehealthFindingId/v1":"e1a9b19a688a6856567c00b0c3a279376dc834449badd9bafc7b61f10986b5e8"}},{"ruleId":"D1","level":"warning","message":{"text":"myelination_rewards.emit_myelination_reward_event (cyclomatic 28): myelination_rewards.emit_myelination_reward_event 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":"core_memory/persistence/myelination_rewards.py"},"region":{"startLine":236}}}],"partialFingerprints":{"codehealthFindingId/v1":"58938323752de5cdc8fca405c8ec6edcae1203ab506f642eb1f554b21c7ee22a"}},{"ruleId":"D1","level":"warning","message":{"text":"source_hydration.hydrate_bead_sources_for_root (cyclomatic 28): source_hydration.hydrate_bead_sources_for_root 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":"core_memory/persistence/source_hydration.py"},"region":{"startLine":19}}}],"partialFingerprints":{"codehealthFindingId/v1":"050b76d525ee81a594a4818259ab6e9b09ea7a02c9db6d37b6307d66265455ff"}},{"ruleId":"D1","level":"warning","message":{"text":"chunk_evidence.build_chunk_evidence_corpus (cyclomatic 28): chunk_evidence.build_chunk_evidence_corpus 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":"core_memory/retrieval/chunk_evidence.py"},"region":{"startLine":110}}}],"partialFingerprints":{"codehealthFindingId/v1":"9b622cfda438642ad3b8291d90bd23be9813084d8873bd12757cab9fd6a34aca"}},{"ruleId":"D1","level":"warning","message":{"text":"analysis.synthesize_themes (cyclomatic 28): analysis.synthesize_themes 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":"core_memory/runtime/dreamer/analysis.py"},"region":{"startLine":545}}}],"partialFingerprints":{"codehealthFindingId/v1":"04b817a4c3f73c0445cc3add0d9b30c941a0132c3f8b5f1672ac285420545648"}},{"ruleId":"D1","level":"warning","message":{"text":"engine._enforce_structural_invariants (cyclomatic 28): engine._enforce_structural_invariants 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":"core_memory/runtime/engine.py"},"region":{"startLine":418}}}],"partialFingerprints":{"codehealthFindingId/v1":"5d10bacd17f5bbf99aa6d158c325729bd32eb09851dc6c2bdbfda843f88a9f78"}},{"ruleId":"D1","level":"warning","message":{"text":"semantic_state.mark_semantic_write_state (cyclomatic 28): semantic_state.mark_semantic_write_state has cyclomatic complexity 28 (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":"core_memory/runtime/turn/semantic_state.py"},"region":{"startLine":85}}}],"partialFingerprints":{"codehealthFindingId/v1":"c25b4513d68107716119319e1278e78db24a13afc829551c620f799ae37b7615"}},{"ruleId":"D1","level":"warning","message":{"text":"register::emitFallbackTurn (cyclomatic 28): register::emitFallbackTurn has cyclomatic complexity 28 (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":"plugins/openclaw-core-memory-bridge/index.js"},"region":{"startLine":446}}}],"partialFingerprints":{"codehealthFindingId/v1":"b52e40f7ed40f8a2350dc27ad7c00ae533a17413599a39a15e28ef258ad8b3af"}},{"ruleId":"D1","level":"warning","message":{"text":"root_cause._build_edges (cyclomatic 27): root_cause._build_edges 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":"core_memory/graph/root_cause.py"},"region":{"startLine":163}}}],"partialFingerprints":{"codehealthFindingId/v1":"92a868df35b1d7469c2a0c839e97a101043b269b1b66cc788e04a76958bdec97"}},{"ruleId":"D1","level":"warning","message":{"text":"ingest_slack.ingest_slack_handler (cyclomatic 27): ingest_slack.ingest_slack_handler has cyclomatic complexity 27 (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":"core_memory/integrations/mcp/tools/ingest_slack.py"},"region":{"startLine":76}}}],"partialFingerprints":{"codehealthFindingId/v1":"74f3a019386fcc1f714db9f0c4101e2343f5f6529c7fa4d9e57965272cafc221"}},{"ruleId":"D1","level":"warning","message":{"text":"recall_payload.run_recall_payload (cyclomatic 27): recall_payload.run_recall_payload has cyclomatic complexity 27 (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":"core_memory/integrations/recall_payload.py"},"region":{"startLine":59}}}],"partialFingerprints":{"codehealthFindingId/v1":"b2c0838db4f688c2dea4a8bf2d39aba935797ccb8f4305a6027c8423c5bf1c81"}},{"ruleId":"D1","level":"warning","message":{"text":"llm_client.chat_complete (cyclomatic 27): llm_client.chat_complete 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":"core_memory/llm_client.py"},"region":{"startLine":27}}}],"partialFingerprints":{"codehealthFindingId/v1":"4b9b65c240362ef6435a077f72a82d20b0498d336d36927194ebef5ec995b897"}},{"ruleId":"D1","level":"warning","message":{"text":"dreamer_candidate_store.enqueue_contradiction_pressure_candidates (cyclomatic 27): dreamer_candidate_store.enqueue_contradiction_pressure_candidates 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":"core_memory/persistence/dreamer_candidate_store.py"},"region":{"startLine":152}}}],"partialFingerprints":{"codehealthFindingId/v1":"fad4dd3a82bc6b0eb5380caf2c455d22af963e9a642238bb68f0a890906d9710"}},{"ruleId":"D1","level":"warning","message":{"text":"myelination_rewards.supporting_edge_keys_for_bead (cyclomatic 27): myelination_rewards.supporting_edge_keys_for_bead 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":"core_memory/persistence/myelination_rewards.py"},"region":{"startLine":164}}}],"partialFingerprints":{"codehealthFindingId/v1":"3cc0ee2e9cc86f93a4d6c1982af01917617abc1da74711e87b5d3073182c10cb"}},{"ruleId":"D1","level":"warning","message":{"text":"retrieval_feedback.summarize_retrieval_feedback (cyclomatic 27): retrieval_feedback.summarize_retrieval_feedback has cyclomatic complexity 27 (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":"core_memory/persistence/retrieval_feedback.py"},"region":{"startLine":180}}}],"partialFingerprints":{"codehealthFindingId/v1":"db35eefe9a88218a1468d6dfda95b73684dc7af30e73ccdc6338a1da5f58646e"}},{"ruleId":"D1","level":"warning","message":{"text":"agent._resolved_goals_for_result (cyclomatic 27): agent._resolved_goals_for_result 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":"core_memory/retrieval/agent.py"},"region":{"startLine":139}}}],"partialFingerprints":{"codehealthFindingId/v1":"1078be606653e3ddec6657a97c56184cc2eb26c0a0da065a9a1bb152ebc820e7"}},{"ruleId":"D1","level":"warning","message":{"text":"catalog.build_catalog (cyclomatic 27): catalog.build_catalog 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":"core_memory/retrieval/pipeline/catalog.py"},"region":{"startLine":14}}}],"partialFingerprints":{"codehealthFindingId/v1":"79e0e30d1e24dbc52f95038d6ea6a5ca207c401e127e50cbbbf6fd20b3b17b77"}},{"ruleId":"D1","level":"warning","message":{"text":"roadmap_planner.plan_over_roadmap (cyclomatic 27): roadmap_planner.plan_over_roadmap 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":"core_memory/retrieval/roadmap_planner.py"},"region":{"startLine":657}}}],"partialFingerprints":{"codehealthFindingId/v1":"5fc35e67079b88ecd6929666ac3d0104eb8d9902df20b2b58a51c9a1cfdbc673"}},{"ruleId":"D1","level":"warning","message":{"text":"semantic_index._provider_vectors (cyclomatic 27): semantic_index._provider_vectors has cyclomatic complexity 27 (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":"core_memory/retrieval/semantic_index.py"},"region":{"startLine":768}}}],"partialFingerprints":{"codehealthFindingId/v1":"cdd5bca3fc23ca28d473e751492116fc8e9130b9e836af9b1593e03fc8bec1ff"}},{"ruleId":"D1","level":"warning","message":{"text":"identity_value_research.enqueue_identity_value_candidates (cyclomatic 27): identity_value_research.enqueue_identity_value_candidates 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":"core_memory/runtime/dreamer/identity_value_research.py"},"region":{"startLine":38}}}],"partialFingerprints":{"codehealthFindingId/v1":"8103f590eaf5a901772e3cdab75d0eeb55ddf2eea0b772ccb2a7c735ef999169"}},{"ruleId":"D1","level":"warning","message":{"text":"external_evidence._validate_external_payload (cyclomatic 27): external_evidence._validate_external_payload 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":"core_memory/runtime/ingest/external_evidence.py"},"region":{"startLine":372}}}],"partialFingerprints":{"codehealthFindingId/v1":"ffadce80f095eca275c043628b6dfef1df340acad4897a91388f8ba9c558767d"}},{"ruleId":"D1","level":"warning","message":{"text":"agent_crawler_invoke.invoke_turn_crawler_agent (cyclomatic 27): agent_crawler_invoke.invoke_turn_crawler_agent 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":"core_memory/runtime/passes/agent_crawler_invoke.py"},"region":{"startLine":20}}}],"partialFingerprints":{"codehealthFindingId/v1":"819a32d3b89ea42d91cf27eabadabe395dcc6acd32dc9951ab59782c0b65a20e"}},{"ruleId":"D1","level":"warning","message":{"text":"session_start_flow.build_session_start_snapshot (cyclomatic 27): session_start_flow.build_session_start_snapshot has cyclomatic complexity 27 (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":"core_memory/runtime/session/session_start_flow.py"},"region":{"startLine":31}}}],"partialFingerprints":{"codehealthFindingId/v1":"9bdd03a0d4ae5f9ef3c8d2b557fd0400ae346d9ff7eff7f3dbf1dce46e5a101f"}},{"ruleId":"D1","level":"warning","message":{"text":"transcript_ingest.ingest_turn_envelopes (cyclomatic 27): transcript_ingest.ingest_turn_envelopes 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":"core_memory/transcript_ingest.py"},"region":{"startLine":344}}}],"partialFingerprints":{"codehealthFindingId/v1":"2136cfb90b3224c73e21c6dea8a22848e6d066e59eb7e4c186a9d623fe759e35"}},{"ruleId":"D1","level":"warning","message":{"text":"worldlines._goal_worldlines (cyclomatic 26): worldlines._goal_worldlines 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":"core_memory/graph/worldlines.py"},"region":{"startLine":161}}}],"partialFingerprints":{"codehealthFindingId/v1":"8ee235013b98ed69b53fa4b2fd0403074a9a6cc57acf73c18c5e184ee2bf15e0"}},{"ruleId":"D1","level":"warning","message":{"text":"hosted_capture_bridge.process_hosted_capture_event (cyclomatic 26): hosted_capture_bridge.process_hosted_capture_event has cyclomatic complexity 26 (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":"core_memory/integrations/openclaw/hosted_capture_bridge.py"},"region":{"startLine":186}}}],"partialFingerprints":{"codehealthFindingId/v1":"20fdd9e3938da27f276963a11fd9906d333f5ded634f1cd78448c7e0707fbc6b"}},{"ruleId":"D1","level":"warning","message":{"text":"store_management_ops.deactivate_association_for_store (cyclomatic 26): store_management_ops.deactivate_association_for_store has cyclomatic complexity 26 (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":"core_memory/persistence/store_management_ops.py"},"region":{"startLine":785}}}],"partialFingerprints":{"codehealthFindingId/v1":"2fa2ee1bc7c235a7f3a4abd3b3d3ed31327964506627dcfc26713ecdcf417fed"}},{"ruleId":"D1","level":"warning","message":{"text":"association_inference_v21.validate_and_normalize_inference_payload (cyclomatic 26): association_inference_v21.validate_and_normalize_inference_payload has cyclomatic complexity 26 (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":"core_memory/policy/association_inference_v21.py"},"region":{"startLine":129}}}],"partialFingerprints":{"codehealthFindingId/v1":"1426306007c57d8a871d4330c5e5fe06a8865ee496f301ea1f9f85d61ee1d683"}},{"ruleId":"D1","level":"warning","message":{"text":"causal_recall.build_state_packet (cyclomatic 26): causal_recall.build_state_packet 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":"core_memory/retrieval/causal_recall.py"},"region":{"startLine":247}}}],"partialFingerprints":{"codehealthFindingId/v1":"b2635cd565301aa04012f04477898718994b91d5d6013f3670ade9f91dd49d7e"}},{"ruleId":"D1","level":"warning","message":{"text":"pipeline._normalize_search_request (cyclomatic 26): pipeline._normalize_search_request has cyclomatic complexity 26 (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":"core_memory/retrieval/pipeline/__init__.py"},"region":{"startLine":25}}}],"partialFingerprints":{"codehealthFindingId/v1":"21efae8491133fe3b32d260ee75b916b18fd732bbf2d14e32c79b0393be0a62b"}},{"ruleId":"D1","level":"warning","message":{"text":"canonical._to_anchor (cyclomatic 26): canonical._to_anchor has cyclomatic complexity 26 (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":"core_memory/retrieval/pipeline/canonical.py"},"region":{"startLine":596}}}],"partialFingerprints":{"codehealthFindingId/v1":"250ef38ecac1aabbae5e527585c6b5c5887e94671ae8d83e2f451c5f48083bb6"}},{"ruleId":"D1","level":"warning","message":{"text":"semantic_index.semantic_doctor (cyclomatic 26): semantic_index.semantic_doctor has cyclomatic complexity 26 (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":"core_memory/retrieval/semantic_index.py"},"region":{"startLine":452}}}],"partialFingerprints":{"codehealthFindingId/v1":"aadaa3f628d8796937a9c9701ddc9520047f81e42711ef0c1ec606f83db95f64"}},{"ruleId":"D1","level":"warning","message":{"text":"analysis.run_analysis (cyclomatic 26): analysis.run_analysis 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":"core_memory/runtime/dreamer/analysis.py"},"region":{"startLine":371}}}],"partialFingerprints":{"codehealthFindingId/v1":"221e97aa2f6bcd720dc451cf928a7b0d3a5ee7cc594cb6e7892a171b8bc7dcbf"}},{"ruleId":"D1","level":"warning","message":{"text":"self_model_drift.compute_self_model_drift (cyclomatic 26): self_model_drift.compute_self_model_drift 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":"core_memory/runtime/observability/self_model_drift.py"},"region":{"startLine":129}}}],"partialFingerprints":{"codehealthFindingId/v1":"9dc9a552ef38ad29a392eed0deb9a58a701998e119f7c212c8d0b767579f95ae"}},{"ruleId":"D1","level":"warning","message":{"text":"assembly_depth.compute_assembly_depth (cyclomatic 26): assembly_depth.compute_assembly_depth 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":"core_memory/soul/assembly_depth.py"},"region":{"startLine":135}}}],"partialFingerprints":{"codehealthFindingId/v1":"3e7e321ab542267cbaa28264f411ed6de83c10fdba08205aa712a826fb3c6c38"}},{"ruleId":"D1","level":"warning","message":{"text":"identity_value_signals.detect_identity_value_findings (cyclomatic 26): identity_value_signals.detect_identity_value_findings has cyclomatic complexity 26 (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":"core_memory/soul/identity_value_signals.py"},"region":{"startLine":74}}}],"partialFingerprints":{"codehealthFindingId/v1":"cfee6c660ede68464ac4268c74f7fe8d55794c8402e56a520bf71eb32de7fcd5"}},{"ruleId":"D1","level":"warning","message":{"text":"integrity.soul_integrity_check (cyclomatic 26): integrity.soul_integrity_check 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":"core_memory/soul/integrity.py"},"region":{"startLine":63}}}],"partialFingerprints":{"codehealthFindingId/v1":"07735e4ed0bc56640dc0475fa1011f5931a7d497ab290ffbce8267d3b892dc7a"}},{"ruleId":"D1","level":"warning","message":{"text":"memory_search_ab_compare.main (cyclomatic 26): memory_search_ab_compare.main 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":"eval/memory_search_ab_compare.py"},"region":{"startLine":30}}}],"partialFingerprints":{"codehealthFindingId/v1":"7d5f1864e5bd6d9615610994685f8d6cbfcdb5bf0e182ade1061e475eef4a391"}},{"ruleId":"D1","level":"warning","message":{"text":"check_architecture_guards.main (cyclomatic 26): check_architecture_guards.main 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":"scripts/check_architecture_guards.py"},"region":{"startLine":1100}}}],"partialFingerprints":{"codehealthFindingId/v1":"e4e261b15f64a739823797aca44b91872b536ad4ebca81097b4ffcf3b55bed8a"}},{"ruleId":"D1","level":"warning","message":{"text":"edge_lifecycle.collect_used_edge_pairs (cyclomatic 25): edge_lifecycle.collect_used_edge_pairs 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":"core_memory/association/edge_lifecycle.py"},"region":{"startLine":60}}}],"partialFingerprints":{"codehealthFindingId/v1":"444ceafba6387edfeffcb1d28ba74a89acd3cf3e215b5f18475700ea29ca8e06"}},{"ruleId":"D1","level":"warning","message":{"text":"slo.association_slo_report (cyclomatic 25): slo.association_slo_report has cyclomatic complexity 25 (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":"core_memory/association/slo.py"},"region":{"startLine":65}}}],"partialFingerprints":{"codehealthFindingId/v1":"55d4c482b7580556d88898a4c56baf14fef9224cc37cce96dd9aef6ef734fabf"}},{"ruleId":"D1","level":"warning","message":{"text":"retrieval_planner.plan_retrieval_mode (cyclomatic 25): retrieval_planner.plan_retrieval_mode 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":"core_memory/claim/retrieval_planner.py"},"region":{"startLine":73}}}],"partialFingerprints":{"codehealthFindingId/v1":"2d0dd582983e98f2d56aa328a672205521b487dc96023e096f1ed98d11c42c39"}},{"ruleId":"D1","level":"warning","message":{"text":"roadmap.edge_cost_row (cyclomatic 25): roadmap.edge_cost_row has cyclomatic complexity 25 (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":"core_memory/graph/roadmap.py"},"region":{"startLine":229}}}],"partialFingerprints":{"codehealthFindingId/v1":"7645465f6dbe746ff02fd4874818d8ca3b3b75aeeca89dd4d898fe5c091cc27e"}},{"ruleId":"D1","level":"warning","message":{"text":"onboard.harden_openclaw_plugin_config (cyclomatic 25): onboard.harden_openclaw_plugin_config has cyclomatic complexity 25 (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":"core_memory/integrations/openclaw/onboard.py"},"region":{"startLine":39}}}],"partialFingerprints":{"codehealthFindingId/v1":"b7f59f82d3bd596d6b31c6eb0ff87e4ec66594915d30e3f6129a0641f2bde667"}},{"ruleId":"D1","level":"warning","message":{"text":"store_autonomy_ops.reinforcement_signals_for_store (cyclomatic 25): store_autonomy_ops.reinforcement_signals_for_store has cyclomatic complexity 25 (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":"core_memory/persistence/store_autonomy_ops.py"},"region":{"startLine":6}}}],"partialFingerprints":{"codehealthFindingId/v1":"4a3f7b8490452702641121b302695f8654a5e5603462dd3ea6aad8e8f2408085"}},{"ruleId":"D1","level":"warning","message":{"text":"store_claim_ops.find_canonical_turn_bead_id (cyclomatic 25): store_claim_ops.find_canonical_turn_bead_id 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":"core_memory/persistence/store_claim_ops.py"},"region":{"startLine":84}}}],"partialFingerprints":{"codehealthFindingId/v1":"4a8878d3ffdc2ca9ec8bd609c8dbd4d6ed4266e19948f2e76dd5a5de3e27ed5c"}},{"ruleId":"D1","level":"warning","message":{"text":"store_compaction_ops.compact_for_store (cyclomatic 25): store_compaction_ops.compact_for_store has cyclomatic complexity 25 (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":"core_memory/persistence/store_compaction_ops.py"},"region":{"startLine":14}}}],"partialFingerprints":{"codehealthFindingId/v1":"376089cf6de241cda80fc1cacd68f33cd4c628de4932801255024a8449594962"}},{"ruleId":"D1","level":"warning","message":{"text":"causal_recall.extract_source_citations (cyclomatic 25): causal_recall.extract_source_citations 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":"core_memory/retrieval/causal_recall.py"},"region":{"startLine":146}}}],"partialFingerprints":{"codehealthFindingId/v1":"22cef7479c5bd3df589743709041293d7869175a74354930555cbf874e22c8f4"}},{"ruleId":"D1","level":"warning","message":{"text":"eval._label_summary (cyclomatic 25): eval._label_summary has cyclomatic complexity 25 (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":"core_memory/runtime/dreamer/eval.py"},"region":{"startLine":204}}}],"partialFingerprints":{"codehealthFindingId/v1":"e2a74cdb54994f9ecb4aac79cb972d44e3c2fc0bb81bfdf0f3bc22e2d0549d78"}},{"ruleId":"D1","level":"warning","message":{"text":"research._bead_context (cyclomatic 25): research._bead_context has cyclomatic complexity 25 (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":"core_memory/runtime/dreamer/research.py"},"region":{"startLine":98}}}],"partialFingerprints":{"codehealthFindingId/v1":"30e456cb4d1436d8aac5cc887db28742b526aef6af3c1280d4baf77e9ade6994"}},{"ruleId":"D1","level":"warning","message":{"text":"compaction_queue.drain_compaction_queue (cyclomatic 25): compaction_queue.drain_compaction_queue has cyclomatic complexity 25 (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":"core_memory/runtime/queue/compaction_queue.py"},"region":{"startLine":122}}}],"partialFingerprints":{"codehealthFindingId/v1":"b9a7b2fc9a58d41c6152b19c7b0831ca4a79c79b8597a161c3ec5ffa4892924a"}},{"ruleId":"D1","level":"warning","message":{"text":"goal_lifecycle.resolve_goals_for_turn (cyclomatic 25): goal_lifecycle.resolve_goals_for_turn 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":"core_memory/runtime/session/goal_lifecycle.py"},"region":{"startLine":51}}}],"partialFingerprints":{"codehealthFindingId/v1":"389fd9475b4d7028daccabe538e713df794bbf306b2a7f14e7d87b095c72ddf5"}},{"ruleId":"D1","level":"warning","message":{"text":"promotion._reinforcement_signals (cyclomatic 25): promotion._reinforcement_signals has cyclomatic complexity 25 (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":"core_memory/schema/promotion.py"},"region":{"startLine":81}}}],"partialFingerprints":{"codehealthFindingId/v1":"d0aac788061f136569b3030951120bbca5c36d1cfb9018cd6632e59f64e36aa8"}},{"ruleId":"D1","level":"warning","message":{"text":"summary._tension_light_cone_reports (cyclomatic 25): summary._tension_light_cone_reports has cyclomatic complexity 25 (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":"core_memory/soul/summary.py"},"region":{"startLine":527}}}],"partialFingerprints":{"codehealthFindingId/v1":"3dec0374d6d8f4f3f0c723096b78db9a3c4a624f1c11b6e1eb29ed9f0463e43d"}},{"ruleId":"D1","level":"warning","message":{"text":"edge_lifecycle.fold_edge_usage (cyclomatic 24): edge_lifecycle.fold_edge_usage 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":"core_memory/association/edge_lifecycle.py"},"region":{"startLine":131}}}],"partialFingerprints":{"codehealthFindingId/v1":"8a22026c41094afc161634d96f3e1efc43e41a8c16298596f61a5198bfda7a62"}},{"ruleId":"D1","level":"warning","message":{"text":"update_policy.emit_claim_updates (cyclomatic 24): update_policy.emit_claim_updates 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":"core_memory/claim/update_policy.py"},"region":{"startLine":123}}}],"partialFingerprints":{"codehealthFindingId/v1":"97bdff5eca6c3ad9d8b5b8c1237652880dec683c664ec5eb14133faa0b1387c8"}},{"ruleId":"D1","level":"warning","message":{"text":"sync._dedupe_projection (cyclomatic 24): sync._dedupe_projection has cyclomatic complexity 24 (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":"core_memory/integrations/neo4j/sync.py"},"region":{"startLine":246}}}],"partialFingerprints":{"codehealthFindingId/v1":"0608ab2061b8c756231cb69958e20813de0987da94fd55663e42dde8a7414675"}},{"ruleId":"D1","level":"warning","message":{"text":"store_management_ops.remove_source_beads_for_store (cyclomatic 24): store_management_ops.remove_source_beads_for_store 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":"core_memory/persistence/store_management_ops.py"},"region":{"startLine":474}}}],"partialFingerprints":{"codehealthFindingId/v1":"b4b00492649b56c877b6980f1ab2936bec0c9d94566ea215c3c41cf31bf4b1be"}},{"ruleId":"D1","level":"warning","message":{"text":"hygiene.curated_type_title_hygiene (cyclomatic 24): hygiene.curated_type_title_hygiene 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":"core_memory/policy/hygiene.py"},"region":{"startLine":45}}}],"partialFingerprints":{"codehealthFindingId/v1":"24055d88080e1201446ab69c47198c93f780a3413ed72eea9ccd030d945210df"}},{"ruleId":"D1","level":"warning","message":{"text":"agent._normalize_request (cyclomatic 24): agent._normalize_request 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":"core_memory/retrieval/agent.py"},"region":{"startLine":376}}}],"partialFingerprints":{"codehealthFindingId/v1":"c517c503ae22b6d582799d6df1f5bfb31cfbf2a1979fff2c09f7b308cdcee883"}},{"ruleId":"D1","level":"warning","message":{"text":"rerank._load_structural_adjacency (cyclomatic 24): rerank._load_structural_adjacency 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":"core_memory/retrieval/rerank.py"},"region":{"startLine":113}}}],"partialFingerprints":{"codehealthFindingId/v1":"83e983df1634a26f6cd4c45bc5fb6dd9de1c21fbdbbeca985f5cc2575b5800b5"}},{"ruleId":"D1","level":"warning","message":{"text":"retrieval_value_overrides.apply_retrieval_value_override_for_index (cyclomatic 24): retrieval_value_overrides.apply_retrieval_value_override_for_index has cyclomatic complexity 24 (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":"core_memory/runtime/observability/retrieval_value_overrides.py"},"region":{"startLine":55}}}],"partialFingerprints":{"codehealthFindingId/v1":"1118ca379d880cbc12b88ba2dcc6a38399bc250a38c9d79a869b1c791e25f682"}},{"ruleId":"D1","level":"warning","message":{"text":"reauthoring.retry_pending_semantic (cyclomatic 24): reauthoring.retry_pending_semantic 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":"core_memory/runtime/turn/reauthoring.py"},"region":{"startLine":921}}}],"partialFingerprints":{"codehealthFindingId/v1":"a2f17301fd24483ed5a761718e5ea9ee02a066951fd0af191729cd3e880c0e7d"}},{"ruleId":"D1","level":"warning","message":{"text":"diagnostics.simple_recall_fallback (cyclomatic 23): diagnostics.simple_recall_fallback has cyclomatic complexity 23 (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":"core_memory/cli/diagnostics.py"},"region":{"startLine":170}}}],"partialFingerprints":{"codehealthFindingId/v1":"179ffdf49c632e0f5fc5d34abcdda7a3cbad151ae91f8295cce1a4235713dd6a"}},{"ruleId":"D1","level":"warning","message":{"text":"sync._collect_projection (cyclomatic 23): sync._collect_projection 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":"core_memory/integrations/neo4j/sync.py"},"region":{"startLine":151}}}],"partialFingerprints":{"codehealthFindingId/v1":"93018c938dd39f7b15637eaa7bda867051dc05f9e313ca357faba38d349645ec"}},{"ruleId":"D1","level":"warning","message":{"text":"promotion_service.resolve_goal_candidate_for_store (cyclomatic 23): promotion_service.resolve_goal_candidate_for_store has cyclomatic complexity 23 (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":"core_memory/persistence/promotion_service.py"},"region":{"startLine":288}}}],"partialFingerprints":{"codehealthFindingId/v1":"36925d82b6d4c2feaa193c55ea42739a89372e0f7a3cfed9932f6b7044e720f3"}},{"ruleId":"D1","level":"warning","message":{"text":"bead_judge._normalize_judged_fields (cyclomatic 23): bead_judge._normalize_judged_fields has cyclomatic complexity 23 (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":"core_memory/policy/bead_judge.py"},"region":{"startLine":371}}}],"partialFingerprints":{"codehealthFindingId/v1":"b5d23f30af56bcaf205437ff59eee5a253a31056ac5486cb71786693984909c7"}},{"ruleId":"D1","level":"warning","message":{"text":"causal_recall.attach_causal_recall_pipeline (cyclomatic 23): causal_recall.attach_causal_recall_pipeline 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":"core_memory/retrieval/causal_recall.py"},"region":{"startLine":521}}}],"partialFingerprints":{"codehealthFindingId/v1":"95d08fe9e97daa4e519baa8c2cc04e54e36964a37efe4189c52a169d85aaa997"}},{"ruleId":"D1","level":"warning","message":{"text":"roadmap_planner._fallback (cyclomatic 23): roadmap_planner._fallback has cyclomatic complexity 23 (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":"core_memory/retrieval/roadmap_planner.py"},"region":{"startLine":511}}}],"partialFingerprints":{"codehealthFindingId/v1":"6eec2a495b675e0926019a0a34c5256098c4290dc5824764beac1f7ffa025377"}},{"ruleId":"D1","level":"warning","message":{"text":"memory_reason._chain_coherence (cyclomatic 23): memory_reason._chain_coherence has cyclomatic complexity 23 (threshold 15). To reduce it, split the body: these branches sit side by side rather than nested inside one another, so extracting each one on its own would leave a function per branch. Group the statements between the checks into named steps and move each step into its own function, so the body reads as a short sequence of named stages."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"core_memory/retrieval/tools/memory_reason.py"},"region":{"startLine":121}}}],"partialFingerprints":{"codehealthFindingId/v1":"e5f1189c0e3594d40b053f7083dc0d6b64ad236728d11a9a6daa88a604765442"}},{"ruleId":"D1","level":"warning","message":{"text":"projection.compute_future_projections (cyclomatic 23): projection.compute_future_projections has cyclomatic complexity 23 (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":"core_memory/runtime/dreamer/projection.py"},"region":{"startLine":159}}}],"partialFingerprints":{"codehealthFindingId/v1":"5176df7cfdf28834d792f3135741e2270e1663982bf1fa19a036f8465d7ab721"}},{"ruleId":"D1","level":"warning","message":{"text":"external_evidence._bead_payload (cyclomatic 23): external_evidence._bead_payload has cyclomatic complexity 23 (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":"core_memory/runtime/ingest/external_evidence.py"},"region":{"startLine":417}}}],"partialFingerprints":{"codehealthFindingId/v1":"fefd9a9bebb880979791a5de77e2f41418915ad94eb318414e7f678c3bc20d38"}},{"ruleId":"D1","level":"warning","message":{"text":"retrieval_eval._causal_grounding_components (cyclomatic 23): retrieval_eval._causal_grounding_components 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":"eval/retrieval_eval.py"},"region":{"startLine":22}}}],"partialFingerprints":{"codehealthFindingId/v1":"aceeb81ff57127bcfac896c84c3cd02e0cff733d1a2c84d621811a9b469cd81c"}},{"ruleId":"D1","level":"warning","message":{"text":"answer_policy.explain_answer_outcome (cyclomatic 22): answer_policy.explain_answer_outcome has cyclomatic complexity 22 (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":"core_memory/claim/answer_policy.py"},"region":{"startLine":77}}}],"partialFingerprints":{"codehealthFindingId/v1":"4411ae8109bba4c429d616a86aa91d4b11e37195e5e53e4c5d95c67d8f5b41a5"}},{"ruleId":"D1","level":"warning","message":{"text":"migrate.handle_migrate (cyclomatic 22): migrate.handle_migrate 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":"core_memory/cli/handlers/migrate.py"},"region":{"startLine":68}}}],"partialFingerprints":{"codehealthFindingId/v1":"aeff392ae440bd7abe1bc24f2567e65fdda3958f38bbd5ea6ac61a620000c511"}},{"ruleId":"D1","level":"warning","message":{"text":"retrieval.expand_query_with_entities (cyclomatic 22): retrieval.expand_query_with_entities 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":"core_memory/entity/retrieval.py"},"region":{"startLine":63}}}],"partialFingerprints":{"codehealthFindingId/v1":"d19b63817fbd23c4e0dea045c850b238f3fb0db89a42878e9c3c2894211834b9"}},{"ruleId":"D1","level":"warning","message":{"text":"api.list_turn_summaries (cyclomatic 22): api.list_turn_summaries 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":"core_memory/integrations/api.py"},"region":{"startLine":601}}}],"partialFingerprints":{"codehealthFindingId/v1":"ba5acfee9e4399964e4eed432588f912d49f12c133b62a7098223cca85bc77b0"}},{"ruleId":"D1","level":"warning","message":{"text":"connector._build_default_branch_doc_push (cyclomatic 22): connector._build_default_branch_doc_push 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":"core_memory/integrations/github/connector.py"},"region":{"startLine":170}}}],"partialFingerprints":{"codehealthFindingId/v1":"90d396ebaa2c742e8b08c35aabab6ded302c46287c86dc7fd7cbebbd944f3287"}},{"ruleId":"D1","level":"warning","message":{"text":"semantic_tasks._result_from_payload (cyclomatic 22): semantic_tasks._result_from_payload has cyclomatic complexity 22 (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":"core_memory/integrations/remote/semantic_tasks.py"},"region":{"startLine":137}}}],"partialFingerprints":{"codehealthFindingId/v1":"da09f60e4195fe51effd5f9d0f266ad160f624e3516471d9083adbb289cfdd9b"}},{"ruleId":"D1","level":"warning","message":{"text":"store_compaction_ops.uncompact_for_store (cyclomatic 22): store_compaction_ops.uncompact_for_store 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":"core_memory/persistence/store_compaction_ops.py"},"region":{"startLine":86}}}],"partialFingerprints":{"codehealthFindingId/v1":"67ecbcbf609f5a7ab89a91cd9449a1c5ff6e1780441c19f2f0c6488ea07c2369"}},{"ruleId":"D1","level":"warning","message":{"text":"agent._claim_slots_for_result (cyclomatic 22): agent._claim_slots_for_result 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":"core_memory/retrieval/agent.py"},"region":{"startLine":205}}}],"partialFingerprints":{"codehealthFindingId/v1":"d44935d80cf35489c0f4a817cec8bd58a419ad618712c00fe2c8877f3eef4790"}},{"ruleId":"D1","level":"warning","message":{"text":"snap.snap_form (cyclomatic 22): snap.snap_form has cyclomatic complexity 22 (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":"core_memory/retrieval/pipeline/snap.py"},"region":{"startLine":43}}}],"partialFingerprints":{"codehealthFindingId/v1":"9b828bc5e59b9fa7901056889eea4c02309ff909b94992225271ad51d681d4cd"}},{"ruleId":"D1","level":"warning","message":{"text":"external_evidence._run_semantic_enrichment (cyclomatic 22): external_evidence._run_semantic_enrichment 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":"core_memory/runtime/ingest/external_evidence.py"},"region":{"startLine":591}}}],"partialFingerprints":{"codehealthFindingId/v1":"dca4fa2f73f861ef4f47901db66e4362c39815033a13757cb25cf009e097ee04"}},{"ruleId":"D1","level":"warning","message":{"text":"semantic_state.semantic_write_health (cyclomatic 22): semantic_state.semantic_write_health has cyclomatic complexity 22 (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":"core_memory/runtime/turn/semantic_state.py"},"region":{"startLine":201}}}],"partialFingerprints":{"codehealthFindingId/v1":"493ff2059931bba93177cfe872759032060911f481368c524018722e1d779654"}},{"ruleId":"D1","level":"warning","message":{"text":"assembly_depth._raw_factors (cyclomatic 22): assembly_depth._raw_factors has cyclomatic complexity 22 (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":"core_memory/soul/assembly_depth.py"},"region":{"startLine":76}}}],"partialFingerprints":{"codehealthFindingId/v1":"737e96899ce0e994d46960e2a7b5466a73fce0d8e9f07429dcc4e4795159a109"}},{"ruleId":"D1","level":"warning","message":{"text":"transcript_ingest._group_envelopes (cyclomatic 22): transcript_ingest._group_envelopes 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":"core_memory/transcript_ingest.py"},"region":{"startLine":104}}}],"partialFingerprints":{"codehealthFindingId/v1":"40a4ea81c8e45fecae134b1d3c7a5beb643b058e17e7e039bcec007ce3d9990d"}},{"ruleId":"D1","level":"warning","message":{"text":"check_architecture_guards.check_deterministic_semantic_writers (cyclomatic 22): check_architecture_guards.check_deterministic_semantic_writers 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":"scripts/check_architecture_guards.py"},"region":{"startLine":806}}}],"partialFingerprints":{"codehealthFindingId/v1":"d6b17eedd7ae795f80cb62708a2bc88016fbd787cc6d864110bbf16314b78558"}},{"ruleId":"D1","level":"warning","message":{"text":"typed_read.query_current_state (cyclomatic 21): typed_read.query_current_state has cyclomatic complexity 21 (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":"core_memory/integrations/mcp/typed_read.py"},"region":{"startLine":168}}}],"partialFingerprints":{"codehealthFindingId/v1":"71a457c39f9b38edbd6e1dd8db4e218daa94e8675c9619d0f786bea2ddd4f5d3"}},{"ruleId":"D1","level":"warning","message":{"text":"typed_read.query_contradictions (cyclomatic 21): typed_read.query_contradictions has cyclomatic complexity 21 (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":"core_memory/integrations/mcp/typed_read.py"},"region":{"startLine":288}}}],"partialFingerprints":{"codehealthFindingId/v1":"fc62b44e14728ae7c9d0fbed009ab819d5f8305dfaa97f63f5df68658a8731f4"}},{"ruleId":"D1","level":"warning","message":{"text":"chunk_turns.list_chunk_turns (cyclomatic 21): chunk_turns.list_chunk_turns 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":"core_memory/runtime/ingest/chunk_turns.py"},"region":{"startLine":263}}}],"partialFingerprints":{"codehealthFindingId/v1":"7d35c893be18aac903eb9aeaa7ad3ba7fed5b7ccd735ad5215fe620e8effad11"}},{"ruleId":"D1","level":"warning","message":{"text":"store.propose_soul_update (cyclomatic 21): store.propose_soul_update has cyclomatic complexity 21 (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":"core_memory/soul/store.py"},"region":{"startLine":201}}}],"partialFingerprints":{"codehealthFindingId/v1":"c783c7fd690c6cac336ecd2971f01ff3992391ecfc7653fe0a2167d6b5f1440c"}},{"ruleId":"D1","level":"warning","message":{"text":"quarantine.write_quarantine (cyclomatic 20): quarantine.write_quarantine 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":"core_memory/association/quarantine.py"},"region":{"startLine":37}}}],"partialFingerprints":{"codehealthFindingId/v1":"f913faa93540e22ffd1160050f632d84c48319d9706f109b792298d6bd9f6882"}},{"ruleId":"D1","level":"warning","message":{"text":"junctions.resolve_junction_matches (cyclomatic 20): junctions.resolve_junction_matches has cyclomatic complexity 20 (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":"core_memory/graph/junctions.py"},"region":{"startLine":437}}}],"partialFingerprints":{"codehealthFindingId/v1":"5b78105a691d1960d22eb0af00125d5505aec0bbe6337aa894601d1249d5ffb2"}},{"ruleId":"D1","level":"warning","message":{"text":"root_cause.root_cause_trace (cyclomatic 20): root_cause.root_cause_trace 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":"core_memory/graph/root_cause.py"},"region":{"startLine":1277}}}],"partialFingerprints":{"codehealthFindingId/v1":"b72c820dbaf2819f2336b091cf680b210a37e09b83bf9f0b70cc7a3db8c119cb"}},{"ruleId":"D1","level":"warning","message":{"text":"myelination_rewards.reward_claim_conflict_resolution (cyclomatic 20): myelination_rewards.reward_claim_conflict_resolution 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":"core_memory/persistence/myelination_rewards.py"},"region":{"startLine":527}}}],"partialFingerprints":{"codehealthFindingId/v1":"3f9bea45115179ca2b1273230e722b2cd00bdee5cda935d8c0edac2bc172bb55"}},{"ruleId":"D1","level":"warning","message":{"text":"store_reporting.metrics_report_for_store (cyclomatic 20): store_reporting.metrics_report_for_store 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":"core_memory/persistence/store_reporting.py"},"region":{"startLine":22}}}],"partialFingerprints":{"codehealthFindingId/v1":"2fc050429384158ac991a938a24528360ba0e7fd05994be043ef77bafca9c1f2"}},{"ruleId":"D1","level":"warning","message":{"text":"pipehouse_adapter.retrieve (cyclomatic 20): pipehouse_adapter.retrieve 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":"core_memory/retrieval/adapters/pipehouse_adapter.py"},"region":{"startLine":30}}}],"partialFingerprints":{"codehealthFindingId/v1":"9bb986d1862a676ee13c3cb7e972aa7b70524aed8a12e2480d02f4913034a298"}},{"ruleId":"D1","level":"warning","message":{"text":"canonical._locomo_dia_ids_from_bead (cyclomatic 20): canonical._locomo_dia_ids_from_bead 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":"core_memory/retrieval/pipeline/canonical.py"},"region":{"startLine":558}}}],"partialFingerprints":{"codehealthFindingId/v1":"597c835ac91651b937bdf14baebebeb411865c4684bd2d5e0c8dfa525ace49a8"}},{"ruleId":"D1","level":"warning","message":{"text":"rerank.rerank_candidates (cyclomatic 20): rerank.rerank_candidates 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":"core_memory/retrieval/rerank.py"},"region":{"startLine":221}}}],"partialFingerprints":{"codehealthFindingId/v1":"a4487270be5aedc2a05677c3a755e4c9618da6199ad03ae513776b559026c28e"}},{"ruleId":"D1","level":"warning","message":{"text":"analysis._load_seen_state (cyclomatic 20): analysis._load_seen_state 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":"core_memory/runtime/dreamer/analysis.py"},"region":{"startLine":36}}}],"partialFingerprints":{"codehealthFindingId/v1":"6cf1cc22cca35f1fbaa51afcb85b935c0d75fa093f12d6a29b53f1708fb37831"}},{"ruleId":"D1","level":"warning","message":{"text":"candidates.submit_entity_merge_candidate (cyclomatic 20): candidates.submit_entity_merge_candidate has cyclomatic complexity 20 (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":"core_memory/runtime/dreamer/candidates.py"},"region":{"startLine":1112}}}],"partialFingerprints":{"codehealthFindingId/v1":"c1047523fce295b5f4e57b1286fb4d90ebf90a5db0d829fc04cea35115d08646"}},{"ruleId":"D1","level":"warning","message":{"text":"convergence.detect_worldline_convergence (cyclomatic 20): convergence.detect_worldline_convergence 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":"core_memory/runtime/dreamer/convergence.py"},"region":{"startLine":46}}}],"partialFingerprints":{"codehealthFindingId/v1":"cc49e2d325f57593bfb2491d4e8cb61c96a7ed6f26ad8862a574e72e83ba21be"}},{"ruleId":"D1","level":"warning","message":{"text":"external_evidence.ingest_external_evidence (cyclomatic 20): external_evidence.ingest_external_evidence 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":"core_memory/runtime/ingest/external_evidence.py"},"region":{"startLine":684}}}],"partialFingerprints":{"codehealthFindingId/v1":"e4aaa275111b4397b403aacf95490325f8bfa0de7df7c3cf7ae340ff0e0f9a65"}},{"ruleId":"D1","level":"warning","message":{"text":"jobs.enqueue_async_job (cyclomatic 20): jobs.enqueue_async_job 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":"core_memory/runtime/queue/jobs.py"},"region":{"startLine":192}}}],"partialFingerprints":{"codehealthFindingId/v1":"955ae4809cb70eb36ede6ae7cc7b4341d8aa6f24f03b2986849a3337bb0a66de"}},{"ruleId":"D1","level":"warning","message":{"text":"injection.soul_injection (cyclomatic 20): injection.soul_injection 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":"core_memory/soul/injection.py"},"region":{"startLine":30}}}],"partialFingerprints":{"codehealthFindingId/v1":"be401b317c4157a39f250e55bb36d7b970b5994e55c7ea8541c98d74574d1b1a"}},{"ruleId":"D1","level":"warning","message":{"text":"tension_signals.detect_goal_conflicts (cyclomatic 20): tension_signals.detect_goal_conflicts 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":"core_memory/soul/tension_signals.py"},"region":{"startLine":43}}}],"partialFingerprints":{"codehealthFindingId/v1":"396ddc4addb9ef400af2fd40775ae10768aa000de3af54f8021715cad5cff8fa"}},{"ruleId":"D1","level":"warning","message":{"text":"audit_store_delegation.main (cyclomatic 20): audit_store_delegation.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":"scripts/audit_store_delegation.py"},"region":{"startLine":74}}}],"partialFingerprints":{"codehealthFindingId/v1":"ac355debaac5620b9e26bb609641b7f9075d8fb26713ad75852b71310c900a29"}},{"ruleId":"D1","level":"warning","message":{"text":"update_policy._normalize_explicit_updates (cyclomatic 19): update_policy._normalize_explicit_updates 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":"core_memory/claim/update_policy.py"},"region":{"startLine":75}}}],"partialFingerprints":{"codehealthFindingId/v1":"5fd4dc148698083cf98deef0a90a4f5e14e2194da3c811ff2d9cdbc1df85d1b1"}},{"ruleId":"D1","level":"warning","message":{"text":"junctions._worldline_identities (cyclomatic 19): junctions._worldline_identities 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":"core_memory/graph/junctions.py"},"region":{"startLine":277}}}],"partialFingerprints":{"codehealthFindingId/v1":"42eaae2e3c7a5c38091881cb1a7c39ff034dbf8eb098d3e39f7d00683d804bb6"}},{"ruleId":"D1","level":"warning","message":{"text":"worldlines._entity_worldlines (cyclomatic 19): worldlines._entity_worldlines 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":"core_memory/graph/worldlines.py"},"region":{"startLine":111}}}],"partialFingerprints":{"codehealthFindingId/v1":"ed4b1214783645c68e6ed3a19b99ea1f79a3d697281666dd8f75ccac8a5266b6"}},{"ruleId":"D1","level":"warning","message":{"text":"server.memory_association_candidate_decide (cyclomatic 19): server.memory_association_candidate_decide 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":"core_memory/integrations/http/server.py"},"region":{"startLine":2000}}}],"partialFingerprints":{"codehealthFindingId/v1":"5f509f737163b57187c7185aa8a5f32857b99681ceb7a097973af55ac1e2d3cf"}},{"ruleId":"D1","level":"warning","message":{"text":"CoreMemoryRetriever._get_relevant_documents (cyclomatic 19): CoreMemoryRetriever._get_relevant_documents 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":"core_memory/integrations/langchain/retriever.py"},"region":{"startLine":67}}}],"partialFingerprints":{"codehealthFindingId/v1":"1016785a4fec6fb87b2c03d10a2b3617f50fbdb6d7c3e6e12f4ef38885cfbad4"}},{"ruleId":"D1","level":"warning","message":{"text":"transcript_snapshot_state.reserve_transcript_snapshot (cyclomatic 19): transcript_snapshot_state.reserve_transcript_snapshot 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":"core_memory/integrations/mcp/tools/transcript_snapshot_state.py"},"region":{"startLine":92}}}],"partialFingerprints":{"codehealthFindingId/v1":"2c5eb10e0898a6d733e53550243c172c7e903ffbcbbcc7289db5ca1d632d8b53"}},{"ruleId":"D1","level":"warning","message":{"text":"mapper.bead_to_node (cyclomatic 19): mapper.bead_to_node 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":"core_memory/integrations/neo4j/mapper.py"},"region":{"startLine":23}}}],"partialFingerprints":{"codehealthFindingId/v1":"c83e4b6762ef349ec079be57d1325d1df294a5d51113399f837ce0854aa26023"}},{"ruleId":"D1","level":"warning","message":{"text":"entity_merge_flow.decide_entity_merge_proposal_for_index (cyclomatic 19): entity_merge_flow.decide_entity_merge_proposal_for_index 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":"core_memory/persistence/entity_merge_flow.py"},"region":{"startLine":204}}}],"partialFingerprints":{"codehealthFindingId/v1":"c9847bc25e82edcc88a4c2e3d0e6add74fa1de8896f27724823457d52eb81c27"}},{"ruleId":"D1","level":"warning","message":{"text":"store_metrics_runtime.append_metric_for_store (cyclomatic 19): store_metrics_runtime.append_metric_for_store 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":"core_memory/persistence/store_metrics_runtime.py"},"region":{"startLine":81}}}],"partialFingerprints":{"codehealthFindingId/v1":"9cbc9e93c47c25d2d6e0d98ef12a59cd497718b930d36b24310b9f953db1306f"}},{"ruleId":"D1","level":"warning","message":{"text":"causal_recall.execute_state_packet (cyclomatic 19): causal_recall.execute_state_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":"core_memory/retrieval/causal_recall.py"},"region":{"startLine":387}}}],"partialFingerprints":{"codehealthFindingId/v1":"dc8f73bf03f0e64816cfeece721c5c8867fc4d69ebb100b7301ae9753faadab1"}},{"ruleId":"D1","level":"warning","message":{"text":"coverage._candidate_association_payload (cyclomatic 19): coverage._candidate_association_payload 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":"core_memory/runtime/associations/coverage.py"},"region":{"startLine":1808}}}],"partialFingerprints":{"codehealthFindingId/v1":"1a16d2bd14fad4a8c82908cbe025c376b119dd36946311587888cf63ab4e1683"}},{"ruleId":"D1","level":"warning","message":{"text":"candidates._entity_similarity (cyclomatic 19): candidates._entity_similarity 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":"core_memory/runtime/dreamer/candidates.py"},"region":{"startLine":60}}}],"partialFingerprints":{"codehealthFindingId/v1":"aff2e6657741897f9d50744f489bc5bf34c2e6b0f3730531eb08b4358a6a1c13"}},{"ruleId":"D1","level":"warning","message":{"text":"session_enrichment_delta.delta_to_crawler_updates (cyclomatic 19): session_enrichment_delta.delta_to_crawler_updates 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":"core_memory/runtime/session/session_enrichment_delta.py"},"region":{"startLine":740}}}],"partialFingerprints":{"codehealthFindingId/v1":"3420f6b080304a7c8591b136fc34ca9f4d366510397f7009c071bae0e8e15426"}},{"ruleId":"D1","level":"warning","message":{"text":"storyline_overlay.validate_storyline_overlay (cyclomatic 19): storyline_overlay.validate_storyline_overlay 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":"core_memory/schema/storyline_overlay.py"},"region":{"startLine":40}}}],"partialFingerprints":{"codehealthFindingId/v1":"5a5aa267766a4a34693803dc2b37a3e8079c6dceb55afccdb19bdbcb56bebe75"}},{"ruleId":"D1","level":"warning","message":{"text":"crawler_contract._maybe_upgrade_context_to_reflection (cyclomatic 18): crawler_contract._maybe_upgrade_context_to_reflection 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":"core_memory/association/crawler_contract.py"},"region":{"startLine":697}}}],"partialFingerprints":{"codehealthFindingId/v1":"ffd005f9e1695a06e94556388bbab4d0510eccb733a3d9b694788f0578a20172"}},{"ruleId":"D1","level":"warning","message":{"text":"resolver.resolve_all_current_state (cyclomatic 18): resolver.resolve_all_current_state has cyclomatic complexity 18 (threshold 15). To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"core_memory/claim/resolver.py"},"region":{"startLine":17}}}],"partialFingerprints":{"codehealthFindingId/v1":"de68aed6c172cd35285679fc81e4419c4c39a0ffc1e0227312576fc77f4f1b1b"}},{"ruleId":"D1","level":"warning","message":{"text":"retrieval.infer_query_entity_context (cyclomatic 18): retrieval.infer_query_entity_context 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":"core_memory/entity/retrieval.py"},"region":{"startLine":17}}}],"partialFingerprints":{"codehealthFindingId/v1":"ed1853e3d8949e61100fb6988e7c2f17847ff21b2b10bc68ed54b966afdc5858"}},{"ruleId":"D1","level":"warning","message":{"text":"edge_weights.normalize_backend_chain (cyclomatic 18): edge_weights.normalize_backend_chain 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":"core_memory/graph/edge_weights.py"},"region":{"startLine":149}}}],"partialFingerprints":{"codehealthFindingId/v1":"e721a6da5075156e9af9c7eb5ccc0f9500238abd9212ef90c4a4e3e6eb7d6252"}},{"ruleId":"D1","level":"warning","message":{"text":"roadmap.sample_junction_identities (cyclomatic 18): roadmap.sample_junction_identities has cyclomatic complexity 18 (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":"core_memory/graph/roadmap.py"},"region":{"startLine":104}}}],"partialFingerprints":{"codehealthFindingId/v1":"0e5765716234eef763767f41fbbda1d3e21e325f4c68fe4e128d9487d9ebdc9e"}},{"ruleId":"D1","level":"warning","message":{"text":"root_cause._path_record (cyclomatic 18): root_cause._path_record has cyclomatic complexity 18 (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":"core_memory/graph/root_cause.py"},"region":{"startLine":480}}}],"partialFingerprints":{"codehealthFindingId/v1":"6c2ef7e1a6ef743e27348c8ace928f84227ccccfb22f6580b9848a681838181e"}},{"ruleId":"D1","level":"warning","message":{"text":"server.turn_finalized (cyclomatic 18): server.turn_finalized has cyclomatic complexity 18 (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":"core_memory/integrations/http/server.py"},"region":{"startLine":801}}}],"partialFingerprints":{"codehealthFindingId/v1":"3e784b30372aa4a7a940883fc6c1104bc10bfd7ffa046c6e30c2546d2d4428b9"}},{"ruleId":"D1","level":"warning","message":{"text":"server.memory_association_runs (cyclomatic 18): server.memory_association_runs has cyclomatic complexity 18 (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":"core_memory/integrations/http/server.py"},"region":{"startLine":2034}}}],"partialFingerprints":{"codehealthFindingId/v1":"4c62b618bdafa58bdc9db81451be9aca3fd2656dc33694277496ff6aca9537db"}},{"ruleId":"D1","level":"warning","message":{"text":"capture.capture_handler (cyclomatic 18): capture.capture_handler has cyclomatic complexity 18 (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":"core_memory/integrations/mcp/tools/capture.py"},"region":{"startLine":35}}}],"partialFingerprints":{"codehealthFindingId/v1":"08b008cf2140c721318ef15df12a5ae9a72341da04657a45e110f3f316430c9f"}},{"ruleId":"D1","level":"warning","message":{"text":"dreamer_candidate_store.make_candidate_row (cyclomatic 18): dreamer_candidate_store.make_candidate_row has cyclomatic complexity 18 (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":"core_memory/persistence/dreamer_candidate_store.py"},"region":{"startLine":102}}}],"partialFingerprints":{"codehealthFindingId/v1":"db05d1ba08ec76684372a3ba592a5d469122b569f5cfe01a38bb2a54032899b6"}},{"ruleId":"D1","level":"warning","message":{"text":"semantic_task_verifier._deterministic_checks (cyclomatic 18): semantic_task_verifier._deterministic_checks 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":"core_memory/policy/semantic_task_verifier.py"},"region":{"startLine":84}}}],"partialFingerprints":{"codehealthFindingId/v1":"835683d9372bec843d7cf56a92570c9d9070b2f55db50ffcd34a7478e84e0997"}},{"ruleId":"D1","level":"warning","message":{"text":"provider_config.resolve_embedding_config (cyclomatic 18): provider_config.resolve_embedding_config 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":"core_memory/provider_config.py"},"region":{"startLine":169}}}],"partialFingerprints":{"codehealthFindingId/v1":"bbd424d088704e70b048694f81910753d31d35c5dcc11f3bbdc2f27939660fd1"}},{"ruleId":"D1","level":"warning","message":{"text":"rerank._chain_features (cyclomatic 18): rerank._chain_features 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":"core_memory/retrieval/rerank.py"},"region":{"startLine":177}}}],"partialFingerprints":{"codehealthFindingId/v1":"5abb256176181eda780c50ee6adda8b6953335f189deb33c8bf9b2cf275ff219"}},{"ruleId":"D1","level":"warning","message":{"text":"coverage.on_bead_committed (cyclomatic 18): coverage.on_bead_committed 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":"core_memory/runtime/associations/coverage.py"},"region":{"startLine":2410}}}],"partialFingerprints":{"codehealthFindingId/v1":"87ec36d69a42fe35fe36673e0f1475d4f81a76d9fc1036c6facbe332a18cb2fa"}},{"ruleId":"D1","level":"warning","message":{"text":"progress._process_goal_progress_pair_page (cyclomatic 18): progress._process_goal_progress_pair_page has cyclomatic complexity 18 (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":"core_memory/runtime/goals/progress.py"},"region":{"startLine":743}}}],"partialFingerprints":{"codehealthFindingId/v1":"f995275a91d5ba1c87641db0fd8b60014351f8542326884df14f28949db799cc"}},{"ruleId":"D1","level":"warning","message":{"text":"seed_backfill.run_seed_quality_backfill (cyclomatic 18): seed_backfill.run_seed_quality_backfill 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":"core_memory/runtime/hygiene/seed_backfill.py"},"region":{"startLine":96}}}],"partialFingerprints":{"codehealthFindingId/v1":"5366af1d949263958940d4ced7233eac9baa893ff3225cd6dd379409149dec61"}},{"ruleId":"D1","level":"warning","message":{"text":"reviewer_quick_value._find_bead_id_by_turn_and_title (cyclomatic 18): reviewer_quick_value._find_bead_id_by_turn_and_title 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":"core_memory/runtime/observability/reviewer_quick_value.py"},"region":{"startLine":28}}}],"partialFingerprints":{"codehealthFindingId/v1":"4d0bee0b852f681300bd30e5fb02b73c20379b744c3675e2bdf2f27eed3f72cb"}},{"ruleId":"D1","level":"warning","message":{"text":"jobs.run_async_jobs (cyclomatic 18): jobs.run_async_jobs 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":"core_memory/runtime/queue/jobs.py"},"region":{"startLine":287}}}],"partialFingerprints":{"codehealthFindingId/v1":"ed287594ce8662a21e994a66ca7ceafd18c54d4dfa911ea5f9b0b5b09ada019b"}},{"ruleId":"D1","level":"warning","message":{"text":"semantic_state.latest_finalized_turn (cyclomatic 18): semantic_state.latest_finalized_turn has cyclomatic complexity 18 (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":"core_memory/runtime/turn/semantic_state.py"},"region":{"startLine":250}}}],"partialFingerprints":{"codehealthFindingId/v1":"3ed31c51ebde422aa13ef1137f9c07ff31e4ffba24761552280759e08ca9e8c4"}},{"ruleId":"D1","level":"warning","message":{"text":"turn_quality.emit_agent_turn_quality_metric (cyclomatic 18): turn_quality.emit_agent_turn_quality_metric has cyclomatic complexity 18 (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":"core_memory/runtime/turn/turn_quality.py"},"region":{"startLine":34}}}],"partialFingerprints":{"codehealthFindingId/v1":"ef149ef55404f560bdd5dae4d695c3bc0e73d16b9e1fed41a1febe7780858de7"}},{"ruleId":"D1","level":"warning","message":{"text":"promotion.compute_promotion_score (cyclomatic 18): promotion.compute_promotion_score 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":"core_memory/schema/promotion.py"},"region":{"startLine":129}}}],"partialFingerprints":{"codehealthFindingId/v1":"fa44e1e1ff59255424322f891dbd25661b968b9b65d9b2e79ce6d0c4d78847a7"}},{"ruleId":"D1","level":"warning","message":{"text":"dreamer_bridge._normalize_drafts (cyclomatic 18): dreamer_bridge._normalize_drafts 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":"core_memory/soul/dreamer_bridge.py"},"region":{"startLine":380}}}],"partialFingerprints":{"codehealthFindingId/v1":"bf57abb70e59be8151d7c46104c4b7e5a684658d7b9900511dc20007320b7fe8"}},{"ruleId":"D1","level":"warning","message":{"text":"store._current_entries (cyclomatic 18): store._current_entries has cyclomatic complexity 18 (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":"core_memory/soul/store.py"},"region":{"startLine":101}}}],"partialFingerprints":{"codehealthFindingId/v1":"7b9c088cddaaafa05e4a645200937133ee3d1ba6d1a3a8331699b6eff3d0d507"}},{"ruleId":"D1","level":"warning","message":{"text":"retrieval_planner._active_slot_hints (cyclomatic 17): retrieval_planner._active_slot_hints 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":"core_memory/claim/retrieval_planner.py"},"region":{"startLine":43}}}],"partialFingerprints":{"codehealthFindingId/v1":"d077ec8d3426280590ff70bf530e8658695198803f3eb1b8ca05e89704d6dd2f"}},{"ruleId":"D1","level":"warning","message":{"text":"root_cause.normalize_causal_hints (cyclomatic 17): root_cause.normalize_causal_hints has cyclomatic complexity 17 (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":"core_memory/graph/root_cause.py"},"region":{"startLine":98}}}],"partialFingerprints":{"codehealthFindingId/v1":"cb2a913c08657ff47ebd717c7fc02a9c77a679761f872c47d8ce42fd6ad990fb"}},{"ruleId":"D1","level":"warning","message":{"text":"root_cause.segment_between (cyclomatic 17): root_cause.segment_between 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":"core_memory/graph/root_cause.py"},"region":{"startLine":1104}}}],"partialFingerprints":{"codehealthFindingId/v1":"ef9542c59e6a1d5f4e1e1d744ab0e3d389d9047fcedc50f0c840bcdf430571cc"}},{"ruleId":"D1","level":"warning","message":{"text":"Neo4jClient._prune_scope (cyclomatic 17): Neo4jClient._prune_scope has cyclomatic complexity 17 (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":"core_memory/integrations/neo4j/client.py"},"region":{"startLine":305}}}],"partialFingerprints":{"codehealthFindingId/v1":"5c75ca52ce41a855b568930eaf406017916f31a83f9570b6d6a05297cd0832d9"}},{"ruleId":"D1","level":"warning","message":{"text":"memory_tools.continuity_prompt (cyclomatic 17): memory_tools.continuity_prompt 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":"core_memory/integrations/pydanticai/memory_tools.py"},"region":{"startLine":102}}}],"partialFingerprints":{"codehealthFindingId/v1":"14b80d42c8bdcfc15b07dcef6922c677f67b93227d0a61eec425fa3aafd4198f"}},{"ruleId":"D1","level":"warning","message":{"text":"entity_merge_flow.suggest_entity_merge_proposals_for_index (cyclomatic 17): entity_merge_flow.suggest_entity_merge_proposals_for_index 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":"core_memory/persistence/entity_merge_flow.py"},"region":{"startLine":60}}}],"partialFingerprints":{"codehealthFindingId/v1":"2fbd52d4bb88a8c2099e6a2fc2a30a1a57f4135fd67cfb7d58aea30eea3ea79c"}},{"ruleId":"D1","level":"warning","message":{"text":"myelination_rewards.reward_dreamer_candidate_decision (cyclomatic 17): myelination_rewards.reward_dreamer_candidate_decision has cyclomatic complexity 17 (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":"core_memory/persistence/myelination_rewards.py"},"region":{"startLine":427}}}],"partialFingerprints":{"codehealthFindingId/v1":"75666cbed9cf576aa921f2ae072c7f29f0369090bd9128710270de5c57e26b65"}},{"ruleId":"D1","level":"warning","message":{"text":"promotion_service.evaluate_candidates_for_store (cyclomatic 17): promotion_service.evaluate_candidates_for_store 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":"core_memory/persistence/promotion_service.py"},"region":{"startLine":77}}}],"partialFingerprints":{"codehealthFindingId/v1":"c8143cbf0288006ff94eacfadd1367bc52ec47e25a6df8ad8db5fdf4c1033091"}},{"ruleId":"D1","level":"warning","message":{"text":"promotion_service.apply_agent_promotion_reviews_for_store (cyclomatic 17): promotion_service.apply_agent_promotion_reviews_for_store has cyclomatic complexity 17 (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":"core_memory/persistence/promotion_service.py"},"region":{"startLine":394}}}],"partialFingerprints":{"codehealthFindingId/v1":"c90fb7f9046e559e3937d172284d6a3a9d80a3e1edc72bf60b8e618f6c84c3c4"}},{"ruleId":"D1","level":"warning","message":{"text":"promotion_service.decide_session_promotion_states_for_store (cyclomatic 17): promotion_service.decide_session_promotion_states_for_store 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":"core_memory/persistence/promotion_service.py"},"region":{"startLine":454}}}],"partialFingerprints":{"codehealthFindingId/v1":"95d47b93d71e8462c5c3fa3699351febaeb9fba89d4d70f73e416eb1edbcf9af"}},{"ruleId":"D1","level":"warning","message":{"text":"semantic_task_receipts._compact_run (cyclomatic 17): semantic_task_receipts._compact_run has cyclomatic complexity 17 (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":"core_memory/persistence/semantic_task_receipts.py"},"region":{"startLine":161}}}],"partialFingerprints":{"codehealthFindingId/v1":"eab55589d9c2df550a5d5f142b18caf2f3c76d280595de1c63e14f251f7a5b90"}},{"ruleId":"D1","level":"warning","message":{"text":"store_failure_ops.find_failure_signature_matches_for_store (cyclomatic 17): store_failure_ops.find_failure_signature_matches_for_store 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":"core_memory/persistence/store_failure_ops.py"},"region":{"startLine":16}}}],"partialFingerprints":{"codehealthFindingId/v1":"014466c33ec098a156aaeb8130c859fb343506f7894163d065d50b865fb71a6b"}},{"ruleId":"D1","level":"warning","message":{"text":"store_management_ops._split_source_selector (cyclomatic 17): store_management_ops._split_source_selector 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":"core_memory/persistence/store_management_ops.py"},"region":{"startLine":75}}}],"partialFingerprints":{"codehealthFindingId/v1":"a53e8ec008a26cbb0e8c62e9cde3755fa67f5ea0cd13b6272cc1720d92f4ac57"}},{"ruleId":"D1","level":"warning","message":{"text":"store_query.query_for_store (cyclomatic 17): store_query.query_for_store 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":"core_memory/persistence/store_query.py"},"region":{"startLine":8}}}],"partialFingerprints":{"codehealthFindingId/v1":"fcc8055a1c3ed832b03173794b69764ab51ae4682dde29f7d8866d265782b161"}},{"ruleId":"D1","level":"warning","message":{"text":"store_validation_helpers.normalize_links (cyclomatic 17): store_validation_helpers.normalize_links 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":"core_memory/persistence/store_validation_helpers.py"},"region":{"startLine":6}}}],"partialFingerprints":{"codehealthFindingId/v1":"0b9307457b81966e43d606a2a2bb5951164722638ab91750722bc219d32dc757"}},{"ruleId":"D1","level":"warning","message":{"text":"ProviderSemanticTaskRuntime.run (cyclomatic 17): ProviderSemanticTaskRuntime.run has cyclomatic complexity 17 (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":"core_memory/policy/semantic_task_runtime.py"},"region":{"startLine":254}}}],"partialFingerprints":{"codehealthFindingId/v1":"fb88aff0e7fe7c15e5c8cd8a33e4de83410a941a0e827ec8e0966d9e954608f2"}},{"ruleId":"D1","level":"warning","message":{"text":"turn_memory_authoring._value_at_path (cyclomatic 17): turn_memory_authoring._value_at_path 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":"core_memory/policy/turn_memory_authoring.py"},"region":{"startLine":215}}}],"partialFingerprints":{"codehealthFindingId/v1":"8fae8015cec67304ef375b281e19352c1ff815a5e570464b844543fd7d3a250d"}},{"ruleId":"D1","level":"warning","message":{"text":"pipeline._append_structural_chains (cyclomatic 17): pipeline._append_structural_chains 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":"core_memory/retrieval/pipeline/__init__.py"},"region":{"startLine":80}}}],"partialFingerprints":{"codehealthFindingId/v1":"68b73ec5c4d072256b38cfb30d678668828c64344a74bb0fea63e411edaee080"}},{"ruleId":"D1","level":"warning","message":{"text":"query_norm.resolve_query_anchors (cyclomatic 17): query_norm.resolve_query_anchors 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":"core_memory/retrieval/query_norm.py"},"region":{"startLine":106}}}],"partialFingerprints":{"codehealthFindingId/v1":"c252f257a7c442aa74df9cd0c8daf8ce530348aa98568832f9c99250fc22abba"}},{"ruleId":"D1","level":"warning","message":{"text":"memory_reason._select_diverse_chains (cyclomatic 17): memory_reason._select_diverse_chains 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":"core_memory/retrieval/tools/memory_reason.py"},"region":{"startLine":209}}}],"partialFingerprints":{"codehealthFindingId/v1":"bdd5c949f4e97cac53a4f7806b1f0c19a5dbe1f7987ef600655811f28ab4662d"}},{"ruleId":"D1","level":"warning","message":{"text":"memory_reason._plan_changed (cyclomatic 17): memory_reason._plan_changed 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":"core_memory/retrieval/tools/memory_reason.py"},"region":{"startLine":676}}}],"partialFingerprints":{"codehealthFindingId/v1":"362f9bf70152dba17a74eb28b9eceb27b61a10d361e046ca3fbfe6b04b9108df"}},{"ruleId":"D1","level":"warning","message":{"text":"longitudinal.longitudinal_benchmark_v2 (cyclomatic 17): longitudinal.longitudinal_benchmark_v2 has cyclomatic complexity 17 (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":"core_memory/runtime/dreamer/longitudinal.py"},"region":{"startLine":178}}}],"partialFingerprints":{"codehealthFindingId/v1":"c9d8a386d72bf4361e1231c4fa7b1e1f397670a2daa5e47d79f62d2e28ecfc6c"}},{"ruleId":"D1","level":"warning","message":{"text":"flush_state.upsert_process_flush_checkpoint_bead (cyclomatic 17): flush_state.upsert_process_flush_checkpoint_bead has cyclomatic complexity 17 (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":"core_memory/runtime/flush/flush_state.py"},"region":{"startLine":34}}}],"partialFingerprints":{"codehealthFindingId/v1":"3aa4662100c3884dc3ff0e8b797f7b08d25a90bb3307041c18136e1354d7c434"}},{"ruleId":"D1","level":"warning","message":{"text":"progress.process_goal_progress_event (cyclomatic 17): progress.process_goal_progress_event has cyclomatic complexity 17 (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":"core_memory/runtime/goals/progress.py"},"region":{"startLine":804}}}],"partialFingerprints":{"codehealthFindingId/v1":"2bba4dbb794486d2b8609106a1c6530704fc6ecebcb931a913b23d869b33d44c"}},{"ruleId":"D1","level":"warning","message":{"text":"source_envelope.normalize_source_ingest_envelope (cyclomatic 17): source_envelope.normalize_source_ingest_envelope has cyclomatic complexity 17 (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":"core_memory/runtime/ingest/source_envelope.py"},"region":{"startLine":111}}}],"partialFingerprints":{"codehealthFindingId/v1":"e82cdfbecd920f6f4257e12170150955d3ecd2ced1f87bb05f09d556b6b04d80"}},{"ruleId":"D1","level":"warning","message":{"text":"side_effect_queue.side_effect_queue_status (cyclomatic 17): side_effect_queue.side_effect_queue_status 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":"core_memory/runtime/queue/side_effect_queue.py"},"region":{"startLine":67}}}],"partialFingerprints":{"codehealthFindingId/v1":"665de06aa6c8a4598d9e70ecd9f8c9c387d20a3e28e29961b59ba857c803aacf"}},{"ruleId":"D1","level":"warning","message":{"text":"TurnEnvelope.finalize_hashes (cyclomatic 17): TurnEnvelope.finalize_hashes 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":"core_memory/runtime/state.py"},"region":{"startLine":79}}}],"partialFingerprints":{"codehealthFindingId/v1":"48faae569296c77652ea28031917fa26e14bbcbea239b309f8c44e797d615982"}},{"ruleId":"D1","level":"warning","message":{"text":"promotion._normalize_links (cyclomatic 17): promotion._normalize_links 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":"core_memory/schema/promotion.py"},"region":{"startLine":53}}}],"partialFingerprints":{"codehealthFindingId/v1":"1a134ab88a08643f4ec24ea52adcf1d825a227f7c2b3be0f63c12ee306684b36"}},{"ruleId":"D1","level":"warning","message":{"text":"dreamer_bridge._maybe_auto_endorse_goal (cyclomatic 17): dreamer_bridge._maybe_auto_endorse_goal has cyclomatic complexity 17 (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":"core_memory/soul/dreamer_bridge.py"},"region":{"startLine":277}}}],"partialFingerprints":{"codehealthFindingId/v1":"6bf6cbe222b1a37841332e2dc356d5df4195f9d529f1d96959a235268f2ba9e1"}},{"ruleId":"D1","level":"warning","message":{"text":"store.apply_soul_update (cyclomatic 17): store.apply_soul_update has cyclomatic complexity 17 (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":"core_memory/soul/store.py"},"region":{"startLine":306}}}],"partialFingerprints":{"codehealthFindingId/v1":"d9e40c25e276d384d43f4fd949404d7cff6b7117371084d1e68890e2b9f63fd2"}},{"ruleId":"D1","level":"warning","message":{"text":"transcript_ingest._associations_created_summary (cyclomatic 17): transcript_ingest._associations_created_summary 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":"core_memory/transcript_ingest.py"},"region":{"startLine":429}}}],"partialFingerprints":{"codehealthFindingId/v1":"730fd90ace8b52a95d543eb48769bb75cbd40a9ba75c8f9f580cbdb36673d0a1"}},{"ruleId":"D1","level":"warning","message":{"text":"transcript_ingest.ingest_transcript (cyclomatic 17): transcript_ingest.ingest_transcript has cyclomatic complexity 17 (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":"core_memory/transcript_ingest.py"},"region":{"startLine":545}}}],"partialFingerprints":{"codehealthFindingId/v1":"81e8b947da909ff4c6699834571f620c1b76a6ab34200666a98a9c1a57eeb16c"}},{"ruleId":"D1","level":"warning","message":{"text":"rolling_window._select_beads_for_budget (cyclomatic 17): rolling_window._select_beads_for_budget 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":"core_memory/write_pipeline/rolling_window.py"},"region":{"startLine":188}}}],"partialFingerprints":{"codehealthFindingId/v1":"6f27d418faadcb8a00eddd453a3767525c1a34029719b866b557ef2710b56a44"}},{"ruleId":"D1","level":"warning","message":{"text":"paraphrase_eval._anchor_hit (cyclomatic 17): paraphrase_eval._anchor_hit has cyclomatic complexity 17 (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":"eval/paraphrase_eval.py"},"region":{"startLine":36}}}],"partialFingerprints":{"codehealthFindingId/v1":"b17cd38462ef12c0f832562fc19f234ea760fbd3b91bcae03ce2164fd9b396e9"}},{"ruleId":"D1","level":"warning","message":{"text":"preview.compute_preview_association_candidates (cyclomatic 16): preview.compute_preview_association_candidates 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":"core_memory/association/preview.py"},"region":{"startLine":138}}}],"partialFingerprints":{"codehealthFindingId/v1":"e9e1e79d7494ba4c90e916f430b2c22f88647e61ffaa4c16b824eb19b0350b6c"}},{"ruleId":"D1","level":"warning","message":{"text":"extraction.extract_claims (cyclomatic 16): extraction.extract_claims 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":"core_memory/claim/extraction.py"},"region":{"startLine":248}}}],"partialFingerprints":{"codehealthFindingId/v1":"81ad8903d9be1aeea750c5d6edc3e2e5c54a4c0d773c3c2df5b588e7d3e0ffbb"}},{"ruleId":"D1","level":"warning","message":{"text":"semantic.handle_semantic_command (cyclomatic 16): semantic.handle_semantic_command 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":"core_memory/cli/handlers/semantic.py"},"region":{"startLine":46}}}],"partialFingerprints":{"codehealthFindingId/v1":"003d03acb121750594bf76789ddd9c212449f094f81ef36ab9ba5d6b6b8fe64a"}},{"ruleId":"D1","level":"warning","message":{"text":"core._normalize_links (cyclomatic 16): core._normalize_links 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":"core_memory/graph/core.py"},"region":{"startLine":141}}}],"partialFingerprints":{"codehealthFindingId/v1":"790f3efcbc3d5b97f5a2905db095a82d4b2705b77942730ca8c79fe83c6af0a7"}},{"ruleId":"D1","level":"warning","message":{"text":"root_cause._upstream_edges (cyclomatic 16): root_cause._upstream_edges 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":"core_memory/graph/root_cause.py"},"region":{"startLine":305}}}],"partialFingerprints":{"codehealthFindingId/v1":"963665c22eb659c723bdc553eab154d1096473fdfe574a6ce9d092a9ff1da184"}},{"ruleId":"D1","level":"warning","message":{"text":"root_cause._edge_cost (cyclomatic 16): root_cause._edge_cost 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":"core_memory/graph/root_cause.py"},"region":{"startLine":389}}}],"partialFingerprints":{"codehealthFindingId/v1":"9a37c86b8e0159aaf0552ab061e21d9c0475718af194c4f90044c1069ca77f73"}},{"ruleId":"D1","level":"warning","message":{"text":"root_cause._rank_influence (cyclomatic 16): root_cause._rank_influence 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":"core_memory/graph/root_cause.py"},"region":{"startLine":741}}}],"partialFingerprints":{"codehealthFindingId/v1":"9c11992ce758ab1b31c5f6a34b9fe5ee637e4790fc9cc6c4fc427c3fe9a6028a"}},{"ruleId":"D1","level":"warning","message":{"text":"ingest_discord._parse_message (cyclomatic 16): ingest_discord._parse_message has cyclomatic complexity 16 (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":"core_memory/integrations/mcp/tools/ingest_discord.py"},"region":{"startLine":25}}}],"partialFingerprints":{"codehealthFindingId/v1":"2064c40f1960932b78ea66845ea8e75dcfa82ad06b3c2d7a9225b23a9dc90228"}},{"ruleId":"D1","level":"warning","message":{"text":"status.status_handler (cyclomatic 16): status.status_handler has cyclomatic complexity 16 (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":"core_memory/integrations/mcp/tools/status.py"},"region":{"startLine":40}}}],"partialFingerprints":{"codehealthFindingId/v1":"4b9938d1aa15bee286307958bc97362b7c96f7d7a95b518761602b14a8efc4ae"}},{"ruleId":"D1","level":"warning","message":{"text":"mapper.association_to_edge (cyclomatic 16): mapper.association_to_edge has cyclomatic complexity 16 (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":"core_memory/integrations/neo4j/mapper.py"},"region":{"startLine":69}}}],"partialFingerprints":{"codehealthFindingId/v1":"493da89f6b77f94b414d772712c4e46d964181ef0984ae9448282badf262fe87"}},{"ruleId":"D1","level":"warning","message":{"text":"entity_merge_flow._entity_similarity (cyclomatic 16): entity_merge_flow._entity_similarity has cyclomatic complexity 16 (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":"core_memory/persistence/entity_merge_flow.py"},"region":{"startLine":24}}}],"partialFingerprints":{"codehealthFindingId/v1":"604adedabf393bc5aca4399111b0eda47cd007ddbf056428cc062b7c7070a8aa"}},{"ruleId":"D1","level":"warning","message":{"text":"semantic_task_receipts.summarize_semantic_task_runs (cyclomatic 16): semantic_task_receipts.summarize_semantic_task_runs 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":"core_memory/persistence/semantic_task_receipts.py"},"region":{"startLine":204}}}],"partialFingerprints":{"codehealthFindingId/v1":"19cfd41d11535877ca1adb7f658e3c49df005dadda08f5f406e336ee73372b30"}},{"ruleId":"D1","level":"warning","message":{"text":"store_projection_ops.rebuild_index_projection_from_sessions_for_store (cyclomatic 16): store_projection_ops.rebuild_index_projection_from_sessions_for_store 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":"core_memory/persistence/store_projection_ops.py"},"region":{"startLine":11}}}],"partialFingerprints":{"codehealthFindingId/v1":"d1283c8d2512aae5bf967e616b37ff436ed49c16666971e93a6b120f3acdbc8e"}},{"ruleId":"D1","level":"warning","message":{"text":"causal_recall._fallback_execute_decision (cyclomatic 16): causal_recall._fallback_execute_decision has cyclomatic complexity 16 (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":"core_memory/retrieval/causal_recall.py"},"region":{"startLine":322}}}],"partialFingerprints":{"codehealthFindingId/v1":"5890c568eb96fd5ae245daa390711861c3476a3fd4cdad4667164cd9ea154aa7"}},{"ruleId":"D1","level":"warning","message":{"text":"causal_recall.causal_edge_pressure (cyclomatic 16): causal_recall.causal_edge_pressure 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":"core_memory/retrieval/causal_recall.py"},"region":{"startLine":477}}}],"partialFingerprints":{"codehealthFindingId/v1":"d8a7d1946503a1412d71560eba081d25ef310298645eff9c2aba19301cedfdc3"}},{"ruleId":"D1","level":"warning","message":{"text":"roadmap_planner._goal_advancing_terminals (cyclomatic 16): roadmap_planner._goal_advancing_terminals 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":"core_memory/retrieval/roadmap_planner.py"},"region":{"startLine":110}}}],"partialFingerprints":{"codehealthFindingId/v1":"71ab5c11284efd32fcad95bec2e908e2b9b1329366a6be9a1c2baf8ee7965fe5"}},{"ruleId":"D1","level":"warning","message":{"text":"roadmap_planner._states_for_alternative (cyclomatic 16): roadmap_planner._states_for_alternative 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":"core_memory/retrieval/roadmap_planner.py"},"region":{"startLine":306}}}],"partialFingerprints":{"codehealthFindingId/v1":"1150e1ea29b998fac2463641d73fa9592011f843634a7090d3bdd7797b2848e1"}},{"ruleId":"D1","level":"warning","message":{"text":"roadmap_planner._shortest_stitched_path (cyclomatic 16): roadmap_planner._shortest_stitched_path 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":"core_memory/retrieval/roadmap_planner.py"},"region":{"startLine":441}}}],"partialFingerprints":{"codehealthFindingId/v1":"dba884d92c05a2da32170e0f1d558d6fc9230f0fe694ab06f743eb46f898a718"}},{"ruleId":"D1","level":"warning","message":{"text":"memory_reason._collect_citations_from_chains (cyclomatic 16): memory_reason._collect_citations_from_chains has cyclomatic complexity 16 (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":"core_memory/retrieval/tools/memory_reason.py"},"region":{"startLine":342}}}],"partialFingerprints":{"codehealthFindingId/v1":"9c676920bbd83f054e8fd1012d82a19edd0fc7db97edac5af5e3db1fbd3ab428"}},{"ruleId":"D1","level":"warning","message":{"text":"memory_reason._retrieve_ranked (cyclomatic 16): memory_reason._retrieve_ranked 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":"core_memory/retrieval/tools/memory_reason.py"},"region":{"startLine":476}}}],"partialFingerprints":{"codehealthFindingId/v1":"9a2922e044174d6f19a7980d394e7ce474161a7e3160889fe7191ebbaaca8ebe"}},{"ruleId":"D1","level":"warning","message":{"text":"visible_corpus.build_visible_corpus (cyclomatic 16): visible_corpus.build_visible_corpus 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":"core_memory/retrieval/visible_corpus.py"},"region":{"startLine":64}}}],"partialFingerprints":{"codehealthFindingId/v1":"e8b17ffdcc47365a6dfebdb635bc8636f4758107e452376edb6508e397456e8b"}},{"ruleId":"D1","level":"warning","message":{"text":"coverage.association_judge_readiness (cyclomatic 16): coverage.association_judge_readiness 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":"core_memory/runtime/associations/coverage.py"},"region":{"startLine":1525}}}],"partialFingerprints":{"codehealthFindingId/v1":"f954003874e76601dc269a7985a7323b79868b8b34f3f415313d93be9ad358c8"}},{"ruleId":"D1","level":"warning","message":{"text":"analysis.score_association (cyclomatic 16): analysis.score_association 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":"core_memory/runtime/dreamer/analysis.py"},"region":{"startLine":297}}}],"partialFingerprints":{"codehealthFindingId/v1":"56236657eb8dfeb4d300d966a9e90b9c13ab4133656ffeb13ceff5ec3b9664b7"}},{"ruleId":"D1","level":"warning","message":{"text":"goal_decay.detect_goal_decay (cyclomatic 16): goal_decay.detect_goal_decay 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":"core_memory/runtime/dreamer/goal_decay.py"},"region":{"startLine":72}}}],"partialFingerprints":{"codehealthFindingId/v1":"05fed5d137bff30e9c362b8abc90058fbd91903c237d6646027fc719da16083d"}},{"ruleId":"D1","level":"warning","message":{"text":"source_envelope._infer_boundary_type (cyclomatic 16): source_envelope._infer_boundary_type has cyclomatic complexity 16 (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":"core_memory/runtime/ingest/source_envelope.py"},"region":{"startLine":65}}}],"partialFingerprints":{"codehealthFindingId/v1":"75ed33c58744949e51ff1a471f0b5d38d9493701cb161024f86347334de0de4e"}},{"ruleId":"D1","level":"warning","message":{"text":"source_events.ingest_source_event (cyclomatic 16): source_events.ingest_source_event 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":"core_memory/runtime/ingest/source_events.py"},"region":{"startLine":79}}}],"partialFingerprints":{"codehealthFindingId/v1":"ff4957c76b00765e5736cb49fbd7d0c68ba9b6e5c4eb149b9917c3f6722340ab"}},{"ruleId":"D1","level":"warning","message":{"text":"session_enrichment_delta.write_delta_quarantine (cyclomatic 16): session_enrichment_delta.write_delta_quarantine 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":"core_memory/runtime/session/session_enrichment_delta.py"},"region":{"startLine":333}}}],"partialFingerprints":{"codehealthFindingId/v1":"d680ecd3287c49d483211d3b89f89736f837d1c5cf30dc9741aa955104b47596"}},{"ruleId":"D1","level":"warning","message":{"text":"session_start_flow.process_session_start_impl (cyclomatic 16): session_start_flow.process_session_start_impl has cyclomatic complexity 16 (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":"core_memory/runtime/session/session_start_flow.py"},"region":{"startLine":114}}}],"partialFingerprints":{"codehealthFindingId/v1":"215152e578e2ca19278fb0937f432f6608b9060e6e28143f8f55981e6bf17d7b"}},{"ruleId":"D1","level":"warning","message":{"text":"ingress._normalize_mesh_trace (cyclomatic 16): ingress._normalize_mesh_trace has cyclomatic complexity 16 (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":"core_memory/runtime/turn/ingress.py"},"region":{"startLine":53}}}],"partialFingerprints":{"codehealthFindingId/v1":"d6c2dff840b470441bb6c349244773d69ba1e42969ffaa0c17cd5aca3c53e747"}},{"ruleId":"D1","level":"warning","message":{"text":"receipt._queue_receipt (cyclomatic 16): receipt._queue_receipt has cyclomatic complexity 16 (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":"core_memory/runtime/turn/receipt.py"},"region":{"startLine":76}}}],"partialFingerprints":{"codehealthFindingId/v1":"a9f2449720a62a8716dce2a3766ae40a22b37496e0d9de6861dc902026b9cfc4"}},{"ruleId":"D1","level":"warning","message":{"text":"promotion.get_recommendation_rows (cyclomatic 16): promotion.get_recommendation_rows 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":"core_memory/schema/promotion.py"},"region":{"startLine":218}}}],"partialFingerprints":{"codehealthFindingId/v1":"6f8c5c04535b3829bdfef834d808296b4dc83fe17d903e0b03accc1623a341c2"}},{"ruleId":"D1","level":"warning","message":{"text":"dreamer_bridge.dreamer_soul_review (cyclomatic 16): dreamer_bridge.dreamer_soul_review has cyclomatic complexity 16 (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":"core_memory/soul/dreamer_bridge.py"},"region":{"startLine":768}}}],"partialFingerprints":{"codehealthFindingId/v1":"dd3b964f92cbd3fef0a550e4386e65a36fc839f7bf0d5a8b12858fd5598be4b7"}},{"ruleId":"D1","level":"warning","message":{"text":"check_architecture_guards.check_cleanup_truth (cyclomatic 16): check_architecture_guards.check_cleanup_truth 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/check_architecture_guards.py"},"region":{"startLine":580}}}],"partialFingerprints":{"codehealthFindingId/v1":"9f3e6953525a807e884290fb232116d68e8d33ba56db23e7b0cfa92469877018"}},{"ruleId":"D2","level":"warning","message":{"text":"candidates.decide_dreamer_candidate (cognitive 359): candidates.decide_dreamer_candidate has cognitive complexity 359 (threshold 15). Drivers by points: if/else 49 (139 pts), boolean chains 127, ternaries 19 (64 pts), error handling 5 (17 pts), loops 4 (12 pts) (nesting depth added 155). 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":"core_memory/runtime/dreamer/candidates.py"},"region":{"startLine":334}}}],"partialFingerprints":{"codehealthFindingId/v1":"03c85be56d0a89eb912b629ad5dbab7afbf0105decbe18c093ac3b12cfe5ad86"}},{"ruleId":"D2","level":"warning","message":{"text":"management.maintain (cognitive 186): management.maintain has cognitive complexity 186 (threshold 15). Drivers by points: boolean chains 118, if/else 56 (68 pts) (nesting depth added 12). 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":"core_memory/management/__init__.py"},"region":{"startLine":829}}}],"partialFingerprints":{"codehealthFindingId/v1":"0414b06d3403987ecc2a59916f348dde347a66e44d51a09d8210abc375364e69"}},{"ruleId":"D2","level":"warning","message":{"text":"canonical.search_request (cognitive 180): canonical.search_request has cognitive complexity 180 (threshold 15). Drivers by points: boolean chains 92, if/else 34 (58 pts), ternaries 11 (14 pts), loops 8 (13 pts), error handling 3 (nesting depth added 32). 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":"core_memory/retrieval/pipeline/canonical.py"},"region":{"startLine":891}}}],"partialFingerprints":{"codehealthFindingId/v1":"276c5a2e546577afc42054e5400549b89bb2a425e63c5897bf9b73b2b9f9febb"}},{"ruleId":"D2","level":"warning","message":{"text":"canonical.trace_request (cognitive 162): canonical.trace_request has cognitive complexity 162 (threshold 15). Drivers by points: if/else 34 (62 pts), boolean chains 61, ternaries 15 (16 pts), loops 6 (14 pts), error handling 5 (9 pts) (nesting depth added 41). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"core_memory/retrieval/pipeline/canonical.py"},"region":{"startLine":1180}}}],"partialFingerprints":{"codehealthFindingId/v1":"7601dd3e5195373618d951766f0480eaa6be5d6d3b70feec45f9788b5ca53b1d"}},{"ruleId":"D2","level":"warning","message":{"text":"crawler_contract.apply_crawler_updates (cognitive 159): crawler_contract.apply_crawler_updates has cognitive complexity 159 (threshold 15). Drivers by points: if/else 36 (79 pts), boolean chains 63, loops 7 (9 pts), ternaries 2 (5 pts), error handling 1 (3 pts) (nesting depth added 50). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"core_memory/association/crawler_contract.py"},"region":{"startLine":767}}}],"partialFingerprints":{"codehealthFindingId/v1":"fa191bf00cad2466458f3d7f415535ac4753e53bb8a2e3ee726e21d1d71ae679"}},{"ruleId":"D2","level":"warning","message":{"text":"side_effect_queue.process_side_effect_event (cognitive 155): side_effect_queue.process_side_effect_event has cognitive complexity 155 (threshold 15). Drivers by points: if/else 32 (56 pts), boolean chains 48, error handling 15 (31 pts), ternaries 9 (18 pts), loops 1 (2 pts) (nesting depth added 50). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"core_memory/runtime/queue/side_effect_queue.py"},"region":{"startLine":117}}}],"partialFingerprints":{"codehealthFindingId/v1":"6554386ae0134e1dc561402b1aa8062c19f565cadc3fa2ea0ce7f043ef2a3b50"}},{"ruleId":"D2","level":"warning","message":{"text":"crawler_contract.merge_crawler_updates (cognitive 151): crawler_contract.merge_crawler_updates has cognitive complexity 151 (threshold 15). Drivers by points: if/else 29 (83 pts), boolean chains 51, error handling 2 (7 pts), ternaries 2 (6 pts), loops 4 (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":"core_memory/association/crawler_contract.py"},"region":{"startLine":435}}}],"partialFingerprints":{"codehealthFindingId/v1":"74af03dd9ffcf360f033088692fa3d55012f8d2047c0ba672fe8bfb2ee5b02fb"}},{"ruleId":"D2","level":"warning","message":{"text":"store_validation_helpers.required_field_issues_for_store (cognitive 148): store_validation_helpers.required_field_issues_for_store has cognitive complexity 148 (threshold 15). Drivers by points: if/else 48 (86 pts), boolean chains 60, loops 1 (2 pts) (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":"core_memory/persistence/store_validation_helpers.py"},"region":{"startLine":42}}}],"partialFingerprints":{"codehealthFindingId/v1":"1b898b1aa30c29e1f5b8a69a6fe219bb7dfa1bf34b58f9406316cd2e17d43b1f"}},{"ruleId":"D2","level":"warning","message":{"text":"memory_reason.memory_reason (cognitive 148): memory_reason.memory_reason has cognitive complexity 148 (threshold 15). Drivers by points: boolean chains 67, if/else 27 (51 pts), ternaries 10 (19 pts), loops 4 (8 pts), error handling 1 (3 pts) (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":"core_memory/retrieval/tools/memory_reason.py"},"region":{"startLine":762}}}],"partialFingerprints":{"codehealthFindingId/v1":"73238ad8bed4f9e113db857174ac5ad3fca47094a0911dc31a1c58a1ba3a84fb"}},{"ruleId":"D2","level":"warning","message":{"text":"turn_flow.process_turn_finalized_impl (cognitive 141): turn_flow.process_turn_finalized_impl has cognitive complexity 141 (threshold 15). Drivers by points: if/else 35 (68 pts), boolean chains 58, error handling 3 (7 pts), ternaries 2 (5 pts), loops 1 (3 pts) (nesting depth added 42). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"core_memory/runtime/turn/turn_flow.py"},"region":{"startLine":29}}}],"partialFingerprints":{"codehealthFindingId/v1":"a0a85aa2ff335b7adfc668deacdfd5b429a4c397b5e2f2f35c305ac053593c63"}},{"ruleId":"D2","level":"warning","message":{"text":"semantic_index.semantic_lookup (cognitive 129): semantic_index.semantic_lookup has cognitive complexity 129 (threshold 15). Drivers by points: if/else 35 (65 pts), boolean chains 48, error handling 3 (6 pts), ternaries 2 (6 pts), loops 2 (4 pts) (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":"core_memory/retrieval/semantic_index.py"},"region":{"startLine":1546}}}],"partialFingerprints":{"codehealthFindingId/v1":"a4c1c72bd9b8705b713e5edb24c9a013c8507f69a46f99535e9a105a16eb1e46"}},{"ruleId":"D2","level":"warning","message":{"text":"canonical.execute_request (cognitive 126): canonical.execute_request has cognitive complexity 126 (threshold 15). Drivers by points: boolean chains 85, if/else 19 (33 pts), ternaries 3 (6 pts), error handling 1 (2 pts) (nesting depth added 18). 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":"core_memory/retrieval/pipeline/canonical.py"},"region":{"startLine":1444}}}],"partialFingerprints":{"codehealthFindingId/v1":"3c0a30f6ae5fd44cef6c2ea52dbd074403c0331e8d52424ac9e6d019fa5cb6d5"}},{"ruleId":"D2","level":"warning","message":{"text":"management._validate_action (cognitive 122): management._validate_action has cognitive complexity 122 (threshold 15). Drivers by points: if/else 41 (78 pts), boolean chains 44 (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":"core_memory/management/__init__.py"},"region":{"startLine":396}}}],"partialFingerprints":{"codehealthFindingId/v1":"3020c4cd6fc5c0088ec1de3201f3e7abbafc95513c91b99c08b06eaf8686ecd4"}},{"ruleId":"D2","level":"warning","message":{"text":"agent_authored_contract.validate_agent_authored_updates (cognitive 115): agent_authored_contract.validate_agent_authored_updates has cognitive complexity 115 (threshold 15). Drivers by points: if/else 35 (78 pts), boolean chains 17, ternaries 6 (16 pts), loops 3 (4 pts) (nesting depth added 54). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"core_memory/runtime/passes/agent_authored_contract.py"},"region":{"startLine":93}}}],"partialFingerprints":{"codehealthFindingId/v1":"6ae1055d518cf7dc39eb53a1beb95d997e5f92c2d63d03a0ab6f77068e5141c8"}},{"ruleId":"D2","level":"warning","message":{"text":"candidates.enqueue_dreamer_candidates (cognitive 109): candidates.enqueue_dreamer_candidates has cognitive complexity 109 (threshold 15). Drivers by points: boolean chains 52, if/else 17 (41 pts), ternaries 5 (9 pts), loops 3 (6 pts), error handling 1 (nesting depth added 31). 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":"core_memory/runtime/dreamer/candidates.py"},"region":{"startLine":93}}}],"partialFingerprints":{"codehealthFindingId/v1":"520d75b4275c6366a38422778048e8a8938d47a24d880b07f052facf62fb9f90"}},{"ruleId":"D2","level":"warning","message":{"text":"enrichment.run_turn_enrichment (cognitive 109): enrichment.run_turn_enrichment has cognitive complexity 109 (threshold 15). Drivers by points: boolean chains 57, if/else 19 (31 pts), error handling 12 (17 pts), ternaries 2 (4 pts) (nesting depth added 19). 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":"core_memory/runtime/passes/enrichment.py"},"region":{"startLine":115}}}],"partialFingerprints":{"codehealthFindingId/v1":"50cb4df36c53f226aa6308dd49ad455bf48f1829144e79410ec634b3de55973d"}},{"ruleId":"D2","level":"warning","message":{"text":"search.search_typed (cognitive 107): search.search_typed has cognitive complexity 107 (threshold 15). Drivers by points: boolean chains 57, if/else 24 (44 pts), loops 3 (4 pts), ternaries 1 (2 pts) (nesting depth added 22). 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":"core_memory/retrieval/pipeline/search.py"},"region":{"startLine":36}}}],"partialFingerprints":{"codehealthFindingId/v1":"2b64684ca6e344198383c37fc5ee4d727e12282805db78ce87cd491f261d6125"}},{"ruleId":"D2","level":"warning","message":{"text":"flush_flow.process_flush_impl (cognitive 106): flush_flow.process_flush_impl has cognitive complexity 106 (threshold 15). Drivers by points: boolean chains 84, if/else 8 (12 pts), error handling 4 (6 pts), ternaries 4 (nesting depth added 6). 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":"core_memory/runtime/flush/flush_flow.py"},"region":{"startLine":29}}}],"partialFingerprints":{"codehealthFindingId/v1":"75d70e372e6ea06663d9f50a91a1c10495d7fe7e9735dead8d240a0b22431ec6"}},{"ruleId":"D2","level":"warning","message":{"text":"coverage._apply_judge_result (cognitive 101): coverage._apply_judge_result has cognitive complexity 101 (threshold 15). Drivers by points: if/else 29 (59 pts), boolean chains 32, loops 5 (10 pts) (nesting depth added 35). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"core_memory/runtime/associations/coverage.py"},"region":{"startLine":1862}}}],"partialFingerprints":{"codehealthFindingId/v1":"70e0f8254c0f4bc604e7c31294515df619d7d1f2a4fbe0d64526a0215ed3139d"}},{"ruleId":"D2","level":"warning","message":{"text":"session_enrichment_delta.crawler_updates_to_delta (cognitive 101): session_enrichment_delta.crawler_updates_to_delta has cognitive complexity 101 (threshold 15). Drivers by points: boolean chains 46, if/else 20 (37 pts), loops 10 (12 pts), ternaries 4 (6 pts) (nesting depth added 21). 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":"core_memory/runtime/session/session_enrichment_delta.py"},"region":{"startLine":422}}}],"partialFingerprints":{"codehealthFindingId/v1":"a0c8deffc135cb8d34f892dbcd4723b3a7297abd22fe70e1d43caef380fadecf"}},{"ruleId":"D2","level":"warning","message":{"text":"canonical._claim_anchors_from_state (cognitive 93): canonical._claim_anchors_from_state has cognitive complexity 93 (threshold 15). Drivers by points: if/else 18 (50 pts), boolean chains 28, loops 4 (9 pts), ternaries 2 (6 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":"core_memory/retrieval/pipeline/canonical.py"},"region":{"startLine":184}}}],"partialFingerprints":{"codehealthFindingId/v1":"3dcdac4d2133378bc44ec0ba9bd40b7c9adb9d636275b9beac1dbf945ef596a9"}},{"ruleId":"D2","level":"warning","message":{"text":"summary._build_light_cone (cognitive 93): summary._build_light_cone has cognitive complexity 93 (threshold 15). Drivers by points: boolean chains 42, if/else 19 (32 pts), loops 8 (9 pts), ternaries 5 (7 pts), error handling 3 (nesting depth added 16). 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":"core_memory/soul/summary.py"},"region":{"startLine":603}}}],"partialFingerprints":{"codehealthFindingId/v1":"4fc829011c7b5a554513cd8d0a39d9f503ad992e994d249f412ab6e7f66d12c4"}},{"ruleId":"D2","level":"warning","message":{"text":"dreamer_bridge.propose_soul_from_dreamer (cognitive 90): dreamer_bridge.propose_soul_from_dreamer has cognitive complexity 90 (threshold 15). Drivers by points: boolean chains 39, if/else 17 (35 pts), ternaries 10 (14 pts), loops 2 (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":"core_memory/soul/dreamer_bridge.py"},"region":{"startLine":536}}}],"partialFingerprints":{"codehealthFindingId/v1":"4cacccac826d8e50235b8792131df9132cd86bb2b5c3c06d27f10624aaacea39"}},{"ruleId":"D2","level":"warning","message":{"text":"core.backfill_causal_links (cognitive 88): core.backfill_causal_links has cognitive complexity 88 (threshold 15). Drivers by points: if/else 13 (38 pts), boolean chains 31, loops 9 (15 pts), ternaries 1 (4 pts) (nesting depth added 34). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"core_memory/graph/core.py"},"region":{"startLine":257}}}],"partialFingerprints":{"codehealthFindingId/v1":"9d4131d07bb54e3b0ee8b2bcda695fcfb549180d673daedd86d20adf4bb4c2d5"}},{"ruleId":"D2","level":"warning","message":{"text":"hybrid.hybrid_lookup (cognitive 88): hybrid.hybrid_lookup has cognitive complexity 88 (threshold 15). Drivers by points: boolean chains 39, if/else 16 (33 pts), loops 6 (9 pts), ternaries 3 (5 pts), error handling 1 (2 pts) (nesting depth added 23). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"core_memory/retrieval/hybrid.py"},"region":{"startLine":101}}}],"partialFingerprints":{"codehealthFindingId/v1":"b09985d2c9320e4942b2526c5dfd82eb224ab47cff6bba39b90866902d0e0dcf"}},{"ruleId":"D2","level":"warning","message":{"text":"roadmap.roadmap_watershed_attribution (cognitive 84): roadmap.roadmap_watershed_attribution has cognitive complexity 84 (threshold 15). Drivers by points: if/else 20 (45 pts), boolean chains 23, loops 9 (13 pts), ternaries 2 (3 pts) (nesting depth added 30). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"core_memory/graph/roadmap.py"},"region":{"startLine":486}}}],"partialFingerprints":{"codehealthFindingId/v1":"b9647c0e59f69adb23596c03a17186a96a5e7f956268279a97ca7be11a505667"}},{"ruleId":"D2","level":"warning","message":{"text":"transcript_ingest.normalize_transcript_payload (cognitive 83): transcript_ingest.normalize_transcript_payload has cognitive complexity 83 (threshold 15). Drivers by points: boolean chains 39, if/else 15 (24 pts), ternaries 5 (11 pts), loops 5 (9 pts) (nesting depth added 19). 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":"core_memory/transcript_ingest.py"},"region":{"startLine":192}}}],"partialFingerprints":{"codehealthFindingId/v1":"3f11b3a3ca44f7b3ac4de4434cff27e3f582eb0cc3f2b0d3ab9096acfca3a951"}},{"ruleId":"D2","level":"warning","message":{"text":"canonical._apply_typed_filters (cognitive 82): canonical._apply_typed_filters has cognitive complexity 82 (threshold 15). Drivers by points: if/else 21 (43 pts), boolean chains 38, loops 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":"core_memory/retrieval/pipeline/canonical.py"},"region":{"startLine":699}}}],"partialFingerprints":{"codehealthFindingId/v1":"331113468c16c82a90e3d3a25529ec5a2645e5bddc7f33be796012eeaedf7d4d"}},{"ruleId":"D2","level":"warning","message":{"text":"sync_transcript_snapshot.sync_transcript_snapshot_handler (cognitive 80): sync_transcript_snapshot.sync_transcript_snapshot_handler has cognitive complexity 80 (threshold 15). Drivers by points: boolean chains 39, if/else 26 (36 pts), error handling 1 (2 pts), loops 1 (2 pts), ternaries 1 (nesting depth added 12). 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":"core_memory/integrations/mcp/tools/sync_transcript_snapshot.py"},"region":{"startLine":217}}}],"partialFingerprints":{"codehealthFindingId/v1":"1ec54b97b60d8257878e920ef58529ad08b425b86adc880cc8559351b0d0b9b4"}},{"ruleId":"D2","level":"warning","message":{"text":"agent._expand_via_association_hops (cognitive 80): agent._expand_via_association_hops has cognitive complexity 80 (threshold 15). Drivers by points: if/else 17 (38 pts), boolean chains 18, loops 10 (18 pts), ternaries 3 (5 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":"core_memory/retrieval/agent.py"},"region":{"startLine":599}}}],"partialFingerprints":{"codehealthFindingId/v1":"9eff7542fee949fff620852b536a0d2765a6fb67c60581bcaf3a08feb0c33ba9"}},{"ruleId":"D2","level":"warning","message":{"text":"memory_reason._plan_why (cognitive 80): memory_reason._plan_why has cognitive complexity 80 (threshold 15). Drivers by points: boolean chains 41, if/else 20 (30 pts), loops 3 (4 pts), ternaries 3, error handling 1 (2 pts) (nesting depth added 12). 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":"core_memory/retrieval/tools/memory_reason.py"},"region":{"startLine":525}}}],"partialFingerprints":{"codehealthFindingId/v1":"66e10f8be30ac6160a27cda1be84ed457928fdca233338000d1a3ceb0cb6cce3"}},{"ruleId":"D2","level":"warning","message":{"text":"session_enrichment_delta.canonical_session_projection (cognitive 79): session_enrichment_delta.canonical_session_projection has cognitive complexity 79 (threshold 15). Drivers by points: if/else 23 (52 pts), boolean chains 16, loops 7 (11 pts) (nesting depth added 33). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"core_memory/runtime/session/session_enrichment_delta.py"},"region":{"startLine":802}}}],"partialFingerprints":{"codehealthFindingId/v1":"1adf8ca2b81f9521d7a912acf3265ceca0e68279110bc4802de5c885caada55b"}},{"ruleId":"D2","level":"warning","message":{"text":"coverage.decide_association_candidate (cognitive 74): coverage.decide_association_candidate has cognitive complexity 74 (threshold 15). Drivers by points: if/else 23 (40 pts), boolean chains 26, ternaries 8 (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":"core_memory/runtime/associations/coverage.py"},"region":{"startLine":2925}}}],"partialFingerprints":{"codehealthFindingId/v1":"7fdd49b16666110a9789f23675da1e5a3f739e5a3f18eb8cf49e540ae9d05974"}},{"ruleId":"D2","level":"warning","message":{"text":"summary._build_tensions (cognitive 74): summary._build_tensions has cognitive complexity 74 (threshold 15). Drivers by points: boolean chains 41, if/else 9 (15 pts), loops 6 (7 pts), ternaries 4 (7 pts), error handling 4 (nesting depth added 10). 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":"core_memory/soul/summary.py"},"region":{"startLine":957}}}],"partialFingerprints":{"codehealthFindingId/v1":"e1d5f38f9541316fd3d45ff01fbfb36e430b3b015c4c83e251ed991c238d1606"}},{"ruleId":"D2","level":"warning","message":{"text":"traversal._build_adjacency (cognitive 72): traversal._build_adjacency has cognitive complexity 72 (threshold 15). Drivers by points: if/else 14 (42 pts), boolean chains 16, loops 6 (14 pts) (nesting depth added 36). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"core_memory/graph/traversal.py"},"region":{"startLine":37}}}],"partialFingerprints":{"codehealthFindingId/v1":"f35008a90fcb071831b0b4f698a44170f3f7fe79eec4c992371b21bf683875a7"}},{"ruleId":"D2","level":"warning","message":{"text":"core.sync_structural_pipeline (cognitive 69): core.sync_structural_pipeline has cognitive complexity 69 (threshold 15). Drivers by points: boolean chains 31, if/else 15 (28 pts), loops 7 (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":"core_memory/graph/core.py"},"region":{"startLine":391}}}],"partialFingerprints":{"codehealthFindingId/v1":"6d4385c9018b53cb973d7b6efa546c20d8395c9d33958ccf87a037c1202e7847"}},{"ruleId":"D2","level":"warning","message":{"text":"memory_reason._radius1_structural_fallback (cognitive 69): memory_reason._radius1_structural_fallback has cognitive complexity 69 (threshold 15). Drivers by points: if/else 13 (36 pts), boolean chains 22, loops 7 (10 pts), ternaries 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":"core_memory/retrieval/tools/memory_reason.py"},"region":{"startLine":371}}}],"partialFingerprints":{"codehealthFindingId/v1":"18afe06f26b64708c2532fb5d545da0b32942f9522c1d342037ab3e55cc7050a"}},{"ruleId":"D2","level":"warning","message":{"text":"crawler_contract._normalize_creation_rows_with_diagnostics (cognitive 67): crawler_contract._normalize_creation_rows_with_diagnostics has cognitive complexity 67 (threshold 15). Drivers by points: if/else 24 (46 pts), boolean chains 13, loops 3 (4 pts), ternaries 3 (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":"core_memory/association/crawler_contract.py"},"region":{"startLine":156}}}],"partialFingerprints":{"codehealthFindingId/v1":"b57b96da3d37ddd8defd071017463fc03868d0408cd97ce1e638f6a9b6d041d3"}},{"ruleId":"D2","level":"warning","message":{"text":"root_cause._parameterized_best_first_search (cognitive 67): root_cause._parameterized_best_first_search has cognitive complexity 67 (threshold 15). Drivers by points: if/else 20 (47 pts), boolean chains 12, loops 4 (6 pts), ternaries 1 (2 pts) (nesting depth added 30). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"core_memory/graph/root_cause.py"},"region":{"startLine":554}}}],"partialFingerprints":{"codehealthFindingId/v1":"bd033f887edb7ece13714411437b9adb8038a423c76700b5a3f52f22b933f616"}},{"ruleId":"D2","level":"warning","message":{"text":"semantic_index.build_semantic_index (cognitive 67): semantic_index.build_semantic_index has cognitive complexity 67 (threshold 15). Drivers by points: boolean chains 20, if/else 13 (20 pts), ternaries 4 (12 pts), error handling 4 (9 pts), loops 2 (6 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":"core_memory/retrieval/semantic_index.py"},"region":{"startLine":1104}}}],"partialFingerprints":{"codehealthFindingId/v1":"6f309ff3d0e35245234fd88e3546643ebb55feaca3e8b6c78f00ff43390b6a74"}},{"ruleId":"D2","level":"warning","message":{"text":"ingest.ingest_handler (cognitive 66): ingest.ingest_handler has cognitive complexity 66 (threshold 15). Drivers by points: boolean chains 26, if/else 13 (21 pts), ternaries 9 (13 pts), error handling 3 (5 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":"core_memory/integrations/mcp/tools/ingest.py"},"region":{"startLine":196}}}],"partialFingerprints":{"codehealthFindingId/v1":"1941f8e07ae8eea8983ea5ef515da56135abfbb1f75f381efc07919184fc53da"}},{"ruleId":"D2","level":"warning","message":{"text":"contracts.recall_result_from_memory_execute (cognitive 66): contracts.recall_result_from_memory_execute has cognitive complexity 66 (threshold 15). Drivers by points: boolean chains 22, ternaries 16 (21 pts), if/else 18 (20 pts), loops 2 (3 pts) (nesting depth added 8). 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":"core_memory/retrieval/contracts.py"},"region":{"startLine":306}}}],"partialFingerprints":{"codehealthFindingId/v1":"c3cb346acbb2361856d812fc214d7df5c4b26c9375f631b12f481d02ef1dffe7"}},{"ruleId":"D2","level":"warning","message":{"text":"events.rebuild_index (cognitive 65): events.rebuild_index has cognitive complexity 65 (threshold 15). Drivers by points: if/else 17 (38 pts), boolean chains 12, loops 6 (9 pts), error handling 2 (6 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":"core_memory/persistence/events.py"},"region":{"startLine":163}}}],"partialFingerprints":{"codehealthFindingId/v1":"1723fd0b5dd7923af7245f7de557d5660a8811f5c11be57cc15aed8272ee99f9"}},{"ruleId":"D2","level":"warning","message":{"text":"reauthoring._cohort_metrics (cognitive 65): reauthoring._cohort_metrics has cognitive complexity 65 (threshold 15). Drivers by points: if/else 23 (39 pts), boolean chains 22, loops 3 (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":"core_memory/runtime/turn/reauthoring.py"},"region":{"startLine":209}}}],"partialFingerprints":{"codehealthFindingId/v1":"6baeb18b41eaddf80e80400cab2e68de89edf99d98c1563634aefa57dbc7b096"}},{"ruleId":"D2","level":"warning","message":{"text":"engine.process_turn_finalized (cognitive 63): engine.process_turn_finalized has cognitive complexity 63 (threshold 15). Drivers by points: if/else 10 (31 pts), ternaries 6 (13 pts), boolean chains 9, error handling 3 (8 pts), loops 1 (2 pts) (nesting depth added 34). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"core_memory/runtime/engine.py"},"region":{"startLine":576}}}],"partialFingerprints":{"codehealthFindingId/v1":"5855c64011301a6f524c206f97d0d7283b62806f8dda33db6eb005918c16bc68"}},{"ruleId":"D2","level":"warning","message":{"text":"agent.recall (cognitive 62): agent.recall has cognitive complexity 62 (threshold 15). Drivers by points: if/else 19 (24 pts), boolean chains 15, error handling 9 (13 pts), ternaries 7 (10 pts) (nesting depth added 12). To reduce it, split the body: most of this score is breadth rather than depth \u2014 checks laid out side by side rather than stacked \u2014 so group the statements between the checks into named steps and move each step into its own function. Some of it IS depth: where a check sits inside another whose only job is to reach it, merge the two into one condition, and where an else follows a branch that already returns, drop the trailing else and let the rest of the body continue at one level."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"core_memory/retrieval/agent.py"},"region":{"startLine":817}}}],"partialFingerprints":{"codehealthFindingId/v1":"a8f97ee30b7df2d9c66a64743ecb36ef0ff4cc997d81119be3e60a3a172c0da6"}},{"ruleId":"D2","level":"warning","message":{"text":"coverage.run_association_coverage (cognitive 62): coverage.run_association_coverage has cognitive complexity 62 (threshold 15). Drivers by points: boolean chains 34, if/else 18 (20 pts), loops 4, error handling 2, ternaries 2 (nesting depth added 2). 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":"core_memory/runtime/associations/coverage.py"},"region":{"startLine":2483}}}],"partialFingerprints":{"codehealthFindingId/v1":"2fd75a156ed9436dcef622f585285695030a5c53371be050ebd081ccc48058c5"}},{"ruleId":"D2","level":"warning","message":{"text":"crawler_contract._normalize_review_rows (cognitive 61): crawler_contract._normalize_review_rows has cognitive complexity 61 (threshold 15). Drivers by points: boolean chains 37, if/else 9 (16 pts), loops 6 (8 pts) (nesting depth added 9). 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":"core_memory/association/crawler_contract.py"},"region":{"startLine":35}}}],"partialFingerprints":{"codehealthFindingId/v1":"3160ffaede8d77b58691a40fcb218127e9588ad28895f05adb1dc22ed49ceadf"}},{"ruleId":"D2","level":"warning","message":{"text":"semantic_index.apply_semantic_delta (cognitive 61): semantic_index.apply_semantic_delta has cognitive complexity 61 (threshold 15). Drivers by points: if/else 21 (30 pts), boolean chains 21, loops 4 (6 pts), 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":"core_memory/retrieval/semantic_index.py"},"region":{"startLine":1348}}}],"partialFingerprints":{"codehealthFindingId/v1":"a4fe410c1740e44bd9bd8cd03e78794e46c613223fa30deedc91eeac5ad585bf"}},{"ruleId":"D2","level":"warning","message":{"text":"health.association_pending_judge_health (cognitive 60): health.association_pending_judge_health has cognitive complexity 60 (threshold 15). Drivers by points: if/else 12 (24 pts), boolean chains 19, ternaries 6 (9 pts), error handling 2 (5 pts), loops 2 (3 pts) (nesting depth added 19). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"core_memory/association/health.py"},"region":{"startLine":29}}}],"partialFingerprints":{"codehealthFindingId/v1":"9206eb97e7f05e921ba9eb05f28ea9f7e8821f58cf87d908f4b419b61997b7a0"}},{"ruleId":"D2","level":"warning","message":{"text":"core.causal_traverse (cognitive 60): core.causal_traverse has cognitive complexity 60 (threshold 15). Drivers by points: if/else 10 (25 pts), boolean chains 17, loops 5 (10 pts), error handling 2 (4 pts), ternaries 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":"core_memory/graph/core.py"},"region":{"startLine":816}}}],"partialFingerprints":{"codehealthFindingId/v1":"9293c0f47caa9e02ef585e11a9c9fc283356aeb9e55fd383afb65b61edaf34f4"}},{"ruleId":"D2","level":"warning","message":{"text":"api.inspect_state (cognitive 60): api.inspect_state has cognitive complexity 60 (threshold 15). Drivers by points: boolean chains 47, if/else 3 (5 pts), loops 4, error handling 3, ternaries 1 (nesting depth added 2). 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":"core_memory/integrations/api.py"},"region":{"startLine":349}}}],"partialFingerprints":{"codehealthFindingId/v1":"429ee0b6db57ef0c76dfd0b23cf1c0eda64382f42588ad92314ac6275fe7f169"}},{"ruleId":"D2","level":"warning","message":{"text":"myelination.compute_myelination_bonus_map (cognitive 60): myelination.compute_myelination_bonus_map has cognitive complexity 60 (threshold 15). Drivers by points: if/else 17 (35 pts), boolean chains 14, loops 6 (11 pts) (nesting depth added 23). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"core_memory/runtime/observability/myelination.py"},"region":{"startLine":57}}}],"partialFingerprints":{"codehealthFindingId/v1":"2b88c9cf1835a435f0f52b13a60a5b32cb4e945bc7fabde186323bfda1b02c32"}},{"ruleId":"D2","level":"warning","message":{"text":"models._normalize_bead_payload (cognitive 59): models._normalize_bead_payload has cognitive complexity 59 (threshold 15). Drivers by points: if/else 22 (28 pts), ternaries 9 (16 pts), boolean chains 12, 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":"core_memory/schema/models.py"},"region":{"startLine":310}}}],"partialFingerprints":{"codehealthFindingId/v1":"5dd2aefa5238cf4ca176b2aa162ef092647920a72d4a10bb3200e5c43634228b"}},{"ruleId":"D2","level":"warning","message":{"text":"Neo4jClient.upsert_projection (cognitive 58): Neo4jClient.upsert_projection has cognitive complexity 58 (threshold 15). Drivers by points: boolean chains 32, if/else 11 (20 pts), error handling 4, loops 2 (nesting depth added 9). 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":"core_memory/integrations/neo4j/client.py"},"region":{"startLine":121}}}],"partialFingerprints":{"codehealthFindingId/v1":"259499e7adb80bc9591da65e7940ba500f16210d11f48748c92795ffe72bfa70"}},{"ruleId":"D2","level":"warning","message":{"text":"agent._collect_extra_seeds (cognitive 58): agent._collect_extra_seeds has cognitive complexity 58 (threshold 15). Drivers by points: boolean chains 22, if/else 7 (16 pts), ternaries 3 (8 pts), loops 4 (7 pts), error handling 4 (5 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":"core_memory/retrieval/agent.py"},"region":{"startLine":473}}}],"partialFingerprints":{"codehealthFindingId/v1":"8d9473442f34c1f69d0e62a30758249548fd6d0d3e46b2ad86b9f8c06da4faa7"}},{"ruleId":"D2","level":"warning","message":{"text":"core.build_graph (cognitive 56): core.build_graph has cognitive complexity 56 (threshold 15). Drivers by points: if/else 16 (30 pts), boolean chains 18, loops 6 (8 pts) (nesting depth added 16). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"core_memory/graph/core.py"},"region":{"startLine":673}}}],"partialFingerprints":{"codehealthFindingId/v1":"1c40c29a423dcf98d9456a383a9cbcaffb9ed2989813d3e1a536bfcd2a0ce666"}},{"ruleId":"D2","level":"warning","message":{"text":"coverage._normalized_candidate_rows (cognitive 56): coverage._normalized_candidate_rows has cognitive complexity 56 (threshold 15). Drivers by points: if/else 13 (27 pts), boolean chains 20, loops 4 (5 pts), ternaries 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":"core_memory/runtime/associations/coverage.py"},"region":{"startLine":490}}}],"partialFingerprints":{"codehealthFindingId/v1":"770b92c40e2d5881b529ee06f917c55b6577d8eebe92aa366d34f9037c0b0eb0"}},{"ruleId":"D2","level":"warning","message":{"text":"side_effect_queue.drain_side_effect_queue (cognitive 55): side_effect_queue.drain_side_effect_queue has cognitive complexity 55 (threshold 15). Drivers by points: if/else 11 (24 pts), boolean chains 22, loops 3 (4 pts), ternaries 2 (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":"core_memory/runtime/queue/side_effect_queue.py"},"region":{"startLine":582}}}],"partialFingerprints":{"codehealthFindingId/v1":"6fad9b2849ff96171b5def27b99815750f60a88cb228d436de10d4740268dde6"}},{"ruleId":"D2","level":"warning","message":{"text":"agent_authored_updates._validate_json_value (cognitive 55): agent_authored_updates._validate_json_value has cognitive complexity 55 (threshold 15). Drivers by points: if/else 21 (38 pts), boolean chains 10, loops 2 (5 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":"core_memory/schema/agent_authored_updates.py"},"region":{"startLine":506}}}],"partialFingerprints":{"codehealthFindingId/v1":"6f95cad27da971597752f7af6b221adb6497af92b762271e3d300bedd481822e"}},{"ruleId":"D2","level":"warning","message":{"text":"store_retrieval_context.retrieve_with_context_for_store (cognitive 54): store_retrieval_context.retrieve_with_context_for_store has cognitive complexity 54 (threshold 15). Drivers by points: if/else 14 (27 pts), boolean chains 15, loops 4 (8 pts), ternaries 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":"core_memory/persistence/store_retrieval_context.py"},"region":{"startLine":6}}}],"partialFingerprints":{"codehealthFindingId/v1":"c0d5a03cc8bdd50b675f3246200aa89515da242bd7326dc1c5cac67ced477952"}},{"ruleId":"D2","level":"warning","message":{"text":"chunk_evidence.resolve_semantic_hits (cognitive 54): chunk_evidence.resolve_semantic_hits has cognitive complexity 54 (threshold 15). Drivers by points: if/else 11 (27 pts), boolean chains 13, ternaries 5 (10 pts), loops 2 (4 pts) (nesting depth added 23). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"core_memory/retrieval/chunk_evidence.py"},"region":{"startLine":190}}}],"partialFingerprints":{"codehealthFindingId/v1":"b3fceee0cc55f5ecd0e5ec261c295a7e362d3b53c5719ed7c986981b756dd907"}},{"ruleId":"D2","level":"warning","message":{"text":"semantic_index._provider_vectors (cognitive 54): semantic_index._provider_vectors has cognitive complexity 54 (threshold 15). Drivers by points: if/else 8 (24 pts), boolean chains 12, loops 4 (10 pts), error handling 2 (8 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":"core_memory/retrieval/semantic_index.py"},"region":{"startLine":768}}}],"partialFingerprints":{"codehealthFindingId/v1":"f6a0d53571502056282969e96c51237493e21e4b4b2581ddf7dccb0ca4c7d162"}},{"ruleId":"D2","level":"warning","message":{"text":"external_evidence._find_existing_external_bead (cognitive 54): external_evidence._find_existing_external_bead has cognitive complexity 54 (threshold 15). Drivers by points: if/else 16 (39 pts), boolean chains 11, loops 2 (3 pts), ternaries 1 (nesting depth added 24). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"core_memory/runtime/ingest/external_evidence.py"},"region":{"startLine":242}}}],"partialFingerprints":{"codehealthFindingId/v1":"7673a5ca2fc676f1e97d3a568dbd294063c077461245056840c768b0773c0126"}},{"ruleId":"D2","level":"warning","message":{"text":"summary._build_divergence (cognitive 54): summary._build_divergence has cognitive complexity 54 (threshold 15). Drivers by points: boolean chains 26, if/else 9 (23 pts), error handling 2, loops 2, ternaries 1 (nesting depth added 14). 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":"core_memory/soul/summary.py"},"region":{"startLine":829}}}],"partialFingerprints":{"codehealthFindingId/v1":"529d98872c76a4afbc96b29729de8957c839d6917b972635c17e263dd55a68ec"}},{"ruleId":"D2","level":"warning","message":{"text":"transcript_ingest._resolve_envelope_speakers (cognitive 54): transcript_ingest._resolve_envelope_speakers has cognitive complexity 54 (threshold 15). Drivers by points: if/else 10 (23 pts), boolean chains 17, loops 7 (13 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":"core_memory/transcript_ingest.py"},"region":{"startLine":467}}}],"partialFingerprints":{"codehealthFindingId/v1":"1f188c37a09300d6ee0fbed709b9aa9a178b74ff3ce9da6606930c7cb472fbd7"}},{"ruleId":"D2","level":"warning","message":{"text":"canonical._apply_hint_boosts (cognitive 53): canonical._apply_hint_boosts has cognitive complexity 53 (threshold 15). Drivers by points: if/else 13 (28 pts), boolean chains 19, loops 4 (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":"core_memory/retrieval/pipeline/canonical.py"},"region":{"startLine":811}}}],"partialFingerprints":{"codehealthFindingId/v1":"6cdca91dd4ac7916d2da6520dfa9280025030a0f1ad50834f6a05d40e3339fa2"}},{"ruleId":"D2","level":"warning","message":{"text":"bead_projection.build_retrieval_text (cognitive 53): bead_projection.build_retrieval_text has cognitive complexity 53 (threshold 15). Drivers by points: if/else 17 (34 pts), boolean chains 16, loops 3 (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":"core_memory/schema/bead_projection.py"},"region":{"startLine":79}}}],"partialFingerprints":{"codehealthFindingId/v1":"972a952d89c0cdb40e55ede3d9828bf30f54575654de55775380c3eda7d233c6"}},{"ruleId":"D2","level":"warning","message":{"text":"context_recall.retrieve_with_context (cognitive 52): context_recall.retrieve_with_context has cognitive complexity 52 (threshold 15). Drivers by points: if/else 14 (27 pts), boolean chains 13, loops 4 (8 pts), ternaries 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":"core_memory/retrieval/context_recall.py"},"region":{"startLine":15}}}],"partialFingerprints":{"codehealthFindingId/v1":"e3a75dabe88828413eae7a016438df5839977d7d77a015507b07bb53aad755c7"}},{"ruleId":"D2","level":"warning","message":{"text":"answer_signals.compute_answer_signals (cognitive 51): answer_signals.compute_answer_signals has cognitive complexity 51 (threshold 15). Drivers by points: if/else 16 (25 pts), boolean chains 22, loops 1 (2 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":"core_memory/claim/answer_signals.py"},"region":{"startLine":15}}}],"partialFingerprints":{"codehealthFindingId/v1":"35e81f388ab5bb11297eafa938d8fa02abb9f8db031f43d00f6e1184d1ec24d0"}},{"ruleId":"D2","level":"warning","message":{"text":"metrics.handle_metrics_command (cognitive 51): metrics.handle_metrics_command has cognitive complexity 51 (threshold 15). Drivers by points: if/else 18 (36 pts), boolean chains 12, ternaries 1 (3 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":"core_memory/cli/handlers/metrics.py"},"region":{"startLine":14}}}],"partialFingerprints":{"codehealthFindingId/v1":"a3205ebff302dd9d65863e284137fde151aac3d3198493c27a2bfa4401a6cb12"}},{"ruleId":"D2","level":"warning","message":{"text":"engine._resolve_reviewed_updates (cognitive 51): engine._resolve_reviewed_updates has cognitive complexity 51 (threshold 15). Drivers by points: boolean chains 23, if/else 12 (20 pts), ternaries 4 (8 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":"core_memory/runtime/engine.py"},"region":{"startLine":302}}}],"partialFingerprints":{"codehealthFindingId/v1":"6c1af46b5fb6c37662f4314ed82d9ad7730663387eda78244103957b11175976"}},{"ruleId":"D2","level":"warning","message":{"text":"coverage.apply_association_proposals (cognitive 50): coverage.apply_association_proposals has cognitive complexity 50 (threshold 15). Drivers by points: if/else 11 (25 pts), boolean chains 18, ternaries 3 (6 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":"core_memory/runtime/associations/coverage.py"},"region":{"startLine":3270}}}],"partialFingerprints":{"codehealthFindingId/v1":"380dfdd69d50d3d0524ba4e74cf64317763f3c8d01e04248bb3362b5c9639aa9"}},{"ruleId":"D2","level":"warning","message":{"text":"agent._conflicts_for_result (cognitive 49): agent._conflicts_for_result has cognitive complexity 49 (threshold 15). Drivers by points: if/else 10 (24 pts), boolean chains 13, loops 4 (6 pts), ternaries 3 (6 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":"core_memory/retrieval/agent.py"},"region":{"startLine":241}}}],"partialFingerprints":{"codehealthFindingId/v1":"a324557464288a7b72f0aae205686bbdaa2e00ce4753697b39fca9f787853ca2"}},{"ruleId":"D2","level":"warning","message":{"text":"catalog.build_catalog (cognitive 49): catalog.build_catalog has cognitive complexity 49 (threshold 15). Drivers by points: if/else 10 (28 pts), boolean chains 10, loops 5 (9 pts), error handling 1 (2 pts) (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":"core_memory/retrieval/pipeline/catalog.py"},"region":{"startLine":14}}}],"partialFingerprints":{"codehealthFindingId/v1":"c12a1796278eeb101197cf20ce6e5ce58da7797075950b6d50f18199fb683bdb"}},{"ruleId":"D2","level":"warning","message":{"text":"myelination_rewards.supporting_edge_keys_for_bead (cognitive 48): myelination_rewards.supporting_edge_keys_for_bead has cognitive complexity 48 (threshold 15). Drivers by points: if/else 11 (29 pts), boolean chains 11, loops 3 (6 pts), 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":"core_memory/persistence/myelination_rewards.py"},"region":{"startLine":164}}}],"partialFingerprints":{"codehealthFindingId/v1":"609bf1934f4847d5bf3ee4ecf1fa59a4ca5c414be7ba6fe1e30de99e405a6275"}},{"ruleId":"D2","level":"warning","message":{"text":"canonical._claim_answer_candidate (cognitive 48): canonical._claim_answer_candidate has cognitive complexity 48 (threshold 15). Drivers by points: boolean chains 25, if/else 13 (19 pts), loops 1 (2 pts), ternaries 2 (nesting depth added 7). 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":"core_memory/retrieval/pipeline/canonical.py"},"region":{"startLine":310}}}],"partialFingerprints":{"codehealthFindingId/v1":"b617c4fb2073cbce7c594d7d8adcefca92a656afcf9160a938d1af22bfafea46"}},{"ruleId":"D2","level":"warning","message":{"text":"core.infer_structural_edges (cognitive 47): core.infer_structural_edges has cognitive complexity 47 (threshold 15). Drivers by points: if/else 9 (23 pts), boolean chains 14, loops 6 (10 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":"core_memory/graph/core.py"},"region":{"startLine":582}}}],"partialFingerprints":{"codehealthFindingId/v1":"6b2462dbd1e34588e10283851bbe57937c93de84f4ff401a08e163955ce7b910"}},{"ruleId":"D2","level":"warning","message":{"text":"coverage._pair_signals (cognitive 47): coverage._pair_signals has cognitive complexity 47 (threshold 15). Drivers by points: if/else 19 (24 pts), boolean chains 16, ternaries 3 (7 pts) (nesting depth added 9). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"core_memory/runtime/associations/coverage.py"},"region":{"startLine":1056}}}],"partialFingerprints":{"codehealthFindingId/v1":"d521d71dafe7e49d36792972b992ead5b8b645141632674cb8cae326c8e152de"}},{"ruleId":"D2","level":"warning","message":{"text":"storylines.derive_storylines (cognitive 46): storylines.derive_storylines has cognitive complexity 46 (threshold 15). Drivers by points: if/else 8 (19 pts), boolean chains 13, loops 5 (7 pts), ternaries 1 (4 pts), error handling 1 (3 pts) (nesting depth added 18). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"core_memory/graph/storylines.py"},"region":{"startLine":66}}}],"partialFingerprints":{"codehealthFindingId/v1":"e1680f1023bb7c488617a6a674d78cf515ff91c2fead06c4b113591108db87aa"}},{"ruleId":"D2","level":"warning","message":{"text":"source_hydration.hydrate_bead_sources_for_root (cognitive 46): source_hydration.hydrate_bead_sources_for_root has cognitive complexity 46 (threshold 15). Drivers by points: if/else 11 (23 pts), loops 4 (9 pts), boolean chains 8, error handling 1 (3 pts), ternaries 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":"core_memory/persistence/source_hydration.py"},"region":{"startLine":19}}}],"partialFingerprints":{"codehealthFindingId/v1":"8776bcf6810a1dcc973a55d209ec2020ea777d17eaacc9e48b6d8cf16581c9ea"}},{"ruleId":"D2","level":"warning","message":{"text":"analysis.synthesize_themes (cognitive 46): analysis.synthesize_themes has cognitive complexity 46 (threshold 15). Drivers by points: if/else 8 (18 pts), loops 6 (13 pts), boolean chains 11, ternaries 1 (3 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":"core_memory/runtime/dreamer/analysis.py"},"region":{"startLine":545}}}],"partialFingerprints":{"codehealthFindingId/v1":"45ffa13885894061b85a43cc08fd18b61e3445dba3472c59d0ac332081e1f156"}},{"ruleId":"D2","level":"warning","message":{"text":"calibration.compute_calibration_curve (cognitive 45): calibration.compute_calibration_curve has cognitive complexity 45 (threshold 15). Drivers by points: if/else 11 (21 pts), ternaries 7 (11 pts), boolean chains 9, loops 3 (4 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":"core_memory/persistence/calibration.py"},"region":{"startLine":182}}}],"partialFingerprints":{"codehealthFindingId/v1":"7455c7159f960c146fb758ba9343d07995fd9f071a8deadabedf205c6e94b551"}},{"ruleId":"D2","level":"warning","message":{"text":"evidence_scoring.rerank_semantic_rows (cognitive 45): evidence_scoring.rerank_semantic_rows has cognitive complexity 45 (threshold 15). Drivers by points: if/else 11 (21 pts), boolean chains 17, ternaries 3 (6 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":"core_memory/retrieval/evidence_scoring.py"},"region":{"startLine":105}}}],"partialFingerprints":{"codehealthFindingId/v1":"1e5e0845d01da93c441e5344f9ea314848a646557e8e4d7024cc46f66fa3f768"}},{"ruleId":"D2","level":"warning","message":{"text":"coverage.enqueue_association_coverage (cognitive 45): coverage.enqueue_association_coverage has cognitive complexity 45 (threshold 15). Drivers by points: boolean chains 30, if/else 11 (12 pts), ternaries 3 (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":"core_memory/runtime/associations/coverage.py"},"region":{"startLine":2192}}}],"partialFingerprints":{"codehealthFindingId/v1":"399018771e4fd16c9dfcc717c2a3c0eda8fb1b9e5319c1c8c96057c5a419e017"}},{"ruleId":"D2","level":"warning","message":{"text":"health.association_health_report (cognitive 44): health.association_health_report has cognitive complexity 44 (threshold 15). Drivers by points: if/else 16 (26 pts), boolean chains 14, loops 2 (3 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":"core_memory/association/health.py"},"region":{"startLine":120}}}],"partialFingerprints":{"codehealthFindingId/v1":"d76f64c40dbb1a4995542f99775ceb21b5774333bfb95194180d65c1ac396954"}},{"ruleId":"D2","level":"warning","message":{"text":"graph.handle_graph_command (cognitive 44): graph.handle_graph_command has cognitive complexity 44 (threshold 15). Drivers by points: if/else 16 (28 pts), boolean chains 12, ternaries 2 (4 pts) (nesting depth added 14). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"core_memory/cli/handlers/graph.py"},"region":{"startLine":20}}}],"partialFingerprints":{"codehealthFindingId/v1":"901995b3768ee6f695179eacbdd7bd165ae9a00d6012999edbc84c3c77662132"}},{"ruleId":"D2","level":"warning","message":{"text":"ingest_discord.ingest_discord_handler (cognitive 44): ingest_discord.ingest_discord_handler has cognitive complexity 44 (threshold 15). Drivers by points: if/else 11 (18 pts), boolean chains 17, error handling 3 (5 pts), ternaries 2 (3 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":"core_memory/integrations/mcp/tools/ingest_discord.py"},"region":{"startLine":79}}}],"partialFingerprints":{"codehealthFindingId/v1":"e520679db971b92c6ad32d2650786bb0e3eaf851846cf5959eee01f0d44b8f89"}},{"ruleId":"D2","level":"warning","message":{"text":"semantic_index.load_cached_bead_embeddings (cognitive 44): semantic_index.load_cached_bead_embeddings has cognitive complexity 44 (threshold 15). Drivers by points: if/else 12 (20 pts), boolean chains 12, loops 4 (6 pts), error handling 2 (3 pts), 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":"core_memory/retrieval/semantic_index.py"},"region":{"startLine":945}}}],"partialFingerprints":{"codehealthFindingId/v1":"b0f8184acd1073998ce4c9553455b32c1565f2350b22a347b75d1c97819b1d1c"}},{"ruleId":"D2","level":"warning","message":{"text":"memory.handle_memory_command (cognitive 43): memory.handle_memory_command has cognitive complexity 43 (threshold 15). Drivers by points: if/else 14 (27 pts), boolean chains 16 (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":"core_memory/cli/handlers/memory.py"},"region":{"startLine":8}}}],"partialFingerprints":{"codehealthFindingId/v1":"a93dc28a9db48e776405b0357962e3c4b4529e5ace29bc142ac6f6d142b995fa"}},{"ruleId":"D2","level":"warning","message":{"text":"traversal.filter_chains_to_active_edges (cognitive 43): traversal.filter_chains_to_active_edges has cognitive complexity 43 (threshold 15). Drivers by points: if/else 10 (21 pts), boolean chains 15, loops 4 (6 pts), 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":"core_memory/graph/traversal.py"},"region":{"startLine":106}}}],"partialFingerprints":{"codehealthFindingId/v1":"2e0e95d3991a3ac5f7c1cccf800863cc640bec5c1ef88d46ce109bfaf1d2eb99"}},{"ruleId":"D2","level":"warning","message":{"text":"rerank._load_structural_adjacency (cognitive 43): rerank._load_structural_adjacency has cognitive complexity 43 (threshold 15). Drivers by points: if/else 8 (20 pts), boolean chains 9, error handling 3 (7 pts), loops 2 (4 pts), ternaries 1 (3 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":"core_memory/retrieval/rerank.py"},"region":{"startLine":113}}}],"partialFingerprints":{"codehealthFindingId/v1":"4dc416c3e265c065cb2c340f1382f4280eb40c5bae16d3a94903a37b71afecc4"}},{"ruleId":"D2","level":"warning","message":{"text":"check_architecture_guards.check_cleanup_truth (cognitive 43): check_architecture_guards.check_cleanup_truth has cognitive complexity 43 (threshold 15). Drivers by points: if/else 10 (31 pts), loops 5 (12 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":"scripts/check_architecture_guards.py"},"region":{"startLine":580}}}],"partialFingerprints":{"codehealthFindingId/v1":"f50330188dc0304794ff153e8ea1b597fef4e44039dec82c1ed84504c8d5c0c5"}},{"ruleId":"D2","level":"warning","message":{"text":"core.backfill_structural_edges (cognitive 42): core.backfill_structural_edges has cognitive complexity 42 (threshold 15). Drivers by points: if/else 9 (19 pts), boolean chains 18, loops 4 (5 pts) (nesting depth added 11). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"core_memory/graph/core.py"},"region":{"startLine":488}}}],"partialFingerprints":{"codehealthFindingId/v1":"c7ac481d2b1e5a855e9a0291b0252956c97b48a5151c9251ad8a66a34a141c12"}},{"ruleId":"D2","level":"warning","message":{"text":"eval.dreamer_eval_report (cognitive 42): eval.dreamer_eval_report has cognitive complexity 42 (threshold 15). Drivers by points: if/else 18 (21 pts), boolean chains 20, 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":"core_memory/runtime/dreamer/eval.py"},"region":{"startLine":261}}}],"partialFingerprints":{"codehealthFindingId/v1":"31afeba8689dc584cb5eec39b893fc1bfcb610b0e9096341ae1fb2efdacddd1a"}},{"ruleId":"D2","level":"warning","message":{"text":"reviewer_quick_value.reviewer_quick_value_v2 (cognitive 42): reviewer_quick_value.reviewer_quick_value_v2 has cognitive complexity 42 (threshold 15). Drivers by points: boolean chains 33, if/else 6 (7 pts), loops 1, ternaries 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":"core_memory/runtime/observability/reviewer_quick_value.py"},"region":{"startLine":61}}}],"partialFingerprints":{"codehealthFindingId/v1":"5315b2a654f0cf2a3ffe906bc1a3535623cbcac7fb4fb4c0f1ff2a907041758b"}},{"ruleId":"D2","level":"warning","message":{"text":"reauthoring.reauthor_memory (cognitive 42): reauthoring.reauthor_memory has cognitive complexity 42 (threshold 15). Drivers by points: if/else 12 (19 pts), boolean chains 11, ternaries 4 (7 pts), error handling 2 (4 pts), loops 1 (nesting depth added 12). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"core_memory/runtime/turn/reauthoring.py"},"region":{"startLine":618}}}],"partialFingerprints":{"codehealthFindingId/v1":"9517462c4a216909b7c49f69ae3f3848b6529af549f607751bd52f9e0f3759b7"}},{"ruleId":"D2","level":"warning","message":{"text":"memory_execute_eval.main (cognitive 42): memory_execute_eval.main has cognitive complexity 42 (threshold 15). Drivers by points: if/else 19 (21 pts), boolean chains 20, loops 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":"eval/memory_execute_eval.py"},"region":{"startLine":44}}}],"partialFingerprints":{"codehealthFindingId/v1":"28003296b2a51869c3e7e0b6129f05fd1b77d34ff42d0e7ff4efcf103919201c"}},{"ruleId":"D2","level":"warning","message":{"text":"agent_end_bridge.process_agent_end_event (cognitive 41): agent_end_bridge.process_agent_end_event has cognitive complexity 41 (threshold 15). Drivers by points: boolean chains 21, if/else 15 (16 pts), ternaries 4 (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":"core_memory/integrations/openclaw/agent_end_bridge.py"},"region":{"startLine":182}}}],"partialFingerprints":{"codehealthFindingId/v1":"1b9dd815d1767807e99b34157fc14f3fd0f7023afa473a8fb0a2e83d435c9c0a"}},{"ruleId":"D2","level":"warning","message":{"text":"semantic_task_verifier.verify_semantic_task_output (cognitive 41): semantic_task_verifier.verify_semantic_task_output has cognitive complexity 41 (threshold 15). Drivers by points: boolean chains 29, ternaries 6 (9 pts), if/else 3 (nesting depth added 3). 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":"core_memory/policy/semantic_task_verifier.py"},"region":{"startLine":182}}}],"partialFingerprints":{"codehealthFindingId/v1":"31d5e39653da0ee09c2614ef8cd804b72cae3e8ffe215ae0dc3ffd5fd8f23d61"}},{"ruleId":"D2","level":"warning","message":{"text":"chunk_evidence.build_chunk_evidence_corpus (cognitive 41): chunk_evidence.build_chunk_evidence_corpus has cognitive complexity 41 (threshold 15). Drivers by points: if/else 8 (18 pts), boolean chains 13, loops 4 (6 pts), ternaries 2 (4 pts) (nesting depth added 14). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"core_memory/retrieval/chunk_evidence.py"},"region":{"startLine":110}}}],"partialFingerprints":{"codehealthFindingId/v1":"c7519c8189f127b1804aa11d9469d6e9401ce764fd80fc50ab8ff0a0e3e7dcaf"}},{"ruleId":"D2","level":"warning","message":{"text":"memory_search_ab_compare.main (cognitive 41): memory_search_ab_compare.main has cognitive complexity 41 (threshold 15). Drivers by points: ternaries 6 (19 pts), boolean chains 16, if/else 1 (3 pts), loops 2 (3 pts) (nesting depth added 16). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"eval/memory_search_ab_compare.py"},"region":{"startLine":30}}}],"partialFingerprints":{"codehealthFindingId/v1":"eaf72c41bbe64914c12aaa3af74642b567ceb3a1f8906fe9449d443a9e4e9f33"}},{"ruleId":"D2","level":"warning","message":{"text":"cli.main (cognitive 40): cli.main has cognitive complexity 40 (threshold 15). Drivers by points: if/else 27 (40 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":"core_memory/cli/__init__.py"},"region":{"startLine":100}}}],"partialFingerprints":{"codehealthFindingId/v1":"52ba693004ae5b5f3303dd74251b3103f056b4504b356e77796cd7ec415014a8"}},{"ruleId":"D2","level":"warning","message":{"text":"ingest_zoom.ingest_zoom_handler (cognitive 40): ingest_zoom.ingest_zoom_handler has cognitive complexity 40 (threshold 15). Drivers by points: if/else 11 (16 pts), boolean chains 14, error handling 3 (6 pts), ternaries 2 (3 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":"core_memory/integrations/mcp/tools/ingest_zoom.py"},"region":{"startLine":129}}}],"partialFingerprints":{"codehealthFindingId/v1":"6a42ae05bb2a0458bc2ff531f3e87852da1ef7e5af9ab8fdc277b527b134be91"}},{"ruleId":"D2","level":"warning","message":{"text":"promotion_service.promotion_kpis_for_store (cognitive 40): promotion_service.promotion_kpis_for_store has cognitive complexity 40 (threshold 15). Drivers by points: boolean chains 21, if/else 8 (15 pts), loops 3, ternaries 1 (nesting depth added 7). 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":"core_memory/persistence/promotion_service.py"},"region":{"startLine":528}}}],"partialFingerprints":{"codehealthFindingId/v1":"a638d91e53e6db80ae3eceb68c581208baed054f9e1197f8735cea323abc0e5e"}},{"ruleId":"D2","level":"warning","message":{"text":"store_add_bead_ops.add_bead_for_store (cognitive 40): store_add_bead_ops.add_bead_for_store has cognitive complexity 40 (threshold 15). Drivers by points: if/else 18 (24 pts), boolean chains 14, error handling 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":"core_memory/persistence/store_add_bead_ops.py"},"region":{"startLine":33}}}],"partialFingerprints":{"codehealthFindingId/v1":"eb022a59df6190c044ff66096a018a917f34733782dd86015370f516adad1295"}},{"ruleId":"D2","level":"warning","message":{"text":"integrity.soul_integrity_check (cognitive 40): integrity.soul_integrity_check has cognitive complexity 40 (threshold 15). Drivers by points: boolean chains 15, if/else 7 (15 pts), ternaries 2 (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":"core_memory/soul/integrity.py"},"region":{"startLine":63}}}],"partialFingerprints":{"codehealthFindingId/v1":"4e1cc40bb902263389a1c79167f40aad906768d1ddaeb981d8d98fc66c15bf33"}},{"ruleId":"D2","level":"warning","message":{"text":"paraphrase_eval.main (cognitive 40): paraphrase_eval.main has cognitive complexity 40 (threshold 15). Drivers by points: boolean chains 15, if/else 5 (11 pts), loops 4 (7 pts), ternaries 4 (7 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":"eval/paraphrase_eval.py"},"region":{"startLine":51}}}],"partialFingerprints":{"codehealthFindingId/v1":"b249f892c93d3868541baed0dd3afa74a9e038240c73cb70e7873662adbada8e"}},{"ruleId":"D2","level":"warning","message":{"text":"store.handle_store_commands (cognitive 39): store.handle_store_commands has cognitive complexity 39 (threshold 15). Drivers by points: if/else 26 (33 pts), boolean chains 4, loops 1 (2 pts) (nesting depth added 8). 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":"core_memory/cli/handlers/store.py"},"region":{"startLine":14}}}],"partialFingerprints":{"codehealthFindingId/v1":"f2e57a112d6f005fd94a5853847763a08f9fad8a69e124a4e385a31cbd962046"}},{"ruleId":"D2","level":"warning","message":{"text":"root_cause._build_edges (cognitive 39): root_cause._build_edges has cognitive complexity 39 (threshold 15). Drivers by points: if/else 7 (16 pts), boolean chains 9, loops 6 (9 pts), error handling 2 (3 pts), ternaries 2 (nesting depth added 13). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"core_memory/graph/root_cause.py"},"region":{"startLine":163}}}],"partialFingerprints":{"codehealthFindingId/v1":"7c6e94a40db241567f76bdad0fff3f8c7374b13ddff39dd6377a41fb076f66fa"}},{"ruleId":"D2","level":"warning","message":{"text":"worldlines._goal_worldlines (cognitive 39): worldlines._goal_worldlines has cognitive complexity 39 (threshold 15). Drivers by points: if/else 7 (18 pts), boolean chains 13, loops 4 (6 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":"core_memory/graph/worldlines.py"},"region":{"startLine":161}}}],"partialFingerprints":{"codehealthFindingId/v1":"79dfdc72e657837d132258e06944f6f432d2870b6b26556589c9f87da6d60327"}},{"ruleId":"D2","level":"warning","message":{"text":"retrieval_feedback.record_retrieval_feedback (cognitive 39): retrieval_feedback.record_retrieval_feedback has cognitive complexity 39 (threshold 15). Drivers by points: boolean chains 35, if/else 3, ternaries 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":"core_memory/persistence/retrieval_feedback.py"},"region":{"startLine":76}}}],"partialFingerprints":{"codehealthFindingId/v1":"c992bf7cb734afbea1c4719142cfcf06b6eeadaf70a9f71fd088046ebf8e8de3"}},{"ruleId":"D2","level":"warning","message":{"text":"retrieval_feedback.summarize_retrieval_feedback (cognitive 39): retrieval_feedback.summarize_retrieval_feedback has cognitive complexity 39 (threshold 15). Drivers by points: if/else 7 (17 pts), boolean chains 14, loops 5 (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":"core_memory/persistence/retrieval_feedback.py"},"region":{"startLine":180}}}],"partialFingerprints":{"codehealthFindingId/v1":"409d2d4b9fb5a8fe602ef464d669196388df609150a54ac7a9e5d7b989c98abf"}},{"ruleId":"D2","level":"warning","message":{"text":"store_relationship_ops.promote_for_store (cognitive 39): store_relationship_ops.promote_for_store has cognitive complexity 39 (threshold 15). Drivers by points: if/else 11 (21 pts), boolean chains 18 (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":"core_memory/persistence/store_relationship_ops.py"},"region":{"startLine":18}}}],"partialFingerprints":{"codehealthFindingId/v1":"08073c36bac39830597ccbffc9e3ef8c68a2b424ea7ebdecea65574113ad90cc"}},{"ruleId":"D2","level":"warning","message":{"text":"causal_recall.extract_source_citations (cognitive 39): causal_recall.extract_source_citations has cognitive complexity 39 (threshold 15). Drivers by points: if/else 8 (18 pts), boolean chains 9, loops 4 (7 pts), ternaries 3 (5 pts) (nesting depth added 15). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"core_memory/retrieval/causal_recall.py"},"region":{"startLine":146}}}],"partialFingerprints":{"codehealthFindingId/v1":"8dbde148c69311dfed23ff79b449c91e4e4bf8df07d5ed25a7013738d5aabb8a"}},{"ruleId":"D2","level":"warning","message":{"text":"refinement.refine_pending_candidates (cognitive 39): refinement.refine_pending_candidates has cognitive complexity 39 (threshold 15). Drivers by points: boolean chains 23, if/else 11 (13 pts), ternaries 2, loops 1 (nesting depth added 2). 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":"core_memory/runtime/dreamer/refinement.py"},"region":{"startLine":145}}}],"partialFingerprints":{"codehealthFindingId/v1":"45102690100be2adb3b6529a7f2dc7c218c60a466ecb06b0658421638173ce3f"}},{"ruleId":"D2","level":"warning","message":{"text":"retrieval_eval._causal_grounding_components (cognitive 39): retrieval_eval._causal_grounding_components has cognitive complexity 39 (threshold 15). Drivers by points: if/else 6 (18 pts), boolean chains 14, loops 2 (7 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":"eval/retrieval_eval.py"},"region":{"startLine":22}}}],"partialFingerprints":{"codehealthFindingId/v1":"c8edb9550fd0ea33aed62a90599e9663141c5d1a1eb52ab08c30696600c24652"}},{"ruleId":"D2","level":"warning","message":{"text":"audit_store_delegation.main (cognitive 39): audit_store_delegation.main has cognitive complexity 39 (threshold 15). Drivers by points: if/else 11 (18 pts), ternaries 4 (12 pts), loops 5 (9 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":"scripts/audit_store_delegation.py"},"region":{"startLine":74}}}],"partialFingerprints":{"codehealthFindingId/v1":"f9fb2155f01ca8286d7be3d6e21c33dd6aa541951ca23774635a62f57dc0d0e8"}},{"ruleId":"D2","level":"warning","message":{"text":"core._sync_associations_to_links (cognitive 38): core._sync_associations_to_links has cognitive complexity 38 (threshold 15). Drivers by points: if/else 9 (19 pts), boolean chains 15, loops 3 (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":"core_memory/graph/core.py"},"region":{"startLine":188}}}],"partialFingerprints":{"codehealthFindingId/v1":"d2a76b19b4b94ad0ed81625850e605d428ffbbaebbe42f57a02c9b1fe350334e"}},{"ruleId":"D2","level":"warning","message":{"text":"entity_registry.upsert_canonical_entity (cognitive 38): entity_registry.upsert_canonical_entity has cognitive complexity 38 (threshold 15). Drivers by points: boolean chains 21, if/else 11 (15 pts), loops 2 (nesting depth added 4). 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":"core_memory/persistence/entity_registry.py"},"region":{"startLine":112}}}],"partialFingerprints":{"codehealthFindingId/v1":"00887b18b426cb00b363b0565d50f412508988acba1e1a6dd9672ef3374ec99f"}},{"ruleId":"D2","level":"warning","message":{"text":"analysis.run_analysis (cognitive 38): analysis.run_analysis has cognitive complexity 38 (threshold 15). Drivers by points: if/else 11 (21 pts), boolean chains 11, loops 2 (3 pts), 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":"core_memory/runtime/dreamer/analysis.py"},"region":{"startLine":371}}}],"partialFingerprints":{"codehealthFindingId/v1":"3660ca092ed9f1db8b20afb5d56cc514c800ba547150f25af97fe058b9b05c51"}},{"ruleId":"D2","level":"warning","message":{"text":"chunk_turns.list_chunk_turns (cognitive 38): chunk_turns.list_chunk_turns has cognitive complexity 38 (threshold 15). Drivers by points: if/else 9 (21 pts), error handling 3 (8 pts), boolean chains 6, loops 2 (3 pts) (nesting depth added 18). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"core_memory/runtime/ingest/chunk_turns.py"},"region":{"startLine":263}}}],"partialFingerprints":{"codehealthFindingId/v1":"9133c3ec01aed65c6c3f07c71da5bad78c39783146ced6a56e12385fe079cb5c"}},{"ruleId":"D2","level":"warning","message":{"text":"transcript_ingest.ingest_turn_envelopes (cognitive 38): transcript_ingest.ingest_turn_envelopes has cognitive complexity 38 (threshold 15). Drivers by points: if/else 9 (16 pts), boolean chains 12, error handling 2 (5 pts), loops 2 (3 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":"core_memory/transcript_ingest.py"},"region":{"startLine":344}}}],"partialFingerprints":{"codehealthFindingId/v1":"194031c18ffbbe66d1ed6f92516124cdc4d2309fbc0374dab47dd62e9baaa899"}},{"ruleId":"D2","level":"warning","message":{"text":"edge_lifecycle.fold_edge_usage (cognitive 37): edge_lifecycle.fold_edge_usage has cognitive complexity 37 (threshold 15). Drivers by points: if/else 8 (16 pts), error handling 5 (7 pts), boolean chains 5, ternaries 2 (5 pts), 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":"core_memory/association/edge_lifecycle.py"},"region":{"startLine":131}}}],"partialFingerprints":{"codehealthFindingId/v1":"9b5538ff0196abd46f779721957538ac915d710de71d934d1b358776f9105bd7"}},{"ruleId":"D2","level":"warning","message":{"text":"roadmap.build_junction_roadmap (cognitive 37): roadmap.build_junction_roadmap has cognitive complexity 37 (threshold 15). Drivers by points: if/else 10 (18 pts), boolean chains 15, loops 1 (2 pts), ternaries 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":"core_memory/graph/roadmap.py"},"region":{"startLine":774}}}],"partialFingerprints":{"codehealthFindingId/v1":"885131c2798102621d3b1355e0cc4fa331b6bbeab92840e7a1ce55d50ed8b9d1"}},{"ruleId":"D2","level":"warning","message":{"text":"llm_client.chat_complete (cognitive 37): llm_client.chat_complete has cognitive complexity 37 (threshold 15). Drivers by points: if/else 14 (23 pts), boolean chains 12, 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":"core_memory/llm_client.py"},"region":{"startLine":27}}}],"partialFingerprints":{"codehealthFindingId/v1":"00df3fe7809fda4a82793a2756d7576a46a0328d83f0f593487fc06b76673129"}},{"ruleId":"D2","level":"warning","message":{"text":"store_add_helpers.find_recent_duplicate_bead_id_for_store (cognitive 37): store_add_helpers.find_recent_duplicate_bead_id_for_store has cognitive complexity 37 (threshold 15). Drivers by points: boolean chains 18, if/else 9 (18 pts), loops 1 (nesting depth added 9). 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":"core_memory/persistence/store_add_helpers.py"},"region":{"startLine":121}}}],"partialFingerprints":{"codehealthFindingId/v1":"59b00c7e85030fe0b83c61b8b4e5e1bc9c1c83d3626c02ab990a36d9924d07c5"}},{"ruleId":"D2","level":"warning","message":{"text":"store_claim_ops.resolve_current_state (cognitive 37): store_claim_ops.resolve_current_state has cognitive complexity 37 (threshold 15). Drivers by points: boolean chains 17, if/else 10 (14 pts), ternaries 4 (5 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":"core_memory/persistence/store_claim_ops.py"},"region":{"startLine":448}}}],"partialFingerprints":{"codehealthFindingId/v1":"1a4d314d97225e0d5c0f6ffb6f20edf53945e3d9a3f0c93c5e4c1759616961b7"}},{"ruleId":"D2","level":"warning","message":{"text":"hygiene.curated_type_title_hygiene (cognitive 37): hygiene.curated_type_title_hygiene has cognitive complexity 37 (threshold 15). Drivers by points: if/else 8 (16 pts), boolean chains 10, loops 4 (8 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":"core_memory/policy/hygiene.py"},"region":{"startLine":45}}}],"partialFingerprints":{"codehealthFindingId/v1":"992f294b38e25ff2ddc66ad05b1dd73f629dc7d4e622ce9d79696e4e040d939f"}},{"ruleId":"D2","level":"warning","message":{"text":"research._apply_candidate_refinements (cognitive 37): research._apply_candidate_refinements has cognitive complexity 37 (threshold 15). Drivers by points: boolean chains 23, if/else 8 (12 pts), loops 1, ternaries 1 (nesting depth added 4). 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":"core_memory/runtime/dreamer/research.py"},"region":{"startLine":243}}}],"partialFingerprints":{"codehealthFindingId/v1":"19a41287de5c5912bde4ece603ffe79231d3445ca91c496d645d8d0dda6c7055"}},{"ruleId":"D2","level":"warning","message":{"text":"receipt.build_turn_finalized_receipt (cognitive 37): receipt.build_turn_finalized_receipt has cognitive complexity 37 (threshold 15). Drivers by points: boolean chains 25, if/else 8, ternaries 2 (4 pts) (nesting depth added 2). 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":"core_memory/runtime/turn/receipt.py"},"region":{"startLine":129}}}],"partialFingerprints":{"codehealthFindingId/v1":"b1415f428dca5082ad36c79cc943f61de4013086b5bc29ee5e999681008b57aa"}},{"ruleId":"D2","level":"warning","message":{"text":"edge_lifecycle.collect_used_edge_pairs (cognitive 36): edge_lifecycle.collect_used_edge_pairs has cognitive complexity 36 (threshold 15). Drivers by points: if/else 9 (19 pts), boolean chains 11, loops 4 (6 pts) (nesting depth added 12). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"core_memory/association/edge_lifecycle.py"},"region":{"startLine":60}}}],"partialFingerprints":{"codehealthFindingId/v1":"58a29c69cfc617b923b35a87dc3ec251eef861133a0160a5e3fb2da1b6077791"}},{"ruleId":"D2","level":"warning","message":{"text":"root_cause.segment_frontier_between (cognitive 36): root_cause.segment_frontier_between has cognitive complexity 36 (threshold 15). Drivers by points: if/else 10 (16 pts), boolean chains 12, loops 4 (5 pts), ternaries 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":"core_memory/graph/root_cause.py"},"region":{"startLine":1168}}}],"partialFingerprints":{"codehealthFindingId/v1":"186b0ec189ca3878e4fd6c6787c0eb062d3d08d8fb556add5ee70bc59aff80ae"}},{"ruleId":"D2","level":"warning","message":{"text":"store_reporting.schema_quality_report_for_store (cognitive 36): store_reporting.schema_quality_report_for_store has cognitive complexity 36 (threshold 15). Drivers by points: boolean chains 19, if/else 6 (14 pts), loops 2 (3 pts) (nesting depth added 9). 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":"core_memory/persistence/store_reporting.py"},"region":{"startLine":127}}}],"partialFingerprints":{"codehealthFindingId/v1":"5827df3e07c8c52b923a40de3ce09cf062f0a4b0a6d38c8d1e01d347a746a339"}},{"ruleId":"D2","level":"warning","message":{"text":"memory_reason._select_diverse_chains (cognitive 36): memory_reason._select_diverse_chains has cognitive complexity 36 (threshold 15). Drivers by points: if/else 8 (22 pts), loops 5 (10 pts), boolean chains 4 (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":"core_memory/retrieval/tools/memory_reason.py"},"region":{"startLine":209}}}],"partialFingerprints":{"codehealthFindingId/v1":"9c5894ee2a14b7550a804773c0214d4db167e0385d3c9e889286990b8ea66ab3"}},{"ruleId":"D2","level":"warning","message":{"text":"research._bead_context (cognitive 36): research._bead_context has cognitive complexity 36 (threshold 15). Drivers by points: boolean chains 12, if/else 5 (12 pts), loops 5 (9 pts), ternaries 2 (3 pts) (nesting depth added 12). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"core_memory/runtime/dreamer/research.py"},"region":{"startLine":98}}}],"partialFingerprints":{"codehealthFindingId/v1":"7ac6b72596afbcd447b4fc0c2e0a3ce79b7baa06f6405aa9acd33c0a2f624e9c"}},{"ruleId":"D2","level":"warning","message":{"text":"update_policy.emit_claim_updates (cognitive 35): update_policy.emit_claim_updates has cognitive complexity 35 (threshold 15). Drivers by points: if/else 16 (25 pts), boolean chains 6, loops 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":"core_memory/claim/update_policy.py"},"region":{"startLine":123}}}],"partialFingerprints":{"codehealthFindingId/v1":"cddd42bc6d846ad79cfddfa45facd47456599f9ea19c74744911c980d47fecde"}},{"ruleId":"D2","level":"warning","message":{"text":"migrate.handle_migrate (cognitive 35): migrate.handle_migrate has cognitive complexity 35 (threshold 15). Drivers by points: if/else 7 (14 pts), boolean chains 9, error handling 4 (9 pts), loops 1 (2 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":"core_memory/cli/handlers/migrate.py"},"region":{"startLine":68}}}],"partialFingerprints":{"codehealthFindingId/v1":"72151e8b9a4b1599d76322f417bad88fa7508215316220345b44bc782d78badb"}},{"ruleId":"D2","level":"warning","message":{"text":"event_schema_audit.audit_event_schemas (cognitive 35): event_schema_audit.audit_event_schemas has cognitive complexity 35 (threshold 15). Drivers by points: if/else 7 (25 pts), loops 3 (6 pts), error handling 1 (3 pts), ternaries 1 (nesting depth added 23). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"core_memory/persistence/event_schema_audit.py"},"region":{"startLine":120}}}],"partialFingerprints":{"codehealthFindingId/v1":"26161105967a959ebd0874397c89fd7ac4b287f81e96db442c1d2b7267d95faf"}},{"ruleId":"D2","level":"warning","message":{"text":"store_validation_helpers.normalize_links (cognitive 35): store_validation_helpers.normalize_links has cognitive complexity 35 (threshold 15). Drivers by points: if/else 9 (22 pts), loops 3 (8 pts), boolean chains 5 (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":"core_memory/persistence/store_validation_helpers.py"},"region":{"startLine":6}}}],"partialFingerprints":{"codehealthFindingId/v1":"185432a039491c891fc281edbd83057fc02a81e4d231b800d9a4dcb69bf17003"}},{"ruleId":"D2","level":"warning","message":{"text":"turn_memory_authoring._value_at_path (cognitive 35): turn_memory_authoring._value_at_path has cognitive complexity 35 (threshold 15). Drivers by points: if/else 10 (27 pts), boolean chains 4, error handling 1 (3 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":"core_memory/policy/turn_memory_authoring.py"},"region":{"startLine":215}}}],"partialFingerprints":{"codehealthFindingId/v1":"ccb456e8835c08ddefda4fd382ec953f1a61c30c725f96311758b19c7ca99091"}},{"ruleId":"D2","level":"warning","message":{"text":"agent._resolved_goals_for_result (cognitive 35): agent._resolved_goals_for_result has cognitive complexity 35 (threshold 15). Drivers by points: if/else 9 (17 pts), boolean chains 12, loops 3, ternaries 2 (3 pts) (nesting depth added 9). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"core_memory/retrieval/agent.py"},"region":{"startLine":139}}}],"partialFingerprints":{"codehealthFindingId/v1":"1ebbdf0647c4e9befab4135903e8888a8ab01843b8f501fc1c2b7b4fc0574767"}},{"ruleId":"D2","level":"warning","message":{"text":"geometry.build_geometry_manifest (cognitive 35): geometry.build_geometry_manifest has cognitive complexity 35 (threshold 15). Drivers by points: boolean chains 17, if/else 6 (11 pts), loops 3, error handling 2, ternaries 1 (2 pts) (nesting depth added 6). 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":"core_memory/runtime/dreamer/geometry.py"},"region":{"startLine":68}}}],"partialFingerprints":{"codehealthFindingId/v1":"26345da123097c76fe656de46a7c9386abbc56d4d7489e798848dd2562916b37"}},{"ruleId":"D2","level":"warning","message":{"text":"progress._evaluate_pair (cognitive 35): progress._evaluate_pair has cognitive complexity 35 (threshold 15). Drivers by points: boolean chains 19, if/else 12, ternaries 3 (4 pts) (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":"core_memory/runtime/goals/progress.py"},"region":{"startLine":231}}}],"partialFingerprints":{"codehealthFindingId/v1":"80525e262f76e0801c5cd4ee7aae59dd82a60af52ed6c592e3d25c1079afa3df"}},{"ruleId":"D2","level":"warning","message":{"text":"promotion._normalize_links (cognitive 35): promotion._normalize_links has cognitive complexity 35 (threshold 15). Drivers by points: if/else 9 (22 pts), loops 3 (8 pts), boolean chains 5 (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":"core_memory/schema/promotion.py"},"region":{"startLine":53}}}],"partialFingerprints":{"codehealthFindingId/v1":"a0e335331a74a872b7bb9d73849522fb069da945905aaf8f128e925ed457a4f0"}},{"ruleId":"D2","level":"warning","message":{"text":"dreamer_bridge._run_soul_proposal_task (cognitive 35): dreamer_bridge._run_soul_proposal_task has cognitive complexity 35 (threshold 15). Drivers by points: boolean chains 27, if/else 6 (7 pts), ternaries 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":"core_memory/soul/dreamer_bridge.py"},"region":{"startLine":421}}}],"partialFingerprints":{"codehealthFindingId/v1":"09daf5185ef38ac446b25226a9859ab6d8b6c05aeeafcf127464e96d663fbc98"}},{"ruleId":"D2","level":"warning","message":{"text":"injection.soul_injection (cognitive 35): injection.soul_injection has cognitive complexity 35 (threshold 15). Drivers by points: if/else 5 (16 pts), boolean chains 11, loops 2 (5 pts), ternaries 1 (3 pts) (nesting depth added 16). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"core_memory/soul/injection.py"},"region":{"startLine":30}}}],"partialFingerprints":{"codehealthFindingId/v1":"2902f23c6b7d186033cb5260d6e5ea5813063fd3edaa5ccf7b39fde8d9c4ddab"}},{"ruleId":"D2","level":"warning","message":{"text":"sync._collect_prune_keep_assoc_ids (cognitive 34): sync._collect_prune_keep_assoc_ids has cognitive complexity 34 (threshold 15). Drivers by points: if/else 10 (16 pts), boolean chains 15, 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":"core_memory/integrations/neo4j/sync.py"},"region":{"startLine":199}}}],"partialFingerprints":{"codehealthFindingId/v1":"6aeca95cabaa45a56f114bdf47f9d1e597f553f4880277e0e873f5ac8c7d79aa"}},{"ruleId":"D2","level":"warning","message":{"text":"store_compaction_ops.uncompact_for_store (cognitive 34): store_compaction_ops.uncompact_for_store has cognitive complexity 34 (threshold 15). Drivers by points: if/else 12 (22 pts), boolean chains 5, ternaries 4 (5 pts), loops 1 (2 pts) (nesting depth added 12). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"core_memory/persistence/store_compaction_ops.py"},"region":{"startLine":86}}}],"partialFingerprints":{"codehealthFindingId/v1":"41f70ae0cbc96633a749e85d9811925777f54b90af2411631bd16825d31f7cb1"}},{"ruleId":"D2","level":"warning","message":{"text":"engine._ensure_turn_creation_update (cognitive 34): engine._ensure_turn_creation_update has cognitive complexity 34 (threshold 15). Drivers by points: if/else 10 (16 pts), boolean chains 14, ternaries 2 (3 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":"core_memory/runtime/engine.py"},"region":{"startLine":483}}}],"partialFingerprints":{"codehealthFindingId/v1":"21782073fa9259a5f0a324e8dd74a55d20926ee8736e88b0fad5427ee683f6c6"}},{"ruleId":"D2","level":"warning","message":{"text":"turn_prep.normalize_turn_request (cognitive 34): turn_prep.normalize_turn_request has cognitive complexity 34 (threshold 15). Drivers by points: boolean chains 20, ternaries 7 (9 pts), if/else 5 (nesting depth added 2). 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":"core_memory/runtime/turn/turn_prep.py"},"region":{"startLine":25}}}],"partialFingerprints":{"codehealthFindingId/v1":"d887c3479cb139f9eff116b3276d93afc0afbe15e486da4c9dce6084ad4ae1de"}},{"ruleId":"D2","level":"warning","message":{"text":"check_architecture_guards.main (cognitive 34): check_architecture_guards.main has cognitive complexity 34 (threshold 15). Drivers by points: if/else 16 (24 pts), boolean chains 9, 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":"scripts/check_architecture_guards.py"},"region":{"startLine":1100}}}],"partialFingerprints":{"codehealthFindingId/v1":"a568d497894e9517d2111331ae15e7346b40add7e70153999bcd62c8ee2bc93d"}},{"ruleId":"D2","level":"warning","message":{"text":"retrieval_planner.plan_retrieval_mode (cognitive 33): retrieval_planner.plan_retrieval_mode has cognitive complexity 33 (threshold 15). Drivers by points: if/else 12 (18 pts), boolean chains 9, loops 3 (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":"core_memory/claim/retrieval_planner.py"},"region":{"startLine":73}}}],"partialFingerprints":{"codehealthFindingId/v1":"ef2e0766ab55c8f9a45ad250782f5e67f275780b7c1c7a3345efc899c25a9237"}},{"ruleId":"D2","level":"warning","message":{"text":"core._normalize_links (cognitive 33): core._normalize_links has cognitive complexity 33 (threshold 15). Drivers by points: if/else 7 (20 pts), loops 3 (8 pts), boolean chains 5 (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":"core_memory/graph/core.py"},"region":{"startLine":141}}}],"partialFingerprints":{"codehealthFindingId/v1":"8e101b98e2dacbae3275f4c4e5269366ad36299c14b0af74789d9153e9c86f00"}},{"ruleId":"D2","level":"warning","message":{"text":"ingest_slack.ingest_slack_handler (cognitive 33): ingest_slack.ingest_slack_handler has cognitive complexity 33 (threshold 15). Drivers by points: boolean chains 13, if/else 7 (11 pts), error handling 3 (5 pts), ternaries 2 (3 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":"core_memory/integrations/mcp/tools/ingest_slack.py"},"region":{"startLine":76}}}],"partialFingerprints":{"codehealthFindingId/v1":"cb1c2d8741cdfaf8e6c3474a9ead373c2a008210f21b0ee065709592f075efb2"}},{"ruleId":"D2","level":"warning","message":{"text":"dreamer_candidate_store.enqueue_contradiction_pressure_candidates (cognitive 33): dreamer_candidate_store.enqueue_contradiction_pressure_candidates has cognitive complexity 33 (threshold 15). Drivers by points: if/else 9 (16 pts), boolean chains 14, loops 2, 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":"core_memory/persistence/dreamer_candidate_store.py"},"region":{"startLine":152}}}],"partialFingerprints":{"codehealthFindingId/v1":"f0515ca7defc847d14f6a6ee7660b9eef1e8cfd8a8a9be11c666b98bd6b39693"}},{"ruleId":"D2","level":"warning","message":{"text":"agent._claim_slots_for_result (cognitive 33): agent._claim_slots_for_result has cognitive complexity 33 (threshold 15). Drivers by points: if/else 5 (10 pts), ternaries 5 (10 pts), boolean chains 7, loops 4 (6 pts) (nesting depth added 12). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"core_memory/retrieval/agent.py"},"region":{"startLine":205}}}],"partialFingerprints":{"codehealthFindingId/v1":"8f557d7b9561f36d5d96e029db3a13caab26736f486a5fb2e9d1925f0988c690"}},{"ruleId":"D2","level":"warning","message":{"text":"causal_recall.build_state_packet (cognitive 33): causal_recall.build_state_packet has cognitive complexity 33 (threshold 15). Drivers by points: ternaries 7 (11 pts), if/else 6 (9 pts), boolean chains 8, loops 4 (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":"core_memory/retrieval/causal_recall.py"},"region":{"startLine":247}}}],"partialFingerprints":{"codehealthFindingId/v1":"048330038383d1ed95a14c6610289b7396f11922cdd91e1f0e2637fd99072e5b"}},{"ruleId":"D2","level":"warning","message":{"text":"research.run_dreamer_research (cognitive 33): research.run_dreamer_research has cognitive complexity 33 (threshold 15). Drivers by points: boolean chains 26, if/else 6, ternaries 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":"core_memory/runtime/dreamer/research.py"},"region":{"startLine":303}}}],"partialFingerprints":{"codehealthFindingId/v1":"a2e7725d4eb8396be156f0662fbca649176ab829bf022b41d31b34ececcf5302"}},{"ruleId":"D2","level":"warning","message":{"text":"assembly_depth.compute_assembly_depth (cognitive 33): assembly_depth.compute_assembly_depth has cognitive complexity 33 (threshold 15). Drivers by points: if/else 8 (12 pts), boolean chains 9, loops 6 (7 pts), ternaries 3 (5 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":"core_memory/soul/assembly_depth.py"},"region":{"startLine":135}}}],"partialFingerprints":{"codehealthFindingId/v1":"7c78d5e940ff26787e5dd9afec6577157ebf859ef05b2893a85e9d072221245f"}},{"ruleId":"D2","level":"warning","message":{"text":"identity_value_signals.detect_identity_value_findings (cognitive 33): identity_value_signals.detect_identity_value_findings has cognitive complexity 33 (threshold 15). Drivers by points: if/else 7 (13 pts), boolean chains 12, loops 6 (8 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":"core_memory/soul/identity_value_signals.py"},"region":{"startLine":74}}}],"partialFingerprints":{"codehealthFindingId/v1":"ce4285207b8f08c40161ebfaa5e675ec7418645adca3a902833f748bc088712c"}},{"ruleId":"D2","level":"warning","message":{"text":"compat.apply_grouped_aliases (cognitive 32): compat.apply_grouped_aliases has cognitive complexity 32 (threshold 15). Drivers by points: if/else 17 (32 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":"core_memory/cli/compat.py"},"region":{"startLine":63}}}],"partialFingerprints":{"codehealthFindingId/v1":"961bff460d2002ee1429aa8a22e13d86a2fa5f9c36e3c0717159b702b4a45fc8"}},{"ruleId":"D2","level":"warning","message":{"text":"recall_payload.run_recall_payload (cognitive 32): recall_payload.run_recall_payload has cognitive complexity 32 (threshold 15). Drivers by points: if/else 11 (14 pts), boolean chains 10, error handling 4 (6 pts), 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":"core_memory/integrations/recall_payload.py"},"region":{"startLine":59}}}],"partialFingerprints":{"codehealthFindingId/v1":"7b02f80447fa14dcbc4dbedb6005818732246656fc503d01d8d5386be278a733"}},{"ruleId":"D2","level":"warning","message":{"text":"entity_merge_flow.apply_entity_merge_for_index (cognitive 32): entity_merge_flow.apply_entity_merge_for_index has cognitive complexity 32 (threshold 15). Drivers by points: boolean chains 15, if/else 8 (12 pts), loops 3, ternaries 1 (2 pts) (nesting depth added 5). To reduce it, name the conditions: bind each compound test to a well-named local or a small predicate function, so the body reads as a sequence of named decisions rather than a chain of operators."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"core_memory/persistence/entity_merge_flow.py"},"region":{"startLine":133}}}],"partialFingerprints":{"codehealthFindingId/v1":"0bb09bfcb3f1eeebe99630e1e90fd75c95b05710011704434cef7630e413b3d7"}},{"ruleId":"D2","level":"warning","message":{"text":"store_autonomy_ops.reinforcement_signals_for_store (cognitive 32): store_autonomy_ops.reinforcement_signals_for_store has cognitive complexity 32 (threshold 15). Drivers by points: boolean chains 13, if/else 6 (12 pts), loops 4 (5 pts), 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":"core_memory/persistence/store_autonomy_ops.py"},"region":{"startLine":6}}}],"partialFingerprints":{"codehealthFindingId/v1":"cd5279b53997c9af86a634e58fecccd5134e24b5d8071d25ce0dc744e7ed8305"}},{"ruleId":"D2","level":"warning","message":{"text":"store_claim_ops.find_canonical_turn_bead_id (cognitive 32): store_claim_ops.find_canonical_turn_bead_id has cognitive complexity 32 (threshold 15). Drivers by points: if/else 10 (16 pts), boolean chains 11, ternaries 2 (4 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":"core_memory/persistence/store_claim_ops.py"},"region":{"startLine":84}}}],"partialFingerprints":{"codehealthFindingId/v1":"a6db12206bea0847466e38750b9d84123c0b301ab5e3750ecfabf1a330d69e5e"}},{"ruleId":"D2","level":"warning","message":{"text":"coverage.judge_association_candidates (cognitive 32): coverage.judge_association_candidates has cognitive complexity 32 (threshold 15). Drivers by points: boolean chains 19, ternaries 4 (5 pts), if/else 4, loops 2 (3 pts), error handling 1 (nesting depth added 2). 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":"core_memory/runtime/associations/coverage.py"},"region":{"startLine":3137}}}],"partialFingerprints":{"codehealthFindingId/v1":"9f19b03d1e66131075d66c02a533d519f546bb183c72db371cfec997a9e74012"}},{"ruleId":"D2","level":"warning","message":{"text":"engine._enforce_structural_invariants (cognitive 32): engine._enforce_structural_invariants has cognitive complexity 32 (threshold 15). Drivers by points: if/else 12 (18 pts), boolean chains 13, 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":"core_memory/runtime/engine.py"},"region":{"startLine":418}}}],"partialFingerprints":{"codehealthFindingId/v1":"f7fc2f5b731f69ab0d6b0dd0e350b0c10d55797be41776cd8c778de18d4322d7"}},{"ruleId":"D2","level":"warning","message":{"text":"progress.run_goal_progress_tasks (cognitive 32): progress.run_goal_progress_tasks has cognitive complexity 32 (threshold 15). Drivers by points: boolean chains 18, if/else 10 (11 pts), ternaries 2, 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":"core_memory/runtime/goals/progress.py"},"region":{"startLine":436}}}],"partialFingerprints":{"codehealthFindingId/v1":"1021a72a3c06ace0f3cdf92295b1f491621ac639ae51e7a93e81ec21688c57db"}},{"ruleId":"D2","level":"warning","message":{"text":"agent_crawler_invoke.invoke_turn_crawler_agent (cognitive 32): agent_crawler_invoke.invoke_turn_crawler_agent has cognitive complexity 32 (threshold 15). Drivers by points: boolean chains 12, if/else 8 (12 pts), ternaries 3 (4 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":"core_memory/runtime/passes/agent_crawler_invoke.py"},"region":{"startLine":20}}}],"partialFingerprints":{"codehealthFindingId/v1":"690172c35335af801b5aa632e3f6b52f0e972ac8f83ac194bcd6bacfe939a440"}},{"ruleId":"D2","level":"warning","message":{"text":"ingress.maybe_emit_finalize_memory_event (cognitive 32): ingress.maybe_emit_finalize_memory_event has cognitive complexity 32 (threshold 15). Drivers by points: boolean chains 14, if/else 9 (12 pts), ternaries 5 (6 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":"core_memory/runtime/turn/ingress.py"},"region":{"startLine":80}}}],"partialFingerprints":{"codehealthFindingId/v1":"c46cbc9d65dfb72305ca249d6f11c4ab5cb84b0178fe4479a8e314f3d9596c47"}},{"ruleId":"D2","level":"warning","message":{"text":"reauthoring.retry_pending_semantic (cognitive 32): reauthoring.retry_pending_semantic has cognitive complexity 32 (threshold 15). Drivers by points: if/else 10 (15 pts), boolean chains 9, error handling 2 (4 pts), 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":"core_memory/runtime/turn/reauthoring.py"},"region":{"startLine":921}}}],"partialFingerprints":{"codehealthFindingId/v1":"74322c198bf873f0bf17e52818df5c719da4057b8246adf72fc9f87dcd464ac1"}},{"ruleId":"D2","level":"warning","message":{"text":"promotion._reinforcement_signals (cognitive 32): promotion._reinforcement_signals has cognitive complexity 32 (threshold 15). Drivers by points: boolean chains 13, if/else 6 (12 pts), loops 4 (5 pts), 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":"core_memory/schema/promotion.py"},"region":{"startLine":81}}}],"partialFingerprints":{"codehealthFindingId/v1":"bee4e3fbb609d2a42cc270722c0867576e2c1195cc95ae722693a2ae3ec5bafb"}},{"ruleId":"D2","level":"warning","message":{"text":"diagnostics.doctor_report (cognitive 31): diagnostics.doctor_report has cognitive complexity 31 (threshold 15). Drivers by points: boolean chains 20, if/else 2 (4 pts), loops 2 (3 pts), ternaries 3, error handling 1 (nesting depth added 3). 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":"core_memory/cli/diagnostics.py"},"region":{"startLine":71}}}],"partialFingerprints":{"codehealthFindingId/v1":"584dcc23e616066c2325b7666e1a9197f08f490072decc38a57bf81df8f9147e"}},{"ruleId":"D2","level":"warning","message":{"text":"junctions.derive_junction_projection (cognitive 31): junctions.derive_junction_projection has cognitive complexity 31 (threshold 15). Drivers by points: if/else 9 (12 pts), boolean chains 11, loops 4 (5 pts), ternaries 3 (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":"core_memory/graph/junctions.py"},"region":{"startLine":323}}}],"partialFingerprints":{"codehealthFindingId/v1":"96c51ae58807164b9d0dfcb4d5dcc5cabc2efb1d162ce99ca63eb529ba45118a"}},{"ruleId":"D2","level":"warning","message":{"text":"api.list_turn_summaries (cognitive 31): api.list_turn_summaries has cognitive complexity 31 (threshold 15). Drivers by points: boolean chains 11, if/else 6 (11 pts), error handling 2 (5 pts), loops 2 (3 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":"core_memory/integrations/api.py"},"region":{"startLine":601}}}],"partialFingerprints":{"codehealthFindingId/v1":"b3a53f87a2b4cf42c22c8ffd97fa67dbb9177675ebcdf531e237c61547d524eb"}},{"ruleId":"D2","level":"warning","message":{"text":"_MCPAuthMiddleware.__call__ (cognitive 31): _MCPAuthMiddleware.__call__ has cognitive complexity 31 (threshold 15). Drivers by points: if/else 9 (24 pts), boolean chains 4, error handling 1 (3 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":"core_memory/integrations/http/server.py"},"region":{"startLine":634}}}],"partialFingerprints":{"codehealthFindingId/v1":"8e44785719c412a89373ea46a175bafe3a23361b2384931791f605fe3e4db594"}},{"ruleId":"D2","level":"warning","message":{"text":"myelination_rewards.emit_myelination_reward_event (cognitive 31): myelination_rewards.emit_myelination_reward_event has cognitive complexity 31 (threshold 15). Drivers by points: boolean chains 14, if/else 10 (14 pts), ternaries 2, 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":"core_memory/persistence/myelination_rewards.py"},"region":{"startLine":236}}}],"partialFingerprints":{"codehealthFindingId/v1":"69614cca4ecc72ee9f703ab2ba8fba06d0908c43a5654b2018d6e0616ba01a8d"}},{"ruleId":"D2","level":"warning","message":{"text":"store_compaction_ops.compact_for_store (cognitive 31): store_compaction_ops.compact_for_store has cognitive complexity 31 (threshold 15). Drivers by points: boolean chains 17, if/else 6 (13 pts), loops 1 (nesting depth added 7). 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":"core_memory/persistence/store_compaction_ops.py"},"region":{"startLine":14}}}],"partialFingerprints":{"codehealthFindingId/v1":"20cfb151ae4699e68998f86647110a195c732461979a8e339699c5fb2c082202"}},{"ruleId":"D2","level":"warning","message":{"text":"identity_value_research.enqueue_identity_value_candidates (cognitive 31): identity_value_research.enqueue_identity_value_candidates has cognitive complexity 31 (threshold 15). Drivers by points: boolean chains 15, if/else 7 (14 pts), loops 2 (nesting depth added 7). 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":"core_memory/runtime/dreamer/identity_value_research.py"},"region":{"startLine":38}}}],"partialFingerprints":{"codehealthFindingId/v1":"c058e6f9adec67146eaec687aa7435341856675fc6e2ae63bbf671c057db3a07"}},{"ruleId":"D2","level":"warning","message":{"text":"external_evidence._validate_external_payload (cognitive 31): external_evidence._validate_external_payload has cognitive complexity 31 (threshold 15). Drivers by points: if/else 12 (21 pts), boolean chains 10 (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":"core_memory/runtime/ingest/external_evidence.py"},"region":{"startLine":372}}}],"partialFingerprints":{"codehealthFindingId/v1":"133b49fa68d2a5323b98e18b96454342b8092651b50a88052d2938caf8a032af"}},{"ruleId":"D2","level":"warning","message":{"text":"check_architecture_guards.check_deterministic_semantic_writers (cognitive 31): check_architecture_guards.check_deterministic_semantic_writers has cognitive complexity 31 (threshold 15). Drivers by points: if/else 11 (20 pts), boolean chains 5, loops 3, ternaries 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":"scripts/check_architecture_guards.py"},"region":{"startLine":806}}}],"partialFingerprints":{"codehealthFindingId/v1":"67d1f7b585c3f160277aa4a02672375709290af91d1d52830fa2a69cef896c15"}},{"ruleId":"D2","level":"warning","message":{"text":"edge_weights.normalize_backend_chain (cognitive 30): edge_weights.normalize_backend_chain has cognitive complexity 30 (threshold 15). Drivers by points: if/else 7 (11 pts), boolean chains 7, error handling 1 (4 pts), loops 2 (4 pts), ternaries 1 (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":"core_memory/graph/edge_weights.py"},"region":{"startLine":149}}}],"partialFingerprints":{"codehealthFindingId/v1":"3ef658acfc1500a272d55505cd9ad18842f4229328ad7e8a401ababf5dd1cb37"}},{"ruleId":"D2","level":"warning","message":{"text":"connector._build_default_branch_doc_push (cognitive 30): connector._build_default_branch_doc_push has cognitive complexity 30 (threshold 15). Drivers by points: if/else 6 (11 pts), boolean chains 10, loops 4 (7 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":"core_memory/integrations/github/connector.py"},"region":{"startLine":170}}}],"partialFingerprints":{"codehealthFindingId/v1":"ec8b1a12185e754af4c89689e2406d9d8e710f30953fdce4d92d49a4e503480a"}},{"ruleId":"D2","level":"warning","message":{"text":"goal_lifecycle_v2.transition_goal_state_for_store (cognitive 30): goal_lifecycle_v2.transition_goal_state_for_store has cognitive complexity 30 (threshold 15). Drivers by points: if/else 14 (15 pts), boolean chains 13, 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."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"core_memory/persistence/goal_lifecycle_v2.py"},"region":{"startLine":77}}}],"partialFingerprints":{"codehealthFindingId/v1":"81e9a41b2bcb69c0ec15a926de9cc4f5ced72030fcdca98728978acd091d2d43"}},{"ruleId":"D2","level":"warning","message":{"text":"store_management_ops.remove_beads_for_store (cognitive 30): store_management_ops.remove_beads_for_store has cognitive complexity 30 (threshold 15). Drivers by points: if/else 14 (16 pts), boolean chains 13, loops 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":"core_memory/persistence/store_management_ops.py"},"region":{"startLine":322}}}],"partialFingerprints":{"codehealthFindingId/v1":"a0fcb4ca6aaad01235575872280e65d797ca127893289e0fb4ac041cb63391ba"}},{"ruleId":"D2","level":"warning","message":{"text":"tension_meter.compute_tension_resolution_meter (cognitive 30): tension_meter.compute_tension_resolution_meter has cognitive complexity 30 (threshold 15). Drivers by points: boolean chains 13, if/else 9 (12 pts), ternaries 3, 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":"core_memory/runtime/observability/tension_meter.py"},"region":{"startLine":108}}}],"partialFingerprints":{"codehealthFindingId/v1":"dccc09ae4e341ad3279c41c8a900cb25b574dfe680923931ac5ee0d0ef809307"}},{"ruleId":"D2","level":"warning","message":{"text":"session_start_flow.build_session_start_snapshot (cognitive 30): session_start_flow.build_session_start_snapshot has cognitive complexity 30 (threshold 15). Drivers by points: boolean chains 13, if/else 8 (11 pts), loops 4 (5 pts), 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":"core_memory/runtime/session/session_start_flow.py"},"region":{"startLine":31}}}],"partialFingerprints":{"codehealthFindingId/v1":"21e4c609876de7abc6cdb0d871911f1ac2ce848d02cff06f931bb38076a5a45b"}},{"ruleId":"D2","level":"warning","message":{"text":"summary._tension_light_cone_reports (cognitive 30): summary._tension_light_cone_reports has cognitive complexity 30 (threshold 15). Drivers by points: boolean chains 16, if/else 6 (9 pts), error handling 1 (2 pts), ternaries 1 (2 pts), loops 1 (nesting depth added 5). To reduce it, name the conditions: bind each compound test to a well-named local or a small predicate function, so the body reads as a sequence of named decisions rather than a chain of operators."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"core_memory/soul/summary.py"},"region":{"startLine":527}}}],"partialFingerprints":{"codehealthFindingId/v1":"cbca6dc7b93e16fdbb2ab19fb93c1b5515885010727a52203f779bae242ea30c"}},{"ruleId":"D2","level":"warning","message":{"text":"extraction.extract_claims (cognitive 29): extraction.extract_claims has cognitive complexity 29 (threshold 15). Drivers by points: if/else 7 (20 pts), boolean chains 6, 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":"core_memory/claim/extraction.py"},"region":{"startLine":248}}}],"partialFingerprints":{"codehealthFindingId/v1":"91289f4d2f3b7a47b681278878e97074c31bd862462aa161f8200e43137ddd37"}},{"ruleId":"D2","level":"warning","message":{"text":"root_cause._claim_refs (cognitive 29): root_cause._claim_refs has cognitive complexity 29 (threshold 15). Drivers by points: if/else 5 (14 pts), loops 4 (6 pts), ternaries 1 (5 pts), boolean chains 4 (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":"core_memory/graph/root_cause.py"},"region":{"startLine":889}}}],"partialFingerprints":{"codehealthFindingId/v1":"0bc6e46ef925e6110f66238dc945dd46c0c5a79087ec9b5308fd82ee9bb40de1"}},{"ruleId":"D2","level":"warning","message":{"text":"worldlines._entity_worldlines (cognitive 29): worldlines._entity_worldlines has cognitive complexity 29 (threshold 15). Drivers by points: if/else 5 (13 pts), loops 7 (10 pts), boolean chains 4, ternaries 2 (nesting depth added 11). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"core_memory/graph/worldlines.py"},"region":{"startLine":111}}}],"partialFingerprints":{"codehealthFindingId/v1":"4763a9756ec077551fbd3653c72bc60f66c30541dc58721eff46590f0c894f0f"}},{"ruleId":"D2","level":"warning","message":{"text":"store_management_ops.deactivate_association_for_store (cognitive 29): store_management_ops.deactivate_association_for_store has cognitive complexity 29 (threshold 15). Drivers by points: boolean chains 14, if/else 10 (14 pts), loops 1 (nesting depth added 4). 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":"core_memory/persistence/store_management_ops.py"},"region":{"startLine":785}}}],"partialFingerprints":{"codehealthFindingId/v1":"4677db6cbc2c25bd163b1ee6049e60e1b500c825f2ef01f8fbe94a9830b01b10"}},{"ruleId":"D2","level":"warning","message":{"text":"association_inference_v21.validate_and_normalize_inference_payload (cognitive 29): association_inference_v21.validate_and_normalize_inference_payload has cognitive complexity 29 (threshold 15). Drivers by points: boolean chains 16, if/else 9 (12 pts), ternaries 1 (nesting depth added 3). 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":"core_memory/policy/association_inference_v21.py"},"region":{"startLine":129}}}],"partialFingerprints":{"codehealthFindingId/v1":"8c2e22fce14b20fcd25913439edd21aeee31a67050ec7024845e7d8b26e4d613"}},{"ruleId":"D2","level":"warning","message":{"text":"roadmap_planner.plan_over_roadmap (cognitive 29): roadmap_planner.plan_over_roadmap has cognitive complexity 29 (threshold 15). Drivers by points: if/else 14 (16 pts), boolean chains 8, ternaries 3 (4 pts), loops 1 (nesting depth added 3). To reduce it, split the body: most of this score is breadth rather than depth \u2014 checks laid out side by side rather than stacked \u2014 so group the statements between the checks into named steps and move each step into its own function. Some of it IS depth: where a check sits inside another whose only job is to reach it, merge the two into one condition, and where an else follows a branch that already returns, drop the trailing else and let the rest of the body continue at one level."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"core_memory/retrieval/roadmap_planner.py"},"region":{"startLine":657}}}],"partialFingerprints":{"codehealthFindingId/v1":"bf3ce53208d7544339de8df29268a44cf943a90ff27d1c9338a2f2928a3d8a66"}},{"ruleId":"D2","level":"warning","message":{"text":"coverage._claim_slots (cognitive 29): coverage._claim_slots has cognitive complexity 29 (threshold 15). Drivers by points: if/else 5 (18 pts), loops 4 (11 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":"core_memory/runtime/associations/coverage.py"},"region":{"startLine":1001}}}],"partialFingerprints":{"codehealthFindingId/v1":"f50baaa1594e2a1e5f254c2d442ff77493b4a47ae1e289874a16f9b51f96a89f"}},{"ruleId":"D2","level":"warning","message":{"text":"analysis._load_seen_state (cognitive 29): analysis._load_seen_state has cognitive complexity 29 (threshold 15). Drivers by points: if/else 9 (17 pts), boolean chains 6, loops 3 (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":"core_memory/runtime/dreamer/analysis.py"},"region":{"startLine":36}}}],"partialFingerprints":{"codehealthFindingId/v1":"4dfcd0e3459ca42da7102f00ae6dea379bd66dfdb82d4c27a7a96f3fe018a59a"}},{"ruleId":"D2","level":"warning","message":{"text":"analysis._structural_signal_pack (cognitive 29): analysis._structural_signal_pack has cognitive complexity 29 (threshold 15). Drivers by points: boolean chains 22, if/else 7. 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":"core_memory/runtime/dreamer/analysis.py"},"region":{"startLine":204}}}],"partialFingerprints":{"codehealthFindingId/v1":"d200c39faf9d224c0fe046b30cbd46597c777f2815dd336d24c9201777731789"}},{"ruleId":"D2","level":"warning","message":{"text":"goal_lifecycle.resolve_goals_for_turn (cognitive 29): goal_lifecycle.resolve_goals_for_turn has cognitive complexity 29 (threshold 15). Drivers by points: if/else 12 (17 pts), boolean chains 10, 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":"core_memory/runtime/session/goal_lifecycle.py"},"region":{"startLine":51}}}],"partialFingerprints":{"codehealthFindingId/v1":"bb3b756c51ae5d729ddc078de4588912547f8c55dda2c5648f5820c84cf675b8"}},{"ruleId":"D2","level":"warning","message":{"text":"retrieval_planner._active_slot_hints (cognitive 28): retrieval_planner._active_slot_hints has cognitive complexity 28 (threshold 15). Drivers by points: if/else 9 (19 pts), boolean chains 5, loops 2 (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":"core_memory/claim/retrieval_planner.py"},"region":{"startLine":43}}}],"partialFingerprints":{"codehealthFindingId/v1":"d7e1ddc2fbb2511c45b2f0797c7d9ed80721507c5908a85466721078d14ef34a"}},{"ruleId":"D2","level":"warning","message":{"text":"retrieval.expand_query_with_entities (cognitive 28): retrieval.expand_query_with_entities has cognitive complexity 28 (threshold 15). Drivers by points: if/else 7 (13 pts), boolean chains 11, loops 3 (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":"core_memory/entity/retrieval.py"},"region":{"startLine":63}}}],"partialFingerprints":{"codehealthFindingId/v1":"ac19b295f08a93c7babeef253a73591b1b9fd0c302501bcd610532d17d54cf91"}},{"ruleId":"D2","level":"warning","message":{"text":"sync._dedupe_projection (cognitive 28): sync._dedupe_projection has cognitive complexity 28 (threshold 15). Drivers by points: boolean chains 14, if/else 7 (12 pts), loops 2 (nesting depth added 5). To reduce it, name the conditions: bind each compound test to a well-named local or a small predicate function, so the body reads as a sequence of named decisions rather than a chain of operators."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"core_memory/integrations/neo4j/sync.py"},"region":{"startLine":246}}}],"partialFingerprints":{"codehealthFindingId/v1":"7131e62971a0eed8d45bb17b7ac849581b88753b89702ce2419aac9af52eb6bf"}},{"ruleId":"D2","level":"warning","message":{"text":"store_management_ops._split_source_selector (cognitive 28): store_management_ops._split_source_selector has cognitive complexity 28 (threshold 15). Drivers by points: if/else 9 (18 pts), boolean chains 4, loops 2 (4 pts), ternaries 2 (nesting depth added 11). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"core_memory/persistence/store_management_ops.py"},"region":{"startLine":75}}}],"partialFingerprints":{"codehealthFindingId/v1":"fc7929b4cbd9b160707b6f615caca7bb8f0be9d3c62587ba9df783b3cc2dbeb6"}},{"ruleId":"D2","level":"warning","message":{"text":"chunk_evidence._referenced_turn_records (cognitive 28): chunk_evidence._referenced_turn_records has cognitive complexity 28 (threshold 15). Drivers by points: if/else 6 (14 pts), error handling 3 (7 pts), loops 2 (3 pts), ternaries 1 (3 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":"core_memory/retrieval/chunk_evidence.py"},"region":{"startLine":68}}}],"partialFingerprints":{"codehealthFindingId/v1":"05198a5ce2312b04e6a1c16d596a9f569e0075d358a34916dba4c2499bd36d98"}},{"ruleId":"D2","level":"warning","message":{"text":"canonical._locomo_dia_ids_from_bead (cognitive 28): canonical._locomo_dia_ids_from_bead has cognitive complexity 28 (threshold 15). Drivers by points: if/else 7 (16 pts), boolean chains 8, loops 3 (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":"core_memory/retrieval/pipeline/canonical.py"},"region":{"startLine":558}}}],"partialFingerprints":{"codehealthFindingId/v1":"305752e5d531694f9557d1128ba774fcc87750e50093a91c724f328a8d20e524"}},{"ruleId":"D2","level":"warning","message":{"text":"coverage.enqueue_goal_progress_candidate (cognitive 28): coverage.enqueue_goal_progress_candidate has cognitive complexity 28 (threshold 15). Drivers by points: if/else 14, boolean chains 13, error handling 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":"core_memory/runtime/associations/coverage.py"},"region":{"startLine":615}}}],"partialFingerprints":{"codehealthFindingId/v1":"a0d184d1c02315c5b0d0ab6221207ef4a30865bd4c06817cf622de6d9ea14712"}},{"ruleId":"D2","level":"warning","message":{"text":"coverage._write_association_if_missing (cognitive 28): coverage._write_association_if_missing has cognitive complexity 28 (threshold 15). Drivers by points: boolean chains 23, if/else 5. To reduce it, name the conditions: bind each compound test to a well-named local or a small predicate function, so the body reads as a sequence of named decisions rather than a chain of operators."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"core_memory/runtime/associations/coverage.py"},"region":{"startLine":1271}}}],"partialFingerprints":{"codehealthFindingId/v1":"02e9eb6ccdb7e4e4c023658ca44324b0bbbb7522903facf51175e3d578ea39cd"}},{"ruleId":"D2","level":"warning","message":{"text":"self_model_drift.compute_self_model_drift (cognitive 28): self_model_drift.compute_self_model_drift has cognitive complexity 28 (threshold 15). Drivers by points: boolean chains 13, if/else 9 (13 pts), error handling 1, loops 1 (nesting depth added 4). 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":"core_memory/runtime/observability/self_model_drift.py"},"region":{"startLine":129}}}],"partialFingerprints":{"codehealthFindingId/v1":"4d55655ff7fdd786d21654a1c52a365a390e6efd3731a1412114bc72c435e439"}},{"ruleId":"D2","level":"warning","message":{"text":"compaction_queue.drain_compaction_queue (cognitive 28): compaction_queue.drain_compaction_queue has cognitive complexity 28 (threshold 15). Drivers by points: boolean chains 16, if/else 7 (11 pts), loops 1 (nesting depth added 4). 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":"core_memory/runtime/queue/compaction_queue.py"},"region":{"startLine":122}}}],"partialFingerprints":{"codehealthFindingId/v1":"ec999f44a8b8801dafd00e721efd4ce1a4fbcbd198b33b0b71659f7849ed93f1"}},{"ruleId":"D2","level":"warning","message":{"text":"transcript_ingest._group_envelopes (cognitive 28): transcript_ingest._group_envelopes has cognitive complexity 28 (threshold 15). Drivers by points: boolean chains 11, if/else 5 (9 pts), ternaries 3 (6 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":"core_memory/transcript_ingest.py"},"region":{"startLine":104}}}],"partialFingerprints":{"codehealthFindingId/v1":"8ec9505c14ce532823873e9377755c251760fd2b40bb3b4fd8a960c14478e7e4"}},{"ruleId":"D2","level":"warning","message":{"text":"register (cognitive 28): register has cognitive complexity 28 (threshold 15). Drivers by points: boolean chains 75, if/else 41 (57 pts), ternaries 22, error handling 14 (20 pts), loops 9 (10 pts), other 6 (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":"plugins/openclaw-core-memory-bridge/index.js"},"region":{"startLine":19}}}],"partialFingerprints":{"codehealthFindingId/v1":"b19c0fb23e2c2a1ea7f45a0635ace3f89d49296350781b9bcd61ffbbf4e2c206"}},{"ruleId":"D2","level":"warning","message":{"text":"quarantine.write_quarantine (cognitive 27): quarantine.write_quarantine has cognitive complexity 27 (threshold 15). Drivers by points: if/else 6 (9 pts), boolean chains 7, loops 4 (7 pts), error handling 1 (3 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":"core_memory/association/quarantine.py"},"region":{"startLine":37}}}],"partialFingerprints":{"codehealthFindingId/v1":"419055b6b2712737799d29a1c76d1cada6ce7ef34e90202dce045a2edc35261f"}},{"ruleId":"D2","level":"warning","message":{"text":"answer_policy.decide_answer_outcome (cognitive 27): answer_policy.decide_answer_outcome has cognitive complexity 27 (threshold 15). Drivers by points: boolean chains 20, if/else 6, ternaries 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":"core_memory/claim/answer_policy.py"},"region":{"startLine":22}}}],"partialFingerprints":{"codehealthFindingId/v1":"7e0e04e9792a1f0732b68f3e7610cb8b15ee46f92b5065d83fee5f152e004c1f"}},{"ruleId":"D2","level":"warning","message":{"text":"sync._collect_projection (cognitive 27): sync._collect_projection has cognitive complexity 27 (threshold 15). Drivers by points: if/else 8 (13 pts), boolean chains 11, loops 2, 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":"core_memory/integrations/neo4j/sync.py"},"region":{"startLine":151}}}],"partialFingerprints":{"codehealthFindingId/v1":"8ba8a33bb71b9fbaa61bf09d94aaebc07c5de88382613a1ebe1d9590297c4df4"}},{"ruleId":"D2","level":"warning","message":{"text":"hosted_capture_bridge.process_hosted_capture_event (cognitive 27): hosted_capture_bridge.process_hosted_capture_event has cognitive complexity 27 (threshold 15). Drivers by points: boolean chains 12, if/else 7, error handling 3 (4 pts), ternaries 3 (4 pts) (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":"core_memory/integrations/openclaw/hosted_capture_bridge.py"},"region":{"startLine":186}}}],"partialFingerprints":{"codehealthFindingId/v1":"1bb66526fb609c3a8b248acf90c787472c164c53e9674d68377fb4d189529cd7"}},{"ruleId":"D2","level":"warning","message":{"text":"promotion_service.decide_promotion_for_store (cognitive 27): promotion_service.decide_promotion_for_store has cognitive complexity 27 (threshold 15). Drivers by points: boolean chains 16, if/else 10 (11 pts) (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":"core_memory/persistence/promotion_service.py"},"region":{"startLine":155}}}],"partialFingerprints":{"codehealthFindingId/v1":"e672a4edea23de686f4060edf597e5479e7a1c6240ea0d1011afe7613ddd5122"}},{"ruleId":"D2","level":"warning","message":{"text":"store_query.query_for_store (cognitive 27): store_query.query_for_store has cognitive complexity 27 (threshold 15). Drivers by points: if/else 10 (20 pts), boolean chains 6, 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":"core_memory/persistence/store_query.py"},"region":{"startLine":8}}}],"partialFingerprints":{"codehealthFindingId/v1":"b7faa697e19c003733af2faf3e830d6617a2ce1823ac1784530f1502ec0fd847"}},{"ruleId":"D2","level":"warning","message":{"text":"causal_recall.attach_causal_recall_pipeline (cognitive 27): causal_recall.attach_causal_recall_pipeline has cognitive complexity 27 (threshold 15). Drivers by points: if/else 10 (15 pts), boolean chains 10, 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":"core_memory/retrieval/causal_recall.py"},"region":{"startLine":521}}}],"partialFingerprints":{"codehealthFindingId/v1":"7de51b59ea7ede0c4c8f342e406f6c4434dba622219ef56a7fbc752259d7f60e"}},{"ruleId":"D2","level":"warning","message":{"text":"roadmap_planner._shortest_stitched_path (cognitive 27): roadmap_planner._shortest_stitched_path has cognitive complexity 27 (threshold 15). Drivers by points: if/else 9 (20 pts), loops 4 (5 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":"core_memory/retrieval/roadmap_planner.py"},"region":{"startLine":441}}}],"partialFingerprints":{"codehealthFindingId/v1":"0d44178c777c0b6076f3c7fd3c27bf9132bfcafdad27daa0b872227a2147528f"}},{"ruleId":"D2","level":"warning","message":{"text":"semantic_index.semantic_doctor (cognitive 27): semantic_index.semantic_doctor has cognitive complexity 27 (threshold 15). Drivers by points: boolean chains 15, if/else 8, error handling 1 (2 pts), ternaries 2 (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":"core_memory/retrieval/semantic_index.py"},"region":{"startLine":452}}}],"partialFingerprints":{"codehealthFindingId/v1":"ec15f8925ebbe132c4c78ecfb4868697a73510586714f686302d0e6195ff1ce2"}},{"ruleId":"D2","level":"warning","message":{"text":"visible_corpus.build_visible_corpus (cognitive 27): visible_corpus.build_visible_corpus has cognitive complexity 27 (threshold 15). Drivers by points: if/else 7 (16 pts), boolean chains 4, loops 3 (4 pts), error handling 1 (3 pts) (nesting depth added 12). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"core_memory/retrieval/visible_corpus.py"},"region":{"startLine":64}}}],"partialFingerprints":{"codehealthFindingId/v1":"9feb1b70c2140b901c066e2f2af72e7960eb3feea4efb9ecce2e62ebfed01519"}},{"ruleId":"D2","level":"warning","message":{"text":"convergence.detect_worldline_convergence (cognitive 27): convergence.detect_worldline_convergence has cognitive complexity 27 (threshold 15). Drivers by points: if/else 8 (12 pts), loops 7 (10 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":"core_memory/runtime/dreamer/convergence.py"},"region":{"startLine":46}}}],"partialFingerprints":{"codehealthFindingId/v1":"656cf146e63801710b00e42677094e2faa5e94a233997c42c8729c0466d8bebc"}},{"ruleId":"D2","level":"warning","message":{"text":"eval._label_summary (cognitive 27): eval._label_summary has cognitive complexity 27 (threshold 15). Drivers by points: boolean chains 18, if/else 4 (7 pts), loops 2 (nesting depth added 3). 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":"core_memory/runtime/dreamer/eval.py"},"region":{"startLine":204}}}],"partialFingerprints":{"codehealthFindingId/v1":"8273780931cb4041b02221d04c8a6d3da05d4b4a01efff277788d58f4944b768"}},{"ruleId":"D2","level":"warning","message":{"text":"projection.compute_future_projections (cognitive 27): projection.compute_future_projections has cognitive complexity 27 (threshold 15). Drivers by points: boolean chains 13, if/else 5 (8 pts), loops 4 (6 pts) (nesting depth added 5). To reduce it, name the conditions: bind each compound test to a well-named local or a small predicate function, so the body reads as a sequence of named decisions rather than a chain of operators."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"core_memory/runtime/dreamer/projection.py"},"region":{"startLine":159}}}],"partialFingerprints":{"codehealthFindingId/v1":"95cd2b08c1f0dc9ae85cf0646a5495116ff839ae6d287a6b9ae2598e7e9b83bb"}},{"ruleId":"D2","level":"warning","message":{"text":"semantic_state.mark_semantic_write_state (cognitive 27): semantic_state.mark_semantic_write_state has cognitive complexity 27 (threshold 15). Drivers by points: boolean chains 22, if/else 4, ternaries 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":"core_memory/runtime/turn/semantic_state.py"},"region":{"startLine":85}}}],"partialFingerprints":{"codehealthFindingId/v1":"26f05b71458f85fc060b3cdfb1e96b7dad48b3e1d4c8602e61eb5807f1154ba2"}},{"ruleId":"D2","level":"warning","message":{"text":"slo.association_slo_report (cognitive 26): slo.association_slo_report has cognitive complexity 26 (threshold 15). Drivers by points: boolean chains 15, if/else 7 (9 pts), loops 1, ternaries 1 (nesting depth added 2). 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":"core_memory/association/slo.py"},"region":{"startLine":65}}}],"partialFingerprints":{"codehealthFindingId/v1":"3273881f9eaef85ba4b628dfeb342e3b4d55243083fbf0ef1011a7df06590912"}},{"ruleId":"D2","level":"warning","message":{"text":"CoreMemoryRetriever._get_relevant_documents (cognitive 26): CoreMemoryRetriever._get_relevant_documents has cognitive complexity 26 (threshold 15). Drivers by points: if/else 8 (15 pts), boolean chains 10, 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":"core_memory/integrations/langchain/retriever.py"},"region":{"startLine":67}}}],"partialFingerprints":{"codehealthFindingId/v1":"5e00141b0b1e2545e283ab867a8f5fd413653fad4d2dfb8c67b4cb5d5502d072"}},{"ruleId":"D2","level":"warning","message":{"text":"agent._normalize_request (cognitive 26): agent._normalize_request has cognitive complexity 26 (threshold 15). Drivers by points: if/else 10 (13 pts), boolean chains 11, ternaries 2 (nesting depth added 3). To reduce it, split the body: most of this score is breadth rather than depth \u2014 checks laid out side by side rather than stacked \u2014 so group the statements between the checks into named steps and move each step into its own function. Some of it IS depth: where a check sits inside another whose only job is to reach it, merge the two into one condition, and where an else follows a branch that already returns, drop the trailing else and let the rest of the body continue at one level."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"core_memory/retrieval/agent.py"},"region":{"startLine":376}}}],"partialFingerprints":{"codehealthFindingId/v1":"b5ebf02ae0cc766d5f281ca3dc7a3c174ab91d57c75e858f4cec682a7319633d"}},{"ruleId":"D2","level":"warning","message":{"text":"rerank.rerank_candidates (cognitive 26): rerank.rerank_candidates has cognitive complexity 26 (threshold 15). Drivers by points: ternaries 5 (10 pts), boolean chains 9, if/else 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":"core_memory/retrieval/rerank.py"},"region":{"startLine":221}}}],"partialFingerprints":{"codehealthFindingId/v1":"50ccc0ca13878e11d35b9306b4712b287eef86f4ecaa04f5e33bfcb8b152677b"}},{"ruleId":"D2","level":"warning","message":{"text":"roadmap_planner._states_for_alternative (cognitive 26): roadmap_planner._states_for_alternative has cognitive complexity 26 (threshold 15). Drivers by points: if/else 8 (18 pts), boolean chains 3, loops 2 (3 pts), ternaries 2 (nesting depth added 11). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"core_memory/retrieval/roadmap_planner.py"},"region":{"startLine":306}}}],"partialFingerprints":{"codehealthFindingId/v1":"af8f94dc5f4a9ef9cd3bdac1995772828bf96ff9ccc9c323ae8f8732153de169"}},{"ruleId":"D2","level":"warning","message":{"text":"jobs.run_async_jobs (cognitive 26): jobs.run_async_jobs has cognitive complexity 26 (threshold 15). Drivers by points: if/else 11 (17 pts), boolean chains 5, error handling 3 (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":"core_memory/runtime/queue/jobs.py"},"region":{"startLine":287}}}],"partialFingerprints":{"codehealthFindingId/v1":"fecf4d29cdb0a123035d2300e18b2feec5acc6d10cb02fdd77cc928801573e69"}},{"ruleId":"D2","level":"warning","message":{"text":"resolver.resolve_all_current_state (cognitive 25): resolver.resolve_all_current_state has cognitive complexity 25 (threshold 15). Drivers by points: if/else 6 (11 pts), ternaries 3 (6 pts), boolean chains 5, loops 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":"core_memory/claim/resolver.py"},"region":{"startLine":17}}}],"partialFingerprints":{"codehealthFindingId/v1":"4feb9634bc895842da4577dbb5f6f652eecef19f2746c6dc900079f1037fb95c"}},{"ruleId":"D2","level":"warning","message":{"text":"diagnostics.simple_recall_fallback (cognitive 25): diagnostics.simple_recall_fallback has cognitive complexity 25 (threshold 15). Drivers by points: boolean chains 17, if/else 3 (4 pts), ternaries 1 (3 pts), loops 1 (nesting depth added 3). 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":"core_memory/cli/diagnostics.py"},"region":{"startLine":170}}}],"partialFingerprints":{"codehealthFindingId/v1":"16541777b49c9e7da7e2ec5239415644b6d3e39eff546142ef1adec076739f96"}},{"ruleId":"D2","level":"warning","message":{"text":"retrieval.infer_query_entity_context (cognitive 25): retrieval.infer_query_entity_context has cognitive complexity 25 (threshold 15). Drivers by points: if/else 6 (13 pts), boolean chains 7, loops 4 (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":"core_memory/entity/retrieval.py"},"region":{"startLine":17}}}],"partialFingerprints":{"codehealthFindingId/v1":"27949dc0c6f5faf0e62e031f5f4ff3ba95856f5535d8082f845d9df8594e0092"}},{"ruleId":"D2","level":"warning","message":{"text":"store_management_ops.remove_source_beads_for_store (cognitive 25): store_management_ops.remove_source_beads_for_store has cognitive complexity 25 (threshold 15). Drivers by points: boolean chains 12, if/else 9 (11 pts), ternaries 2 (nesting depth added 2). To reduce it, split the body: most of this score is breadth rather than depth \u2014 checks laid out side by side rather than stacked \u2014 so group the statements between the checks into named steps and move each step into its own function. Some of it IS depth: where a check sits inside another whose only job is to reach it, merge the two into one condition."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"core_memory/persistence/store_management_ops.py"},"region":{"startLine":474}}}],"partialFingerprints":{"codehealthFindingId/v1":"2fd46d6697a916e3ea89dbee194968a4cc3871b2154294789991ee1f8da7eddf"}},{"ruleId":"D2","level":"warning","message":{"text":"store_projection_ops.rebuild_index_projection_from_sessions_for_store (cognitive 25): store_projection_ops.rebuild_index_projection_from_sessions_for_store has cognitive complexity 25 (threshold 15). Drivers by points: if/else 4 (10 pts), boolean chains 7, loops 3 (5 pts), error handling 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":"core_memory/persistence/store_projection_ops.py"},"region":{"startLine":11}}}],"partialFingerprints":{"codehealthFindingId/v1":"8bf281dc1487d4eaf2ca2ed5de28e7c297952939c8b1d0c544fd95f5dd4638b1"}},{"ruleId":"D2","level":"warning","message":{"text":"bead_judge._normalize_judged_fields (cognitive 25): bead_judge._normalize_judged_fields has cognitive complexity 25 (threshold 15). Drivers by points: boolean chains 14, if/else 6 (9 pts), loops 1, ternaries 1 (nesting depth added 3). 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":"core_memory/policy/bead_judge.py"},"region":{"startLine":371}}}],"partialFingerprints":{"codehealthFindingId/v1":"cdf97c3d8184a9067768d75337f4c9b9d0a28459351315e686778ab12514503b"}},{"ruleId":"D2","level":"warning","message":{"text":"pipeline._normalize_search_request (cognitive 25): pipeline._normalize_search_request has cognitive complexity 25 (threshold 15). Drivers by points: boolean chains 22, ternaries 3. 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":"core_memory/retrieval/pipeline/__init__.py"},"region":{"startLine":25}}}],"partialFingerprints":{"codehealthFindingId/v1":"c0628f1d2371bf4d9abad5645af1b4b5cee86a81e24af3c326c4978e548105c2"}},{"ruleId":"D2","level":"warning","message":{"text":"canonical._to_anchor (cognitive 25): canonical._to_anchor has cognitive complexity 25 (threshold 15). Drivers by points: boolean chains 24, ternaries 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":"core_memory/retrieval/pipeline/canonical.py"},"region":{"startLine":596}}}],"partialFingerprints":{"codehealthFindingId/v1":"e8d0f827eee3e75b02f43740753c74430903447d909bafd784f41f2360178d22"}},{"ruleId":"D2","level":"warning","message":{"text":"query_norm.resolve_query_anchors (cognitive 25): query_norm.resolve_query_anchors has cognitive complexity 25 (threshold 15). Drivers by points: if/else 5 (12 pts), boolean chains 9, loops 3 (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":"core_memory/retrieval/query_norm.py"},"region":{"startLine":106}}}],"partialFingerprints":{"codehealthFindingId/v1":"0089cf4fad2fee0091a2b3fa7187e4e15ea828cc2dfd3e5c0d1e9449ab2ce6ac"}},{"ruleId":"D2","level":"warning","message":{"text":"roadmap_planner._fallback (cognitive 25): roadmap_planner._fallback has cognitive complexity 25 (threshold 15). Drivers by points: boolean chains 11, ternaries 6, if/else 3 (5 pts), loops 2 (3 pts) (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":"core_memory/retrieval/roadmap_planner.py"},"region":{"startLine":511}}}],"partialFingerprints":{"codehealthFindingId/v1":"9e6a48d49a6068e0a69819537e5efc1b84780455b4f8116d5c6c0abe0d8feee2"}},{"ruleId":"D2","level":"warning","message":{"text":"seed_backfill.run_seed_quality_backfill (cognitive 25): seed_backfill.run_seed_quality_backfill has cognitive complexity 25 (threshold 15). Drivers by points: if/else 9 (16 pts), boolean chains 4, loops 2 (3 pts), error handling 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":"core_memory/runtime/hygiene/seed_backfill.py"},"region":{"startLine":96}}}],"partialFingerprints":{"codehealthFindingId/v1":"ca78489c7d31cd8a0bbfbe0ae84bc33ad3038036ae5546a8d0ba19b1dd3da294"}},{"ruleId":"D2","level":"warning","message":{"text":"roadmap.edge_cost_row (cognitive 24): roadmap.edge_cost_row has cognitive complexity 24 (threshold 15). Drivers by points: boolean chains 19, if/else 4, loops 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":"core_memory/graph/roadmap.py"},"region":{"startLine":229}}}],"partialFingerprints":{"codehealthFindingId/v1":"3551ba4a40773114856c4034b2f97de66a98c2c9998cc5ac4b4f5ac5d4782474"}},{"ruleId":"D2","level":"warning","message":{"text":"typed_read.query_contradictions (cognitive 24): typed_read.query_contradictions has cognitive complexity 24 (threshold 15). Drivers by points: boolean chains 15, if/else 5 (8 pts), loops 1 (nesting depth added 3). 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":"core_memory/integrations/mcp/typed_read.py"},"region":{"startLine":288}}}],"partialFingerprints":{"codehealthFindingId/v1":"5781508d2d9417dcaeaa543cbf99bd4abcfdc026c3749205dc0b468aedd5cb50"}},{"ruleId":"D2","level":"warning","message":{"text":"migration.backfill_bead_session_ids (cognitive 24): migration.backfill_bead_session_ids has cognitive complexity 24 (threshold 15). Drivers by points: if/else 6 (16 pts), boolean chains 5, loops 2 (3 pts) (nesting depth added 11). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"core_memory/integrations/migration.py"},"region":{"startLine":14}}}],"partialFingerprints":{"codehealthFindingId/v1":"26db23182649010adca6db065ec9cef2488b6c953b15bcc9440cb69cf0e13919"}},{"ruleId":"D2","level":"warning","message":{"text":"onboard.harden_openclaw_plugin_config (cognitive 24): onboard.harden_openclaw_plugin_config has cognitive complexity 24 (threshold 15). Drivers by points: if/else 9, boolean chains 6, ternaries 6, error handling 2 (3 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":"core_memory/integrations/openclaw/onboard.py"},"region":{"startLine":39}}}],"partialFingerprints":{"codehealthFindingId/v1":"276960dbe8f07f26ada92de1d09fb5245dd7459cfc906e9b56706e0bf40460a2"}},{"ruleId":"D2","level":"warning","message":{"text":"promotion_service.decide_session_promotion_states_for_store (cognitive 24): promotion_service.decide_session_promotion_states_for_store has cognitive complexity 24 (threshold 15). Drivers by points: boolean chains 8, if/else 5 (8 pts), ternaries 2 (6 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":"core_memory/persistence/promotion_service.py"},"region":{"startLine":454}}}],"partialFingerprints":{"codehealthFindingId/v1":"df38ce635d27caf4c8d5147e96b99ca666096e6f712e47d0d65592db7a454f5b"}},{"ruleId":"D2","level":"warning","message":{"text":"store_reporting.metrics_report_for_store (cognitive 24): store_reporting.metrics_report_for_store has cognitive complexity 24 (threshold 15). Drivers by points: boolean chains 9, if/else 5 (8 pts), error handling 1 (3 pts), ternaries 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":"core_memory/persistence/store_reporting.py"},"region":{"startLine":22}}}],"partialFingerprints":{"codehealthFindingId/v1":"a0e6704c49af82b80c10e78ac79beda947ff6ed95a7d7eae29ae819496d8e9c6"}},{"ruleId":"D2","level":"warning","message":{"text":"snap.snap_form (cognitive 24): snap.snap_form has cognitive complexity 24 (threshold 15). Drivers by points: boolean chains 13, if/else 5 (8 pts), loops 3 (nesting depth added 3). 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":"core_memory/retrieval/pipeline/snap.py"},"region":{"startLine":43}}}],"partialFingerprints":{"codehealthFindingId/v1":"24a5e2e9e24d3917743b2ce95322f80df2cf0116fc6d70b08ac55dbc883678ce"}},{"ruleId":"D2","level":"warning","message":{"text":"memory_reason._chain_coherence (cognitive 24): memory_reason._chain_coherence has cognitive complexity 24 (threshold 15). Drivers by points: if/else 9 (12 pts), boolean chains 10, loops 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":"core_memory/retrieval/tools/memory_reason.py"},"region":{"startLine":121}}}],"partialFingerprints":{"codehealthFindingId/v1":"c03a0071204dd52782a27389a498958b232c2061b5f12d91de8dd351117c8af5"}},{"ruleId":"D2","level":"warning","message":{"text":"external_evidence._bead_payload (cognitive 24): external_evidence._bead_payload has cognitive complexity 24 (threshold 15). Drivers by points: boolean chains 12, if/else 5 (7 pts), ternaries 3, loops 2 (nesting depth added 2). 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":"core_memory/runtime/ingest/external_evidence.py"},"region":{"startLine":417}}}],"partialFingerprints":{"codehealthFindingId/v1":"3f6e286125432982aafac4aa7e8b10af6581a922b6dff5181a855bd59b0ce5b3"}},{"ruleId":"D2","level":"warning","message":{"text":"external_evidence._run_semantic_enrichment (cognitive 24): external_evidence._run_semantic_enrichment has cognitive complexity 24 (threshold 15). Drivers by points: if/else 12 (15 pts), boolean chains 8, 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":"core_memory/runtime/ingest/external_evidence.py"},"region":{"startLine":591}}}],"partialFingerprints":{"codehealthFindingId/v1":"d7403d3e9d351b50b7a643fe5cb81f60a76738f02eebd305723c0ba3eb38be00"}},{"ruleId":"D2","level":"warning","message":{"text":"retrieval_value_overrides.apply_retrieval_value_override_for_index (cognitive 24): retrieval_value_overrides.apply_retrieval_value_override_for_index has cognitive complexity 24 (threshold 15). Drivers by points: boolean chains 20, if/else 4. 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":"core_memory/runtime/observability/retrieval_value_overrides.py"},"region":{"startLine":55}}}],"partialFingerprints":{"codehealthFindingId/v1":"809c0fc82146c80c689b039b0d840333ac2d40adda6632f4fac3ebb453444e4f"}},{"ruleId":"D2","level":"warning","message":{"text":"session_enrichment_delta.write_delta_quarantine (cognitive 24): session_enrichment_delta.write_delta_quarantine has cognitive complexity 24 (threshold 15). Drivers by points: if/else 8 (13 pts), boolean chains 5, 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":"core_memory/runtime/session/session_enrichment_delta.py"},"region":{"startLine":333}}}],"partialFingerprints":{"codehealthFindingId/v1":"af8323886ee4a7f5cfc0c0833499d4f6e3591779322258a5fccc5a3c0997a7ba"}},{"ruleId":"D2","level":"warning","message":{"text":"session_enrichment_delta.delta_to_crawler_updates (cognitive 24): session_enrichment_delta.delta_to_crawler_updates has cognitive complexity 24 (threshold 15). Drivers by points: if/else 6 (12 pts), boolean chains 8, loops 4 (nesting depth added 6). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"core_memory/runtime/session/session_enrichment_delta.py"},"region":{"startLine":740}}}],"partialFingerprints":{"codehealthFindingId/v1":"8dbef278793f8d39f7730e7c9e32e3f773019ac93470970e6798c4d66761be3b"}},{"ruleId":"D2","level":"warning","message":{"text":"tension_signals.detect_goal_conflicts (cognitive 24): tension_signals.detect_goal_conflicts has cognitive complexity 24 (threshold 15). Drivers by points: if/else 8 (13 pts), boolean chains 10, 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":"core_memory/soul/tension_signals.py"},"region":{"startLine":43}}}],"partialFingerprints":{"codehealthFindingId/v1":"42bfffbe8d0eaae6ba95f019eebd5508ea3b32abc332342a1890291a1b66c919"}},{"ruleId":"D2","level":"warning","message":{"text":"junctions._worldline_identities (cognitive 23): junctions._worldline_identities has cognitive complexity 23 (threshold 15). Drivers by points: boolean chains 11, if/else 5 (11 pts), loops 1 (nesting depth added 6). 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":"core_memory/graph/junctions.py"},"region":{"startLine":277}}}],"partialFingerprints":{"codehealthFindingId/v1":"92dc4e7653a428f9168b5689aac432b1c1f279abba3ea9a5d4dc8b5903d6c987"}},{"ruleId":"D2","level":"warning","message":{"text":"entity_merge_flow.suggest_entity_merge_proposals_for_index (cognitive 23): entity_merge_flow.suggest_entity_merge_proposals_for_index has cognitive complexity 23 (threshold 15). Drivers by points: if/else 5 (11 pts), boolean chains 9, 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":"core_memory/persistence/entity_merge_flow.py"},"region":{"startLine":60}}}],"partialFingerprints":{"codehealthFindingId/v1":"3445375f4f4274e7651d175deb131e2705119139dc7b048812f13797285045d0"}},{"ruleId":"D2","level":"warning","message":{"text":"myelination_rewards.reward_claim_conflict_resolution (cognitive 23): myelination_rewards.reward_claim_conflict_resolution has cognitive complexity 23 (threshold 15). Drivers by points: if/else 7 (11 pts), boolean chains 10, 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":"core_memory/persistence/myelination_rewards.py"},"region":{"startLine":527}}}],"partialFingerprints":{"codehealthFindingId/v1":"b202c1e19f9a0b4ce0ba885b84a8047eef2b1220910c5a4dc8b1cc5a1fc39328"}},{"ruleId":"D2","level":"warning","message":{"text":"store_claim_ops._claim_update_evidence_bead_ids (cognitive 23): store_claim_ops._claim_update_evidence_bead_ids has cognitive complexity 23 (threshold 15). Drivers by points: if/else 6 (13 pts), boolean chains 6, loops 3 (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":"core_memory/persistence/store_claim_ops.py"},"region":{"startLine":179}}}],"partialFingerprints":{"codehealthFindingId/v1":"addf4dab93c88bbff6db7d318f5d94f64dae75155ced78c8a909d8b8eaccd367"}},{"ruleId":"D2","level":"warning","message":{"text":"store_failure_ops.find_failure_signature_matches_for_store (cognitive 23): store_failure_ops.find_failure_signature_matches_for_store has cognitive complexity 23 (threshold 15). Drivers by points: if/else 6 (12 pts), boolean chains 8, 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":"core_memory/persistence/store_failure_ops.py"},"region":{"startLine":16}}}],"partialFingerprints":{"codehealthFindingId/v1":"4cf89a48b662973e180096df43618b88fdd3a79ec325d3059d52a2f072dcc82d"}},{"ruleId":"D2","level":"warning","message":{"text":"coverage.on_bead_committed (cognitive 23): coverage.on_bead_committed has cognitive complexity 23 (threshold 15). Drivers by points: ternaries 5 (10 pts), boolean chains 8, if/else 4 (5 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":"core_memory/runtime/associations/coverage.py"},"region":{"startLine":2410}}}],"partialFingerprints":{"codehealthFindingId/v1":"a10c5a1d69336474a0f8dd2b1c9ab52d38159014a197de341d2ff2f567ae1723"}},{"ruleId":"D2","level":"warning","message":{"text":"external_evidence.ingest_external_evidence (cognitive 23): external_evidence.ingest_external_evidence has cognitive complexity 23 (threshold 15). Drivers by points: if/else 8 (10 pts), boolean chains 8, ternaries 2 (4 pts), 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":"core_memory/runtime/ingest/external_evidence.py"},"region":{"startLine":684}}}],"partialFingerprints":{"codehealthFindingId/v1":"a2f9d375b2331a52cca864eaa60e7a166f91083664f5eab5d330332da0a17e37"}},{"ruleId":"D2","level":"warning","message":{"text":"jobs.enqueue_async_job (cognitive 23): jobs.enqueue_async_job has cognitive complexity 23 (threshold 15). Drivers by points: boolean chains 11, if/else 7 (10 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":"core_memory/runtime/queue/jobs.py"},"region":{"startLine":192}}}],"partialFingerprints":{"codehealthFindingId/v1":"68da934fc35c4ebb0c4c17e436a05723ed5cd6bad1c717358d2f3ec7c0398182"}},{"ruleId":"D2","level":"warning","message":{"text":"semantic_state.semantic_write_health (cognitive 23): semantic_state.semantic_write_health has cognitive complexity 23 (threshold 15). Drivers by points: boolean chains 12, if/else 4 (5 pts), ternaries 4 (5 pts), loops 1 (nesting depth added 2). 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":"core_memory/runtime/turn/semantic_state.py"},"region":{"startLine":201}}}],"partialFingerprints":{"codehealthFindingId/v1":"e8ace8dd219229421669d30c86743b20fd9923066de343dc3dc5db87e1463b65"}},{"ruleId":"D2","level":"warning","message":{"text":"store._current_entries (cognitive 23): store._current_entries has cognitive complexity 23 (threshold 15). Drivers by points: boolean chains 12, if/else 5 (10 pts), loops 1 (nesting depth added 5). To reduce it, name the conditions: bind each compound test to a well-named local or a small predicate function, so the body reads as a sequence of named decisions rather than a chain of operators."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"core_memory/soul/store.py"},"region":{"startLine":101}}}],"partialFingerprints":{"codehealthFindingId/v1":"707e3e2a9e61d073c41d0b3cfe897f2d528d2aaf00c7c215398521f8e6b86bd5"}},{"ruleId":"D2","level":"warning","message":{"text":"crawler_contract._maybe_upgrade_context_to_reflection (cognitive 22): crawler_contract._maybe_upgrade_context_to_reflection has cognitive complexity 22 (threshold 15). Drivers by points: if/else 9 (14 pts), boolean chains 5, loops 2, 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":"core_memory/association/crawler_contract.py"},"region":{"startLine":697}}}],"partialFingerprints":{"codehealthFindingId/v1":"a26f0aadc38b6098e25ecf6bb76d5e9135185bde7f3490c6d78d8cde493841fb"}},{"ruleId":"D2","level":"warning","message":{"text":"update_policy._normalize_explicit_updates (cognitive 22): update_policy._normalize_explicit_updates has cognitive complexity 22 (threshold 15). Drivers by points: boolean chains 13, if/else 4 (8 pts), loops 1 (nesting depth added 4). 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":"core_memory/claim/update_policy.py"},"region":{"startLine":75}}}],"partialFingerprints":{"codehealthFindingId/v1":"be828fafee8b72fe78bb5fad24a7f9924a4a57fec380d08bd79ae3f0c3c2e2f5"}},{"ruleId":"D2","level":"warning","message":{"text":"junctions._embedding_neighbors (cognitive 22): junctions._embedding_neighbors has cognitive complexity 22 (threshold 15). Drivers by points: loops 5 (10 pts), if/else 4 (9 pts), boolean chains 3 (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":"core_memory/graph/junctions.py"},"region":{"startLine":143}}}],"partialFingerprints":{"codehealthFindingId/v1":"8f38cb71cccdb612bb1cc85a4c3368b41ef2542ee7f645e91ade31b9f43def13"}},{"ruleId":"D2","level":"warning","message":{"text":"promotion_service.evaluate_candidates_for_store (cognitive 22): promotion_service.evaluate_candidates_for_store has cognitive complexity 22 (threshold 15). Drivers by points: boolean chains 9, if/else 3 (5 pts), ternaries 2 (4 pts), error handling 1 (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":"core_memory/persistence/promotion_service.py"},"region":{"startLine":77}}}],"partialFingerprints":{"codehealthFindingId/v1":"2e8c861d16d92c562e1dc8b07d0d539f602f824abcfc9d8bff029539526165b6"}},{"ruleId":"D2","level":"warning","message":{"text":"promotion_service.resolve_goal_candidate_for_store (cognitive 22): promotion_service.resolve_goal_candidate_for_store has cognitive complexity 22 (threshold 15). Drivers by points: boolean chains 14, if/else 7, error handling 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":"core_memory/persistence/promotion_service.py"},"region":{"startLine":288}}}],"partialFingerprints":{"codehealthFindingId/v1":"005f932e16a4d7ab931e3cc3c584116edc89f06c3fe2de52c602218e9d73fd38"}},{"ruleId":"D2","level":"warning","message":{"text":"store_add_helpers.resolve_bead_session_id_for_store (cognitive 22): store_add_helpers.resolve_bead_session_id_for_store has cognitive complexity 22 (threshold 15). Drivers by points: if/else 8 (15 pts), boolean chains 5, 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":"core_memory/persistence/store_add_helpers.py"},"region":{"startLine":9}}}],"partialFingerprints":{"codehealthFindingId/v1":"02ceff422bdf625d013e06f165442108cd76de79ee2fdcd12728f94986766178"}},{"ruleId":"D2","level":"warning","message":{"text":"pipehouse_adapter.retrieve (cognitive 22): pipehouse_adapter.retrieve has cognitive complexity 22 (threshold 15). Drivers by points: boolean chains 10, if/else 5 (7 pts), error handling 1 (2 pts), ternaries 1 (2 pts), loops 1 (nesting depth added 4). 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":"core_memory/retrieval/adapters/pipehouse_adapter.py"},"region":{"startLine":30}}}],"partialFingerprints":{"codehealthFindingId/v1":"3515616adf24e3c30227d3c038575ed0e794e5ea0ea34b7a0a56a1c0fc7ed4b1"}},{"ruleId":"D2","level":"warning","message":{"text":"causal_recall._claims_for_paths (cognitive 22): causal_recall._claims_for_paths has cognitive complexity 22 (threshold 15). Drivers by points: if/else 4 (11 pts), loops 3 (5 pts), boolean chains 3, ternaries 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":"core_memory/retrieval/causal_recall.py"},"region":{"startLine":208}}}],"partialFingerprints":{"codehealthFindingId/v1":"5e06b5476eb91ff88ba6f866ba40c5b5fd083691dc503f873b2dcd1a481b8f9b"}},{"ruleId":"D2","level":"warning","message":{"text":"TurnEnvelope.finalize_hashes (cognitive 22): TurnEnvelope.finalize_hashes has cognitive complexity 22 (threshold 15). Drivers by points: boolean chains 9, if/else 4 (8 pts), loops 2 (4 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":"core_memory/runtime/state.py"},"region":{"startLine":79}}}],"partialFingerprints":{"codehealthFindingId/v1":"1003be936a7d144f8414bf96846f570f2a2dd3ceba7f75fc7a68cea557114105"}},{"ruleId":"D2","level":"warning","message":{"text":"reauthoring._v1_bead_ids (cognitive 22): reauthoring._v1_bead_ids has cognitive complexity 22 (threshold 15). Drivers by points: if/else 5 (13 pts), loops 3 (4 pts), boolean chains 3, 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":"core_memory/runtime/turn/reauthoring.py"},"region":{"startLine":153}}}],"partialFingerprints":{"codehealthFindingId/v1":"eb98bb0822c86c2dbed85da2c8e0d937c6fccbef1cc870483a4993816fee1396"}},{"ruleId":"D2","level":"warning","message":{"text":"semantic_state.latest_finalized_turn (cognitive 22): semantic_state.latest_finalized_turn has cognitive complexity 22 (threshold 15). Drivers by points: boolean chains 10, if/else 5 (9 pts), error handling 1 (2 pts), loops 1 (nesting depth added 5). To reduce it, name the conditions: bind each compound test to a well-named local or a small predicate function, so the body reads as a sequence of named decisions rather than a chain of operators."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"core_memory/runtime/turn/semantic_state.py"},"region":{"startLine":250}}}],"partialFingerprints":{"codehealthFindingId/v1":"fbe01af627df59de1b4f8b7ed0f608a55936a1667b0d3eb28b74794bceef4f3e"}},{"ruleId":"D2","level":"warning","message":{"text":"dreamer_bridge._normalize_drafts (cognitive 22): dreamer_bridge._normalize_drafts has cognitive complexity 22 (threshold 15). Drivers by points: if/else 6 (11 pts), boolean chains 10, 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":"core_memory/soul/dreamer_bridge.py"},"region":{"startLine":380}}}],"partialFingerprints":{"codehealthFindingId/v1":"cec3043291e1779dfab62df38051ab3ca54b961879d1e74e7837f4ea64dec4ee"}},{"ruleId":"D2","level":"warning","message":{"text":"rolling_window._select_beads_for_budget (cognitive 22): rolling_window._select_beads_for_budget has cognitive complexity 22 (threshold 15). Drivers by points: if/else 10 (14 pts), boolean chains 6, loops 1, ternaries 1 (nesting depth added 4). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"core_memory/write_pipeline/rolling_window.py"},"region":{"startLine":188}}}],"partialFingerprints":{"codehealthFindingId/v1":"e7274bff57ee8796be4c5cae8b04308b1841a247a4bd9679372adb2679b4bc5c"}},{"ruleId":"D2","level":"warning","message":{"text":"answer_policy.explain_answer_outcome (cognitive 21): answer_policy.explain_answer_outcome has cognitive complexity 21 (threshold 15). Drivers by points: boolean chains 15, if/else 6. 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":"core_memory/claim/answer_policy.py"},"region":{"startLine":77}}}],"partialFingerprints":{"codehealthFindingId/v1":"ec6c104f2d09a6854c48294f45ab25eb8eaa2e44b04ceb3ccc276b83d2afd150"}},{"ruleId":"D2","level":"warning","message":{"text":"ops.handle_ops_commands (cognitive 21): ops.handle_ops_commands has cognitive complexity 21 (threshold 15). Drivers by points: if/else 12 (19 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":"core_memory/cli/handlers/ops.py"},"region":{"startLine":46}}}],"partialFingerprints":{"codehealthFindingId/v1":"c9853fcd9ad70eb9fffb8a2e50b3132167ee9a45dedfc2760f58ff51a9f87944"}},{"ruleId":"D2","level":"warning","message":{"text":"roadmap._candidate_pairs (cognitive 21): roadmap._candidate_pairs has cognitive complexity 21 (threshold 15). Drivers by points: if/else 3 (9 pts), boolean chains 7, 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":"core_memory/graph/roadmap.py"},"region":{"startLine":164}}}],"partialFingerprints":{"codehealthFindingId/v1":"23d2265fc4f5689e76b4b4ae4a1c992953511f27a3b0c8e98b43974c47797f0f"}},{"ruleId":"D2","level":"warning","message":{"text":"ingest_zoom._parse_vtt (cognitive 21): ingest_zoom._parse_vtt has cognitive complexity 21 (threshold 15). Drivers by points: if/else 7 (14 pts), boolean chains 4, 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":"core_memory/integrations/mcp/tools/ingest_zoom.py"},"region":{"startLine":37}}}],"partialFingerprints":{"codehealthFindingId/v1":"6107e1b4451bd0c5a767cd30efe2ef51d63337cd2c7dc8b8f032b0adeb942abe"}},{"ruleId":"D2","level":"warning","message":{"text":"transcript_snapshot_state.reserve_transcript_snapshot (cognitive 21): transcript_snapshot_state.reserve_transcript_snapshot has cognitive complexity 21 (threshold 15). Drivers by points: boolean chains 11, if/else 5 (8 pts), ternaries 2 (nesting depth added 3). 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":"core_memory/integrations/mcp/tools/transcript_snapshot_state.py"},"region":{"startLine":92}}}],"partialFingerprints":{"codehealthFindingId/v1":"f2eee40cba38600723e1a1a9f4ac8d24c7e58769d054ab58c9ca6b8544705ac1"}},{"ruleId":"D2","level":"warning","message":{"text":"agent_end_bridge._fallback_text (cognitive 21): agent_end_bridge._fallback_text has cognitive complexity 21 (threshold 15). Drivers by points: if/else 7 (14 pts), loops 4 (7 pts) (nesting depth added 10). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"core_memory/integrations/openclaw/agent_end_bridge.py"},"region":{"startLine":59}}}],"partialFingerprints":{"codehealthFindingId/v1":"33181e90d8f8c31038db0220eb1b16f643502f3e6b39e06064cd458d80198f27"}},{"ruleId":"D2","level":"warning","message":{"text":"memory_tools.continuity_prompt (cognitive 21): memory_tools.continuity_prompt has cognitive complexity 21 (threshold 15). Drivers by points: if/else 6 (9 pts), boolean chains 6, error handling 3 (4 pts), loops 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":"core_memory/integrations/pydanticai/memory_tools.py"},"region":{"startLine":102}}}],"partialFingerprints":{"codehealthFindingId/v1":"8e75613b668df665c1a4e960a30b166aea54c7566730734d770f87378cc91a83"}},{"ruleId":"D2","level":"warning","message":{"text":"semantic_tasks._result_from_payload (cognitive 21): semantic_tasks._result_from_payload has cognitive complexity 21 (threshold 15). Drivers by points: boolean chains 17, ternaries 4. 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":"core_memory/integrations/remote/semantic_tasks.py"},"region":{"startLine":137}}}],"partialFingerprints":{"codehealthFindingId/v1":"5ee3382cd9b484dc65a91b10a6d388f7563f0fe875753da21520a0c465e687a3"}},{"ruleId":"D2","level":"warning","message":{"text":"store_constraints.check_plan_constraints_for_store (cognitive 21): store_constraints.check_plan_constraints_for_store has cognitive complexity 21 (threshold 15). Drivers by points: if/else 7 (15 pts), loops 2 (3 pts), ternaries 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":"core_memory/persistence/store_constraints.py"},"region":{"startLine":52}}}],"partialFingerprints":{"codehealthFindingId/v1":"ae3dde0f7e5f186e46ecc7911bcdccb88e040078131ff5c01f248a02e3c237ee"}},{"ruleId":"D2","level":"warning","message":{"text":"association_inference_v21._association_evidence_bead_ids (cognitive 21): association_inference_v21._association_evidence_bead_ids has cognitive complexity 21 (threshold 15). Drivers by points: if/else 5 (10 pts), boolean chains 6, loops 4 (5 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":"core_memory/policy/association_inference_v21.py"},"region":{"startLine":77}}}],"partialFingerprints":{"codehealthFindingId/v1":"72d9d48ebe2d9b0dfcf415d756a9c84bf0bf1567e5dc2ba70431225fd49fbe7c"}},{"ruleId":"D2","level":"warning","message":{"text":"semantic_index._external_backend_connectivity (cognitive 21): semantic_index._external_backend_connectivity has cognitive complexity 21 (threshold 15). Drivers by points: error handling 5 (10 pts), if/else 5 (7 pts), boolean chains 4 (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":"core_memory/retrieval/semantic_index.py"},"region":{"startLine":535}}}],"partialFingerprints":{"codehealthFindingId/v1":"9fe743a110dfc7bfa54525ad406331e29cd0a58f8307ea1f7295eb04f4263d5b"}},{"ruleId":"D2","level":"warning","message":{"text":"assembly_depth._raw_factors (cognitive 21): assembly_depth._raw_factors has cognitive complexity 21 (threshold 15). Drivers by points: boolean chains 13, if/else 5, ternaries 2, loops 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":"core_memory/soul/assembly_depth.py"},"region":{"startLine":76}}}],"partialFingerprints":{"codehealthFindingId/v1":"4d295b541e07121f9c86240669a163053feb3680129fa8b25c8e84d808cd8527"}},{"ruleId":"D2","level":"warning","message":{"text":"dreamer_bridge._enrich_findings_with_signals (cognitive 21): dreamer_bridge._enrich_findings_with_signals has cognitive complexity 21 (threshold 15). Drivers by points: boolean chains 6, if/else 3 (6 pts), ternaries 3 (6 pts), error handling 1 (2 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":"core_memory/soul/dreamer_bridge.py"},"region":{"startLine":191}}}],"partialFingerprints":{"codehealthFindingId/v1":"e0732cea0d80dadc073f5b0ed6b88c52d8cfa0088f2e786bfb7f38e776406eec"}},{"ruleId":"D2","level":"warning","message":{"text":"register::emitFallbackTurn (cognitive 21): register::emitFallbackTurn has cognitive complexity 21 (threshold 15). Drivers by points: boolean chains 12, 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":"plugins/openclaw-core-memory-bridge/index.js"},"region":{"startLine":446}}}],"partialFingerprints":{"codehealthFindingId/v1":"5031e7a819d2c57c66f824535aa4dc6930d16b5169d0c3aa32ca67bc7fd48ccf"}},{"ruleId":"D2","level":"warning","message":{"text":"preview.compute_preview_association_candidates (cognitive 20): preview.compute_preview_association_candidates has cognitive complexity 20 (threshold 15). Drivers by points: if/else 6 (11 pts), boolean chains 8, 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":"core_memory/association/preview.py"},"region":{"startLine":138}}}],"partialFingerprints":{"codehealthFindingId/v1":"c9db5c0f9cf86a5391026bf68940b2a993c641d8535e77045e179383edaf8177"}},{"ruleId":"D2","level":"warning","message":{"text":"root_cause._path_record (cognitive 20): root_cause._path_record has cognitive complexity 20 (threshold 15). Drivers by points: boolean chains 10, if/else 2 (4 pts), loops 3 (4 pts), ternaries 2 (nesting depth added 3). 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":"core_memory/graph/root_cause.py"},"region":{"startLine":480}}}],"partialFingerprints":{"codehealthFindingId/v1":"942622a2ef4f35e7de99f2c4d50e197af3c20ef94603fbfd48136203643a3aa5"}},{"ruleId":"D2","level":"warning","message":{"text":"root_cause._rank_influence (cognitive 20): root_cause._rank_influence has cognitive complexity 20 (threshold 15). Drivers by points: if/else 4 (7 pts), boolean chains 6, loops 4 (5 pts), 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":"core_memory/graph/root_cause.py"},"region":{"startLine":741}}}],"partialFingerprints":{"codehealthFindingId/v1":"c8179cd8fc0a83fb7a82fca30c80a6caa97184fdd7dfb5f8918b5abbf986650f"}},{"ruleId":"D2","level":"warning","message":{"text":"root_cause._dynamic_cost_signature (cognitive 20): root_cause._dynamic_cost_signature has cognitive complexity 20 (threshold 15). Drivers by points: if/else 3 (8 pts), boolean chains 6, loops 4 (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":"core_memory/graph/root_cause.py"},"region":{"startLine":911}}}],"partialFingerprints":{"codehealthFindingId/v1":"1d836ea4501384df87e398fa0cf8d42f4f61865d752210728cbd7fd9b46974a5"}},{"ruleId":"D2","level":"warning","message":{"text":"root_cause.root_cause_trace (cognitive 20): root_cause.root_cause_trace has cognitive complexity 20 (threshold 15). Drivers by points: boolean chains 9, if/else 7, ternaries 2 (3 pts), 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":"core_memory/graph/root_cause.py"},"region":{"startLine":1277}}}],"partialFingerprints":{"codehealthFindingId/v1":"2dd9b30f5f388edd3817e514e62d9746667092953d5df503b198b1153f17eb9e"}},{"ruleId":"D2","level":"warning","message":{"text":"typed_read.query_current_state (cognitive 20): typed_read.query_current_state has cognitive complexity 20 (threshold 15). Drivers by points: boolean chains 17, ternaries 2, if/else 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":"core_memory/integrations/mcp/typed_read.py"},"region":{"startLine":168}}}],"partialFingerprints":{"codehealthFindingId/v1":"133e87418a10f5de69f53c903538bd8d2ebbc0f4962c8073b6fca497933b5c30"}},{"ruleId":"D2","level":"warning","message":{"text":"KuzuGraphBackend._traverse_hops (cognitive 20): KuzuGraphBackend._traverse_hops has cognitive complexity 20 (threshold 15). Drivers by points: if/else 4 (13 pts), loops 3 (6 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":"core_memory/persistence/graph/kuzu_backend.py"},"region":{"startLine":158}}}],"partialFingerprints":{"codehealthFindingId/v1":"19c5b52d0e0e7f4ed09d8a5dc10362a2ab89f5ea8fb83dd8cf1f90d7f20a2ebb"}},{"ruleId":"D2","level":"warning","message":{"text":"myelination_rewards.reward_bonus_by_edge_key (cognitive 20): myelination_rewards.reward_bonus_by_edge_key has cognitive complexity 20 (threshold 15). Drivers by points: if/else 4 (11 pts), loops 3 (4 pts), boolean chains 3, 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":"core_memory/persistence/myelination_rewards.py"},"region":{"startLine":630}}}],"partialFingerprints":{"codehealthFindingId/v1":"91c1b614e27fb28fa96d1f794daa5b81a68e8b4170e1365801f116f971d26e05"}},{"ruleId":"D2","level":"warning","message":{"text":"retrieval_feedback._collect_edges (cognitive 20): retrieval_feedback._collect_edges has cognitive complexity 20 (threshold 15). Drivers by points: if/else 4 (11 pts), boolean chains 6, 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":"core_memory/persistence/retrieval_feedback.py"},"region":{"startLine":54}}}],"partialFingerprints":{"codehealthFindingId/v1":"d2244118806a00e09010b5afec39d0203bacfc36bbc00a8c316e3534f5ec9f1c"}},{"ruleId":"D2","level":"warning","message":{"text":"store_claim_ops._slot_highwater (cognitive 20): store_claim_ops._slot_highwater has cognitive complexity 20 (threshold 15). Drivers by points: if/else 3 (8 pts), boolean chains 6, 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":"core_memory/persistence/store_claim_ops.py"},"region":{"startLine":288}}}],"partialFingerprints":{"codehealthFindingId/v1":"c86476be1d98c0ab88a793aca3ee74365b790bcd15e0dafdae07b420c4ec08cb"}},{"ruleId":"D2","level":"warning","message":{"text":"store_claim_ops._all_claim_rows (cognitive 20): store_claim_ops._all_claim_rows has cognitive complexity 20 (threshold 15). Drivers by points: if/else 4 (9 pts), boolean chains 6, loops 3 (5 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":"core_memory/persistence/store_claim_ops.py"},"region":{"startLine":409}}}],"partialFingerprints":{"codehealthFindingId/v1":"3aba0a312ef4c210cafd85c38757652bdf83d3d1912d53d37a4bd012ad62ad11"}},{"ruleId":"D2","level":"warning","message":{"text":"causal_recall._url_from_value (cognitive 20): causal_recall._url_from_value has cognitive complexity 20 (threshold 15). Drivers by points: if/else 6 (12 pts), loops 3 (6 pts), ternaries 1 (2 pts) (nesting depth added 10). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"core_memory/retrieval/causal_recall.py"},"region":{"startLine":80}}}],"partialFingerprints":{"codehealthFindingId/v1":"c7432b9a85ee252f51b24ebc6a27bb8941586cb88e3e9ed0db73c5eeca7cede0"}},{"ruleId":"D2","level":"warning","message":{"text":"rerank._chain_features (cognitive 20): rerank._chain_features has cognitive complexity 20 (threshold 15). Drivers by points: boolean chains 8, ternaries 6, if/else 1 (3 pts), 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":"core_memory/retrieval/rerank.py"},"region":{"startLine":177}}}],"partialFingerprints":{"codehealthFindingId/v1":"e7b5cbedc5006f2b5def1be7d9b650b5c3cf18c3884a8cdb5b88d5a0603389f3"}},{"ruleId":"D2","level":"warning","message":{"text":"roadmap_planner._goal_advancing_terminals (cognitive 20): roadmap_planner._goal_advancing_terminals has cognitive complexity 20 (threshold 15). Drivers by points: boolean chains 8, if/else 4 (8 pts), ternaries 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":"core_memory/retrieval/roadmap_planner.py"},"region":{"startLine":110}}}],"partialFingerprints":{"codehealthFindingId/v1":"f913a2eb876ebd42d47e74e2030e8063e7dbe14312d4b8314d79a1bf8d5642ac"}},{"ruleId":"D2","level":"warning","message":{"text":"memory_reason._collect_citations_from_chains (cognitive 20): memory_reason._collect_citations_from_chains has cognitive complexity 20 (threshold 15). Drivers by points: boolean chains 9, if/else 2 (4 pts), loops 3 (4 pts), ternaries 1 (3 pts) (nesting depth added 5). To reduce it, name the conditions: bind each compound test to a well-named local or a small predicate function, so the body reads as a sequence of named decisions rather than a chain of operators."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"core_memory/retrieval/tools/memory_reason.py"},"region":{"startLine":342}}}],"partialFingerprints":{"codehealthFindingId/v1":"e40470f30a99cb7de3e0e8e3e8f63af607f5ba921b7f576abdc25eb27afedae2"}},{"ruleId":"D2","level":"warning","message":{"text":"memory_reason._plan_changed (cognitive 20): memory_reason._plan_changed has cognitive complexity 20 (threshold 15). Drivers by points: boolean chains 8, if/else 4 (7 pts), loops 2 (3 pts), ternaries 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":"core_memory/retrieval/tools/memory_reason.py"},"region":{"startLine":676}}}],"partialFingerprints":{"codehealthFindingId/v1":"89073970a572f19a8cad86b332262faa231f5ed64ea07687cfa11c34b9bca5ac"}},{"ruleId":"D2","level":"warning","message":{"text":"reviewer_quick_value._find_bead_id_by_turn_and_title (cognitive 20): reviewer_quick_value._find_bead_id_by_turn_and_title has cognitive complexity 20 (threshold 15). Drivers by points: if/else 6 (9 pts), boolean chains 8, error handling 1, loops 1, ternaries 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":"core_memory/runtime/observability/reviewer_quick_value.py"},"region":{"startLine":28}}}],"partialFingerprints":{"codehealthFindingId/v1":"98203bc9e99e8ef10d3e99399478b894b551a1fa9ec3eda6dcedf758f54e8f93"}},{"ruleId":"D2","level":"warning","message":{"text":"side_effect_queue.side_effect_queue_status (cognitive 20): side_effect_queue.side_effect_queue_status has cognitive complexity 20 (threshold 15). Drivers by points: if/else 4 (9 pts), boolean chains 8, ternaries 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":"core_memory/runtime/queue/side_effect_queue.py"},"region":{"startLine":67}}}],"partialFingerprints":{"codehealthFindingId/v1":"f2a37caf379c6a56754b799621ba4776e613b0cf488a0d261936e90445f2f58d"}},{"ruleId":"D2","level":"warning","message":{"text":"agent_authored_updates._drop_unknown_json_value (cognitive 20): agent_authored_updates._drop_unknown_json_value has cognitive complexity 20 (threshold 15). Drivers by points: if/else 7 (12 pts), ternaries 2 (4 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":"core_memory/schema/agent_authored_updates.py"},"region":{"startLine":568}}}],"partialFingerprints":{"codehealthFindingId/v1":"ff810227962fc626c73570c7bdc66b02da817ff4c933369b4a7dbc3aa11973f8"}},{"ruleId":"D2","level":"warning","message":{"text":"promotion.get_recommendation_rows (cognitive 20): promotion.get_recommendation_rows has cognitive complexity 20 (threshold 15). Drivers by points: if/else 7 (10 pts), boolean chains 9, 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":"core_memory/schema/promotion.py"},"region":{"startLine":218}}}],"partialFingerprints":{"codehealthFindingId/v1":"758327973ce862cc8223ed85ac781b8a0ffc6d743201d8fd32e8da1da5c68cef"}},{"ruleId":"D2","level":"warning","message":{"text":"dreamer_bridge.dreamer_soul_findings (cognitive 20): dreamer_bridge.dreamer_soul_findings has cognitive complexity 20 (threshold 15). Drivers by points: if/else 6 (12 pts), boolean chains 7, 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":"core_memory/soul/dreamer_bridge.py"},"region":{"startLine":729}}}],"partialFingerprints":{"codehealthFindingId/v1":"4efe29c0e59582ba7888ddce5cc66099ed48b1848066856d2dec4d2dc499e7b4"}},{"ruleId":"D2","level":"warning","message":{"text":"injection.soul_injection_text (cognitive 20): injection.soul_injection_text has cognitive complexity 20 (threshold 15). Drivers by points: if/else 4 (9 pts), boolean chains 5, loops 2 (3 pts), ternaries 1 (3 pts) (nesting depth added 8). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"core_memory/soul/injection.py"},"region":{"startLine":74}}}],"partialFingerprints":{"codehealthFindingId/v1":"7bed838db4bf6496dc0616473f6ee3e6cb7699f006cf46f5ba5c5ade5f53d006"}},{"ruleId":"D2","level":"warning","message":{"text":"store.propose_soul_update (cognitive 20): store.propose_soul_update has cognitive complexity 20 (threshold 15). Drivers by points: boolean chains 10, if/else 8, ternaries 2. 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":"core_memory/soul/store.py"},"region":{"startLine":201}}}],"partialFingerprints":{"codehealthFindingId/v1":"c59fb0f2dcee5d65656e69dd47421bbfca081e25a7c69f2be9102c58775f6f8b"}},{"ruleId":"D2","level":"warning","message":{"text":"semantic.handle_semantic_command (cognitive 19): semantic.handle_semantic_command has cognitive complexity 19 (threshold 15). Drivers by points: if/else 10 (14 pts), boolean chains 5 (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":"core_memory/cli/handlers/semantic.py"},"region":{"startLine":46}}}],"partialFingerprints":{"codehealthFindingId/v1":"943672295709648351d424260cc29554e636fc2b0a4670306c07e70d94677d60"}},{"ruleId":"D2","level":"warning","message":{"text":"junctions.resolve_junction_matches (cognitive 19): junctions.resolve_junction_matches has cognitive complexity 19 (threshold 15). Drivers by points: boolean chains 15, if/else 2, loops 1, ternaries 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":"core_memory/graph/junctions.py"},"region":{"startLine":437}}}],"partialFingerprints":{"codehealthFindingId/v1":"e5c0525a5f6b9ce697b63ac3d1e98d2f5844913b3d0c7ddad5ab641d16293a4a"}},{"ruleId":"D2","level":"warning","message":{"text":"worldlines._claim_worldlines (cognitive 19): worldlines._claim_worldlines has cognitive complexity 19 (threshold 15). Drivers by points: if/else 4 (9 pts), boolean chains 6, loops 3 (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":"core_memory/graph/worldlines.py"},"region":{"startLine":68}}}],"partialFingerprints":{"codehealthFindingId/v1":"a8b318b4ecb13aa9e9a6397467dcdebf969f8a33030dc0ad146214fa20d1d56f"}},{"ruleId":"D2","level":"warning","message":{"text":"server.turn_finalized (cognitive 19): server.turn_finalized has cognitive complexity 19 (threshold 15). Drivers by points: boolean chains 9, if/else 4 (5 pts), error handling 3 (4 pts), ternaries 1 (nesting depth added 2). 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":"core_memory/integrations/http/server.py"},"region":{"startLine":801}}}],"partialFingerprints":{"codehealthFindingId/v1":"18dae2eba76d8e9732315e81ad017f3f108c86d89019a2d6a0de9834d309fe5e"}},{"ruleId":"D2","level":"warning","message":{"text":"entity_merge_flow.decide_entity_merge_proposal_for_index (cognitive 19): entity_merge_flow.decide_entity_merge_proposal_for_index has cognitive complexity 19 (threshold 15). Drivers by points: boolean chains 13, if/else 3, ternaries 2 (3 pts) (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":"core_memory/persistence/entity_merge_flow.py"},"region":{"startLine":204}}}],"partialFingerprints":{"codehealthFindingId/v1":"1b73526c0eeb93a89cb5002d7ae48df2157ecd5fc5c59872f0db331c1bafe736"}},{"ruleId":"D2","level":"warning","message":{"text":"factory.create_graph_backend (cognitive 19): factory.create_graph_backend has cognitive complexity 19 (threshold 15). Drivers by points: error handling 5 (10 pts), if/else 5, boolean chains 2, ternaries 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":"core_memory/persistence/graph/factory.py"},"region":{"startLine":34}}}],"partialFingerprints":{"codehealthFindingId/v1":"cb668f14b8a1cb8a964598633c684fc5702b9281e67403722ed3ec4814c0f5c9"}},{"ruleId":"D2","level":"warning","message":{"text":"store_metrics_runtime.append_metric_for_store (cognitive 19): store_metrics_runtime.append_metric_for_store has cognitive complexity 19 (threshold 15). Drivers by points: boolean chains 15, if/else 2 (3 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":"core_memory/persistence/store_metrics_runtime.py"},"region":{"startLine":81}}}],"partialFingerprints":{"codehealthFindingId/v1":"c574ca949f98a91e67d1fd968dea1558c27d9c50303bf129fd7065d353fe1161"}},{"ruleId":"D2","level":"warning","message":{"text":"bead_judge._heuristic_entities (cognitive 19): bead_judge._heuristic_entities has cognitive complexity 19 (threshold 15). Drivers by points: if/else 3 (9 pts), loops 3 (6 pts), boolean chains 4 (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":"core_memory/policy/bead_judge.py"},"region":{"startLine":148}}}],"partialFingerprints":{"codehealthFindingId/v1":"8dd3c97431b9d285b6588dd29a8b9417d2b503aa6a0f10e0dda164f29a2c8191"}},{"ruleId":"D2","level":"warning","message":{"text":"causal_recall.causal_edge_pressure (cognitive 19): causal_recall.causal_edge_pressure has cognitive complexity 19 (threshold 15). Drivers by points: if/else 6 (10 pts), boolean chains 8, 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":"core_memory/retrieval/causal_recall.py"},"region":{"startLine":477}}}],"partialFingerprints":{"codehealthFindingId/v1":"66878f9de3feb3ecb38f06df5a7be9c32050074634d7d375e5e48e34ddf93219"}},{"ruleId":"D2","level":"warning","message":{"text":"coverage._candidate_status_updates (cognitive 19): coverage._candidate_status_updates has cognitive complexity 19 (threshold 15). Drivers by points: if/else 4 (9 pts), loops 4 (7 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":"core_memory/runtime/associations/coverage.py"},"region":{"startLine":455}}}],"partialFingerprints":{"codehealthFindingId/v1":"55bc6e33c7e5db937167b4cd4c6ab4ede7081d028f07945ce34ae69ec180e612"}},{"ruleId":"D2","level":"warning","message":{"text":"candidates._entity_similarity (cognitive 19): candidates._entity_similarity has cognitive complexity 19 (threshold 15). Drivers by points: if/else 8 (9 pts), boolean chains 8, ternaries 2 (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":"core_memory/runtime/dreamer/candidates.py"},"region":{"startLine":60}}}],"partialFingerprints":{"codehealthFindingId/v1":"808e061e2c70a0a779b22e599db7870f5ae9b7a58057a053e5219b97ba55459b"}},{"ruleId":"D2","level":"warning","message":{"text":"candidates.submit_entity_merge_candidate (cognitive 19): candidates.submit_entity_merge_candidate has cognitive complexity 19 (threshold 15). Drivers by points: boolean chains 16, if/else 3. 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":"core_memory/runtime/dreamer/candidates.py"},"region":{"startLine":1112}}}],"partialFingerprints":{"codehealthFindingId/v1":"f3bce6ee73e540afc2584e0728e0031e99a6a852f9a6595989946c00b9ec6a58"}},{"ruleId":"D2","level":"warning","message":{"text":"longitudinal.longitudinal_benchmark_v2 (cognitive 19): longitudinal.longitudinal_benchmark_v2 has cognitive complexity 19 (threshold 15). Drivers by points: boolean chains 10, if/else 5 (8 pts), loops 1 (nesting depth added 3). 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":"core_memory/runtime/dreamer/longitudinal.py"},"region":{"startLine":178}}}],"partialFingerprints":{"codehealthFindingId/v1":"e9fe40731b3232a619c61d2f027e5d286a85356effb1f1f06e2c341ff14cd053"}},{"ruleId":"D2","level":"warning","message":{"text":"engine._default_entities_from_text (cognitive 19): engine._default_entities_from_text has cognitive complexity 19 (threshold 15). Drivers by points: if/else 5 (14 pts), loops 2 (3 pts), boolean chains 2 (nesting depth added 10). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"core_memory/runtime/engine.py"},"region":{"startLine":246}}}],"partialFingerprints":{"codehealthFindingId/v1":"4efccb0369f3cdce6dc0cdaf1cbd0008cd6f92f3ef4e3551e3ebac310e42e59b"}},{"ruleId":"D2","level":"warning","message":{"text":"progress.process_goal_progress_event (cognitive 19): progress.process_goal_progress_event has cognitive complexity 19 (threshold 15). Drivers by points: boolean chains 11, if/else 5 (8 pts) (nesting depth added 3). 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":"core_memory/runtime/goals/progress.py"},"region":{"startLine":804}}}],"partialFingerprints":{"codehealthFindingId/v1":"adfeca559f4f673df566082e75c362da641c52dd2282f3acefd5d4bb0bd0b73f"}},{"ruleId":"D2","level":"warning","message":{"text":"bead_commit._mirror_bead_to_backends (cognitive 19): bead_commit._mirror_bead_to_backends has cognitive complexity 19 (threshold 15). Drivers by points: if/else 5 (8 pts), error handling 3 (6 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":"core_memory/runtime/post_write/bead_commit.py"},"region":{"startLine":35}}}],"partialFingerprints":{"codehealthFindingId/v1":"de6f49afaeff2db03193ebe30c06538f1eebaa7f00ef09ea236181b9220e912c"}},{"ruleId":"D2","level":"warning","message":{"text":"reauthoring._select_reauthor_sources (cognitive 19): reauthoring._select_reauthor_sources has cognitive complexity 19 (threshold 15). Drivers by points: if/else 7 (12 pts), boolean chains 5, 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":"core_memory/runtime/turn/reauthoring.py"},"region":{"startLine":358}}}],"partialFingerprints":{"codehealthFindingId/v1":"c480d09d8a8bbde4d35dc2bb1ce0e0f49fb19787757c8ba71f2c2238ea86b9e1"}},{"ruleId":"D2","level":"warning","message":{"text":"semantic_state.event_for_turn (cognitive 19): semantic_state.event_for_turn has cognitive complexity 19 (threshold 15). Drivers by points: if/else 5 (9 pts), boolean chains 7, 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":"core_memory/runtime/turn/semantic_state.py"},"region":{"startLine":285}}}],"partialFingerprints":{"codehealthFindingId/v1":"95388d47fa980a747304b7cd0b171568c06c81d9c1a25d143d2dff60245038ca"}},{"ruleId":"D2","level":"warning","message":{"text":"promotion.compute_promotion_score (cognitive 19): promotion.compute_promotion_score has cognitive complexity 19 (threshold 15). Drivers by points: if/else 8, boolean chains 7, error handling 1 (2 pts), ternaries 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":"core_memory/schema/promotion.py"},"region":{"startLine":129}}}],"partialFingerprints":{"codehealthFindingId/v1":"c4431c3f96cabf3ab301839264fcc873a5e3fd2d9bb3d963dab43eb7ea8011e4"}},{"ruleId":"D2","level":"warning","message":{"text":"rolling_window._ensure_type_diversity (cognitive 19): rolling_window._ensure_type_diversity has cognitive complexity 19 (threshold 15). Drivers by points: if/else 6 (11 pts), boolean chains 4, loops 3 (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":"core_memory/write_pipeline/rolling_window.py"},"region":{"startLine":100}}}],"partialFingerprints":{"codehealthFindingId/v1":"b2064062e9e7966251dd8eb504b6321f78b743c8fc7300f60988087585c3e13b"}},{"ruleId":"D2","level":"warning","message":{"text":"check_architecture_guards.check_upward_imports (cognitive 19): check_architecture_guards.check_upward_imports has cognitive complexity 19 (threshold 15). Drivers by points: if/else 4 (11 pts), boolean chains 3, loops 2 (3 pts), error handling 1 (2 pts) (nesting depth added 9). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"scripts/check_architecture_guards.py"},"region":{"startLine":407}}}],"partialFingerprints":{"codehealthFindingId/v1":"a858d5e247dd949fa63b479e687c3ab176ff5fa8f727f99fa5ac9786a5977b0f"}},{"ruleId":"D2","level":"warning","message":{"text":"conflict_review.resolution_to_claim_updates (cognitive 18): conflict_review.resolution_to_claim_updates has cognitive complexity 18 (threshold 15). Drivers by points: if/else 7 (11 pts), boolean chains 7 (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":"core_memory/claim/conflict_review.py"},"region":{"startLine":170}}}],"partialFingerprints":{"codehealthFindingId/v1":"8d535ca484bff150eabb82fb6479b65e648f720d0f7c45b02418a87a5960c1ad"}},{"ruleId":"D2","level":"warning","message":{"text":"setup.config_validate_command (cognitive 18): setup.config_validate_command has cognitive complexity 18 (threshold 15). Drivers by points: if/else 9 (13 pts), boolean chains 5 (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":"core_memory/cli/handlers/setup.py"},"region":{"startLine":811}}}],"partialFingerprints":{"codehealthFindingId/v1":"07daa5becf213513b8c5d5adbc25ce79ac63edcd472dd2b0f6712e35b344f03e"}},{"ruleId":"D2","level":"warning","message":{"text":"roadmap.sample_junction_identities (cognitive 18): roadmap.sample_junction_identities has cognitive complexity 18 (threshold 15). Drivers by points: boolean chains 12, if/else 4 (5 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":"core_memory/graph/roadmap.py"},"region":{"startLine":104}}}],"partialFingerprints":{"codehealthFindingId/v1":"db6e7ec9af0bb65ff1e83cc563cd2e899f83b131a0360bd81396c00fabdb6657"}},{"ruleId":"D2","level":"warning","message":{"text":"root_cause.segment_between (cognitive 18): root_cause.segment_between has cognitive complexity 18 (threshold 15). Drivers by points: if/else 8 (10 pts), boolean chains 5, ternaries 2, loops 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":"core_memory/graph/root_cause.py"},"region":{"startLine":1104}}}],"partialFingerprints":{"codehealthFindingId/v1":"21231a5b1a2ff99edee716a01eecbab2011b320826dd73a79add0ae3e807f32e"}},{"ruleId":"D2","level":"warning","message":{"text":"server.memory_association_candidate_decide (cognitive 18): server.memory_association_candidate_decide has cognitive complexity 18 (threshold 15). Drivers by points: boolean chains 17, if/else 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":"core_memory/integrations/http/server.py"},"region":{"startLine":2000}}}],"partialFingerprints":{"codehealthFindingId/v1":"01b9f8648436c0a5e4126d71b1adfefd080898f5b9bdd309236c3b48d9974716"}},{"ruleId":"D2","level":"warning","message":{"text":"capture.capture_handler (cognitive 18): capture.capture_handler has cognitive complexity 18 (threshold 15). Drivers by points: boolean chains 11, if/else 5, error handling 2. 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":"core_memory/integrations/mcp/tools/capture.py"},"region":{"startLine":35}}}],"partialFingerprints":{"codehealthFindingId/v1":"0d4751240b53d66548837c2d3032e256876616fa53a98dd9cd283c8357acc598"}},{"ruleId":"D2","level":"warning","message":{"text":"mapper.bead_to_node (cognitive 18): mapper.bead_to_node has cognitive complexity 18 (threshold 15). Drivers by points: boolean chains 17, if/else 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":"core_memory/integrations/neo4j/mapper.py"},"region":{"startLine":23}}}],"partialFingerprints":{"codehealthFindingId/v1":"46d8e6b55e95c7c3d6e7035822b190b5c50f8c94a10989de15d3a40d9e98a96e"}},{"ruleId":"D2","level":"warning","message":{"text":"promotion_service.apply_agent_promotion_reviews_for_store (cognitive 18): promotion_service.apply_agent_promotion_reviews_for_store has cognitive complexity 18 (threshold 15). Drivers by points: boolean chains 10, if/else 5 (7 pts), loops 1 (nesting depth added 2). 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":"core_memory/persistence/promotion_service.py"},"region":{"startLine":394}}}],"partialFingerprints":{"codehealthFindingId/v1":"fc28f0d0d168664027f6d71876797d5e64029414b42ce09e9c30ee52174b1422"}},{"ruleId":"D2","level":"warning","message":{"text":"semantic_task_receipts.summarize_semantic_task_runs (cognitive 18): semantic_task_receipts.summarize_semantic_task_runs has cognitive complexity 18 (threshold 15). Drivers by points: if/else 4 (7 pts), ternaries 5, boolean chains 4, loops 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":"core_memory/persistence/semantic_task_receipts.py"},"region":{"startLine":204}}}],"partialFingerprints":{"codehealthFindingId/v1":"bf04243fdc43c83b842bb168e6f764a04a88a711476b5ec92d1ec0607d831d04"}},{"ruleId":"D2","level":"warning","message":{"text":"store_claim_ops._append_claim_update_rows (cognitive 18): store_claim_ops._append_claim_update_rows has cognitive complexity 18 (threshold 15). Drivers by points: if/else 5 (9 pts), boolean chains 8, 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":"core_memory/persistence/store_claim_ops.py"},"region":{"startLine":305}}}],"partialFingerprints":{"codehealthFindingId/v1":"93ea340f132a9fc0a7f281ac704947e98e1875f2c84f89adff571b01a7d1c495"}},{"ruleId":"D2","level":"warning","message":{"text":"store_constraints.active_constraints_for_store (cognitive 18): store_constraints.active_constraints_for_store has cognitive complexity 18 (threshold 15). Drivers by points: if/else 6 (13 pts), boolean chains 4, 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":"core_memory/persistence/store_constraints.py"},"region":{"startLine":8}}}],"partialFingerprints":{"codehealthFindingId/v1":"5bd29c75bf8f92979386b7fa8530c6eab97ebf69e167579e0959f9c1e996ce63"}},{"ruleId":"D2","level":"warning","message":{"text":"store_text_hygiene_ops.extract_constraints_for_store (cognitive 18): store_text_hygiene_ops.extract_constraints_for_store has cognitive complexity 18 (threshold 15). Drivers by points: if/else 8 (14 pts), boolean chains 3, 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":"core_memory/persistence/store_text_hygiene_ops.py"},"region":{"startLine":94}}}],"partialFingerprints":{"codehealthFindingId/v1":"ee8a5515eeeb5337703fb1939563a4b2c4f9a1ea6e6c785c28d71313057f521b"}},{"ruleId":"D2","level":"warning","message":{"text":"hygiene.extract_constraints (cognitive 18): hygiene.extract_constraints has cognitive complexity 18 (threshold 15). Drivers by points: if/else 8 (14 pts), boolean chains 3, 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":"core_memory/policy/hygiene.py"},"region":{"startLine":139}}}],"partialFingerprints":{"codehealthFindingId/v1":"cb095a6aa7c627390e63302f2890e00c1c9ffaa65b982ab523eed083e7a554ae"}},{"ruleId":"D2","level":"warning","message":{"text":"incidents.incident_match_strength (cognitive 18): incidents.incident_match_strength has cognitive complexity 18 (threshold 15). Drivers by points: if/else 4 (9 pts), loops 3 (5 pts), boolean chains 4 (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":"core_memory/policy/incidents.py"},"region":{"startLine":36}}}],"partialFingerprints":{"codehealthFindingId/v1":"11627b7a79110b20e545af1eb7c2c57cb8f05ae656a6a3fc31d0f71bce47b724"}},{"ruleId":"D2","level":"warning","message":{"text":"semantic_task_verifier._deterministic_checks (cognitive 18): semantic_task_verifier._deterministic_checks has cognitive complexity 18 (threshold 15). Drivers by points: if/else 7 (9 pts), boolean chains 4, ternaries 4, loops 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":"core_memory/policy/semantic_task_verifier.py"},"region":{"startLine":84}}}],"partialFingerprints":{"codehealthFindingId/v1":"f7987c863f43f35dde3a0e853bf26713ae5aa3ce11d4bd022ce86eda743d25ac"}},{"ruleId":"D2","level":"warning","message":{"text":"causal_recall.execute_state_packet (cognitive 18): causal_recall.execute_state_packet has cognitive complexity 18 (threshold 15). Drivers by points: if/else 8, boolean chains 7, ternaries 2, error handling 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":"core_memory/retrieval/causal_recall.py"},"region":{"startLine":387}}}],"partialFingerprints":{"codehealthFindingId/v1":"7f670226d9c71c55afc1742c503708cdf28da68bf17b568465ad35dca2589496"}},{"ruleId":"D2","level":"warning","message":{"text":"pipeline._append_structural_chains (cognitive 18): pipeline._append_structural_chains has cognitive complexity 18 (threshold 15). Drivers by points: if/else 7 (9 pts), boolean chains 8, ternaries 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":"core_memory/retrieval/pipeline/__init__.py"},"region":{"startLine":80}}}],"partialFingerprints":{"codehealthFindingId/v1":"3d7b3e7911bb85f82c5630d84cd07a9197453b5fc474a1efb3314df86906a036"}},{"ruleId":"D2","level":"warning","message":{"text":"QdrantBackend.search (cognitive 18): QdrantBackend.search has cognitive complexity 18 (threshold 15). Drivers by points: if/else 8 (15 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":"core_memory/retrieval/vector_backend.py"},"region":{"startLine":187}}}],"partialFingerprints":{"codehealthFindingId/v1":"b4c1183b8ed3099ab1c8288d35c1862c289ce3cdac9220b6d1430a63325c8ea9"}},{"ruleId":"D2","level":"warning","message":{"text":"goal_decay.detect_goal_decay (cognitive 18): goal_decay.detect_goal_decay has cognitive complexity 18 (threshold 15). Drivers by points: if/else 6 (9 pts), boolean chains 6, loops 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":"core_memory/runtime/dreamer/goal_decay.py"},"region":{"startLine":72}}}],"partialFingerprints":{"codehealthFindingId/v1":"be3850fd056406c5636f5a61f10f944da55da525b62357b9792ed0376f1b6d28"}},{"ruleId":"D2","level":"warning","message":{"text":"goal_discovery.detect_latent_goals (cognitive 18): goal_discovery.detect_latent_goals has cognitive complexity 18 (threshold 15). Drivers by points: if/else 4 (8 pts), boolean chains 5, loops 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":"core_memory/runtime/dreamer/goal_discovery.py"},"region":{"startLine":86}}}],"partialFingerprints":{"codehealthFindingId/v1":"9816c3eed06f6d7debbbb3b1ddf23df481e6d8ebe2a6c10a80e0ba7df49ef6a8"}},{"ruleId":"D2","level":"warning","message":{"text":"flush_state.upsert_process_flush_checkpoint_bead (cognitive 18): flush_state.upsert_process_flush_checkpoint_bead has cognitive complexity 18 (threshold 15). Drivers by points: boolean chains 13, if/else 2 (4 pts), loops 1 (nesting depth added 2). 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":"core_memory/runtime/flush/flush_state.py"},"region":{"startLine":34}}}],"partialFingerprints":{"codehealthFindingId/v1":"b4aadf2b673cddd28ae2f251d33517e7305a17d9b6aff62507c419ff726facc7"}},{"ruleId":"D2","level":"warning","message":{"text":"myelination.apply_contradiction_decay (cognitive 18): myelination.apply_contradiction_decay has cognitive complexity 18 (threshold 15). Drivers by points: if/else 4 (9 pts), boolean chains 5, loops 2 (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":"core_memory/runtime/observability/myelination.py"},"region":{"startLine":206}}}],"partialFingerprints":{"codehealthFindingId/v1":"9818d7952bbc0a61f602bb650c8ca830f375965e0986989be7c4f2a1a962bbc9"}},{"ruleId":"D2","level":"warning","message":{"text":"ingress._normalize_mesh_trace (cognitive 18): ingress._normalize_mesh_trace has cognitive complexity 18 (threshold 15). Drivers by points: boolean chains 11, if/else 3 (6 pts), loops 1 (nesting depth added 3). 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":"core_memory/runtime/turn/ingress.py"},"region":{"startLine":53}}}],"partialFingerprints":{"codehealthFindingId/v1":"2fe54e196f4f14b956534163b8100cbbc634752c40c524eb420404f5ad81b395"}},{"ruleId":"D2","level":"warning","message":{"text":"reauthoring.semantic_backfill_report (cognitive 18): reauthoring.semantic_backfill_report has cognitive complexity 18 (threshold 15). Drivers by points: if/else 5 (9 pts), boolean chains 3, error handling 1 (3 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":"core_memory/runtime/turn/reauthoring.py"},"region":{"startLine":304}}}],"partialFingerprints":{"codehealthFindingId/v1":"e955108801830f47c25a9d420fca6afe4627e66af679923e437bc9eec1b34a19"}},{"ruleId":"D2","level":"warning","message":{"text":"storyline_overlay.validate_storyline_overlay (cognitive 18): storyline_overlay.validate_storyline_overlay has cognitive complexity 18 (threshold 15). Drivers by points: if/else 9, boolean chains 8, error handling 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":"core_memory/schema/storyline_overlay.py"},"region":{"startLine":40}}}],"partialFingerprints":{"codehealthFindingId/v1":"82aa9827ca9b521b0ba492f84033c7ed863a61d3a26c30826435305f6ff59c97"}},{"ruleId":"D2","level":"warning","message":{"text":"goals.list_goals (cognitive 18): goals.list_goals has cognitive complexity 18 (threshold 15). Drivers by points: boolean chains 9, if/else 4 (8 pts), loops 1 (nesting depth added 4). 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":"core_memory/soul/goals.py"},"region":{"startLine":152}}}],"partialFingerprints":{"codehealthFindingId/v1":"a2ecd0f0ae968129dccebe03495f85c09eb6abf415b31d7e82fea979971c1ba5"}},{"ruleId":"D2","level":"warning","message":{"text":"transcript_ingest._associations_created_summary (cognitive 18): transcript_ingest._associations_created_summary has cognitive complexity 18 (threshold 15). Drivers by points: boolean chains 8, if/else 4 (6 pts), loops 2, error handling 1, ternaries 1 (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":"core_memory/transcript_ingest.py"},"region":{"startLine":429}}}],"partialFingerprints":{"codehealthFindingId/v1":"6c3088cf5df55c045115e46a60f211cbbb57522165ae046fecd10dabdaadaf90"}},{"ruleId":"D2","level":"warning","message":{"text":"paraphrase_eval._anchor_hit (cognitive 18): paraphrase_eval._anchor_hit has cognitive complexity 18 (threshold 15). Drivers by points: boolean chains 10, if/else 5 (7 pts), loops 1 (nesting depth added 2). 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":"eval/paraphrase_eval.py"},"region":{"startLine":36}}}],"partialFingerprints":{"codehealthFindingId/v1":"456eddfb655121f4ec7ab6b78c585ba2ab4da357c29a65884e1cd4b136b4cc5b"}},{"ruleId":"D2","level":"warning","message":{"text":"retrieval_eval.main (cognitive 18): retrieval_eval.main has cognitive complexity 18 (threshold 15). Drivers by points: ternaries 6 (8 pts), boolean chains 4, if/else 1 (3 pts), loops 2 (3 pts) (nesting depth added 5). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"eval/retrieval_eval.py"},"region":{"startLine":73}}}],"partialFingerprints":{"codehealthFindingId/v1":"1d4cf7cfed4688c6f5b078219acdb65666bb06a458010252c41aa5c30286ebe6"}},{"ruleId":"D2","level":"warning","message":{"text":"migrate._iter_all_beads (cognitive 17): migrate._iter_all_beads has cognitive complexity 17 (threshold 15). Drivers by points: if/else 3 (8 pts), error handling 2 (4 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":"core_memory/cli/handlers/migrate.py"},"region":{"startLine":12}}}],"partialFingerprints":{"codehealthFindingId/v1":"aa777a7d816f4c79b360e2afd2dfaa5db94e3398bd39355ac411650602327c81"}},{"ruleId":"D2","level":"warning","message":{"text":"setup._storage_probe (cognitive 17): setup._storage_probe has cognitive complexity 17 (threshold 15). Drivers by points: error handling 4 (7 pts), if/else 5 (6 pts), boolean chains 3, 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":"core_memory/cli/handlers/setup.py"},"region":{"startLine":287}}}],"partialFingerprints":{"codehealthFindingId/v1":"4773a63d621f0c054085fbc9427075767c8abb7824ebb9a30e6ed98ed61e599c"}},{"ruleId":"D2","level":"warning","message":{"text":"root_cause._source_tokens (cognitive 17): root_cause._source_tokens has cognitive complexity 17 (threshold 15). Drivers by points: if/else 4 (10 pts), loops 4 (6 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":"core_memory/graph/root_cause.py"},"region":{"startLine":346}}}],"partialFingerprints":{"codehealthFindingId/v1":"2b3abdf56c19a615f72134918976af154ca117c18cdb6095f46e48b244dec397"}},{"ruleId":"D2","level":"warning","message":{"text":"traversal.causal_traverse (cognitive 17): traversal.causal_traverse has cognitive complexity 17 (threshold 15). Drivers by points: if/else 4 (9 pts), boolean chains 4, loops 2 (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":"core_memory/graph/traversal.py"},"region":{"startLine":167}}}],"partialFingerprints":{"codehealthFindingId/v1":"3665b3133152b31339d19d9077e30a833f7ef156555d08b0b7c8341c21e8e90f"}},{"ruleId":"D2","level":"warning","message":{"text":"server.memory_association_runs (cognitive 17): server.memory_association_runs has cognitive complexity 17 (threshold 15). Drivers by points: boolean chains 15, if/else 2. 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":"core_memory/integrations/http/server.py"},"region":{"startLine":2034}}}],"partialFingerprints":{"codehealthFindingId/v1":"be6e3535e79608211bbe340d2cecd9df5a9d58e94fc21f5688c9e66a69a384bd"}},{"ruleId":"D2","level":"warning","message":{"text":"ingest_zoom._parse_otter (cognitive 17): ingest_zoom._parse_otter has cognitive complexity 17 (threshold 15). Drivers by points: if/else 4 (6 pts), boolean chains 4, ternaries 2 (4 pts), 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":"core_memory/integrations/mcp/tools/ingest_zoom.py"},"region":{"startLine":86}}}],"partialFingerprints":{"codehealthFindingId/v1":"fbec59ea14e4ad20dacd9b005fda699a3e4915037109f494d61e6d9a992dcec5"}},{"ruleId":"D2","level":"warning","message":{"text":"management._resolve_rereview_beads (cognitive 17): management._resolve_rereview_beads has cognitive complexity 17 (threshold 15). Drivers by points: if/else 5 (9 pts), boolean chains 4, loops 2 (3 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":"core_memory/management/__init__.py"},"region":{"startLine":668}}}],"partialFingerprints":{"codehealthFindingId/v1":"d5c52886caf0ac8c219dc3c0b905c233c6c7b7a0730f42e8f53829a47c1d19d9"}},{"ruleId":"D2","level":"warning","message":{"text":"JsonFileBackend.query_beads (cognitive 17): JsonFileBackend.query_beads has cognitive complexity 17 (threshold 15). Drivers by points: if/else 7 (16 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":"core_memory/persistence/backend.py"},"region":{"startLine":158}}}],"partialFingerprints":{"codehealthFindingId/v1":"0ac49cc433831d1cde119f18ed0361bc21d85620452ad6fb66b96e7ae9761cc6"}},{"ruleId":"D2","level":"warning","message":{"text":"dreamer_candidate_store.make_candidate_row (cognitive 17): dreamer_candidate_store.make_candidate_row has cognitive complexity 17 (threshold 15). Drivers by points: boolean chains 15, if/else 1, ternaries 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":"core_memory/persistence/dreamer_candidate_store.py"},"region":{"startLine":102}}}],"partialFingerprints":{"codehealthFindingId/v1":"fe5cc716b10e6e88fd79ef40adfa7b92eb1cb36227f8b37470bad070c893cfbe"}},{"ruleId":"D2","level":"warning","message":{"text":"myelination_rewards.read_reward_events (cognitive 17): myelination_rewards.read_reward_events has cognitive complexity 17 (threshold 15). Drivers by points: if/else 6 (11 pts), boolean chains 3, error handling 1 (2 pts), loops 1 (nesting depth added 6). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"core_memory/persistence/myelination_rewards.py"},"region":{"startLine":600}}}],"partialFingerprints":{"codehealthFindingId/v1":"aae90ddb89a2a7a5bd2f37bd081955c9ffe237f207ff7d4a7162534f8e69b31c"}},{"ruleId":"D2","level":"warning","message":{"text":"store_add_helpers.detect_decision_conflicts_for_store (cognitive 17): store_add_helpers.detect_decision_conflicts_for_store 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":"core_memory/persistence/store_add_helpers.py"},"region":{"startLine":63}}}],"partialFingerprints":{"codehealthFindingId/v1":"8bce0598a2e5419483ec0defeb1e8e422fcd44e37cff909b003b40180bc7c472"}},{"ruleId":"D2","level":"warning","message":{"text":"store_claim_ops._normalize_claim_update_rows (cognitive 17): store_claim_ops._normalize_claim_update_rows has cognitive complexity 17 (threshold 15). Drivers by points: if/else 3 (6 pts), boolean chains 5, error handling 2 (5 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":"core_memory/persistence/store_claim_ops.py"},"region":{"startLine":150}}}],"partialFingerprints":{"codehealthFindingId/v1":"0914514527f9e455da5b35d26378d800a4acbf75403c3bc41c838c2d002f552c"}},{"ruleId":"D2","level":"warning","message":{"text":"store_reporting.autonomy_report_for_store (cognitive 17): store_reporting.autonomy_report_for_store has cognitive complexity 17 (threshold 15). Drivers by points: if/else 5 (9 pts), boolean chains 3, error handling 1 (3 pts), 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":"core_memory/persistence/store_reporting.py"},"region":{"startLine":77}}}],"partialFingerprints":{"codehealthFindingId/v1":"5c36d4882185b2743eb6eebee198aacf0e589a443ab358d427843aa68b47f748"}},{"ruleId":"D2","level":"warning","message":{"text":"causal_recall._source_tokens (cognitive 17): causal_recall._source_tokens has cognitive complexity 17 (threshold 15). Drivers by points: if/else 4 (10 pts), loops 4 (6 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":"core_memory/retrieval/causal_recall.py"},"region":{"startLine":101}}}],"partialFingerprints":{"codehealthFindingId/v1":"54d49032452e14fa02fec6a1cea7375724634024ed2a33f82ea6df0061dc552c"}},{"ruleId":"D2","level":"warning","message":{"text":"evidence_scoring._temporal_fit (cognitive 17): evidence_scoring._temporal_fit has cognitive complexity 17 (threshold 15). Drivers by points: if/else 7 (11 pts), boolean chains 5, 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":"core_memory/retrieval/evidence_scoring.py"},"region":{"startLine":68}}}],"partialFingerprints":{"codehealthFindingId/v1":"68ea7c6a42f21cfddc4af2677c114e3c81f195fece685142bf0aca8cc03c72ff"}},{"ruleId":"D2","level":"warning","message":{"text":"canonical._normalize_public_hydration_request (cognitive 17): canonical._normalize_public_hydration_request has cognitive complexity 17 (threshold 15). Drivers by points: if/else 8 (9 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":"core_memory/retrieval/pipeline/canonical.py"},"region":{"startLine":380}}}],"partialFingerprints":{"codehealthFindingId/v1":"ebd45d9b0c6ef26b715c8cba17d533714537ad700c4f50afb40b9082eba67388"}},{"ruleId":"D2","level":"warning","message":{"text":"canonical._metadata_filter_matches (cognitive 17): canonical._metadata_filter_matches has cognitive complexity 17 (threshold 15). Drivers by points: if/else 5 (9 pts), boolean chains 5, ternaries 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":"core_memory/retrieval/pipeline/canonical.py"},"region":{"startLine":682}}}],"partialFingerprints":{"codehealthFindingId/v1":"1def6d3bb8bc7b7127a428c80619d3caa9be5239d32e8b8e167aa5c36e219332"}},{"ruleId":"D2","level":"warning","message":{"text":"coverage._dedupe_candidate_rows (cognitive 17): coverage._dedupe_candidate_rows has cognitive complexity 17 (threshold 15). Drivers by points: boolean chains 10, if/else 3 (6 pts), loops 1 (nesting depth added 3). 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":"core_memory/runtime/associations/coverage.py"},"region":{"startLine":1208}}}],"partialFingerprints":{"codehealthFindingId/v1":"f9345392be32277973cfa955e8c88a2871ae7747bc555228a22d6ed59fb4072f"}},{"ruleId":"D2","level":"warning","message":{"text":"coverage.association_judge_readiness (cognitive 17): coverage.association_judge_readiness has cognitive complexity 17 (threshold 15). Drivers by points: boolean chains 8, if/else 6 (7 pts), 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":"core_memory/runtime/associations/coverage.py"},"region":{"startLine":1525}}}],"partialFingerprints":{"codehealthFindingId/v1":"aed2449e207f6084581996778dd1c2b960a4ca66c6faed8376fdf14fae21bde6"}},{"ruleId":"D2","level":"warning","message":{"text":"coverage._build_judge_context (cognitive 17): coverage._build_judge_context has cognitive complexity 17 (threshold 15). Drivers by points: boolean chains 7, if/else 4 (6 pts), loops 3 (4 pts) (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":"core_memory/runtime/associations/coverage.py"},"region":{"startLine":1708}}}],"partialFingerprints":{"codehealthFindingId/v1":"9274ea163cde886378ed6934692a31e32f081afbe6ef36bf3cadf13c9f212ecd"}},{"ruleId":"D2","level":"warning","message":{"text":"progress._pair_rows (cognitive 17): progress._pair_rows has cognitive complexity 17 (threshold 15). Drivers by points: boolean chains 7, if/else 4, loops 2 (3 pts), ternaries 1 (3 pts) (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":"core_memory/runtime/goals/progress.py"},"region":{"startLine":138}}}],"partialFingerprints":{"codehealthFindingId/v1":"44b63acc5e10ed87080c2481ab461debf9b7b07ecb833c2744b8646546c577f9"}},{"ruleId":"D2","level":"warning","message":{"text":"progress._process_goal_progress_pair_page (cognitive 17): progress._process_goal_progress_pair_page has cognitive complexity 17 (threshold 15). Drivers by points: boolean chains 13, if/else 3, ternaries 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":"core_memory/runtime/goals/progress.py"},"region":{"startLine":743}}}],"partialFingerprints":{"codehealthFindingId/v1":"478f0232ac7d32cd28190fdb68e21da2a9218356265227fe3c4b80fbec06209b"}},{"ruleId":"D2","level":"warning","message":{"text":"source_envelope.normalize_source_ingest_envelope (cognitive 17): source_envelope.normalize_source_ingest_envelope has cognitive complexity 17 (threshold 15). Drivers by points: boolean chains 8, if/else 6 (7 pts), loops 1, ternaries 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":"core_memory/runtime/ingest/source_envelope.py"},"region":{"startLine":111}}}],"partialFingerprints":{"codehealthFindingId/v1":"05e686779cc048f0a991c2734ea65bf7c93844555e259f67242f97e7a83f4032"}},{"ruleId":"D2","level":"warning","message":{"text":"reauthoring._attach_maintenance_provenance (cognitive 17): reauthoring._attach_maintenance_provenance has cognitive complexity 17 (threshold 15). Drivers by points: if/else 4 (7 pts), boolean chains 6, ternaries 2 (3 pts), loops 1 (nesting depth added 4). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"core_memory/runtime/turn/reauthoring.py"},"region":{"startLine":412}}}],"partialFingerprints":{"codehealthFindingId/v1":"d0c8500e263b4ca07a58fac9c9a5756cc10bc4849ec22d99e4510ab6ef22ae04"}},{"ruleId":"D2","level":"warning","message":{"text":"receipt._queue_receipt (cognitive 17): receipt._queue_receipt has cognitive complexity 17 (threshold 15). Drivers by points: boolean chains 9, if/else 5 (7 pts), loops 1 (nesting depth added 2). 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":"core_memory/runtime/turn/receipt.py"},"region":{"startLine":76}}}],"partialFingerprints":{"codehealthFindingId/v1":"b71f9cf56352f514a86907a81eb0777d0048c893dcf15fe38bab855913b45d3a"}},{"ruleId":"D2","level":"warning","message":{"text":"turn_quality.emit_agent_turn_quality_metric (cognitive 17): turn_quality.emit_agent_turn_quality_metric has cognitive complexity 17 (threshold 15). Drivers by points: boolean chains 16, error handling 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":"core_memory/runtime/turn/turn_quality.py"},"region":{"startLine":34}}}],"partialFingerprints":{"codehealthFindingId/v1":"195c83535f39820b7e9ddac34ae20d06fe56efa6d52f617f9d4cd6415ee9764b"}},{"ruleId":"D2","level":"warning","message":{"text":"integrity.soul_integrity_repair (cognitive 17): integrity.soul_integrity_repair has cognitive complexity 17 (threshold 15). Drivers by points: if/else 5 (10 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":"core_memory/soul/integrity.py"},"region":{"startLine":140}}}],"partialFingerprints":{"codehealthFindingId/v1":"cdc16c98782ae230b9ad8866756499a285cbe437923c3458db5aaf4db6d447a1"}},{"ruleId":"D2","level":"warning","message":{"text":"store.apply_soul_update (cognitive 17): store.apply_soul_update has cognitive complexity 17 (threshold 15). Drivers by points: boolean chains 10, if/else 6 (7 pts) (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":"core_memory/soul/store.py"},"region":{"startLine":306}}}],"partialFingerprints":{"codehealthFindingId/v1":"7091b1b1f8c31efeb4668acc2d99093e6ba9eab054872e60ed0a6e21004a237d"}},{"ruleId":"D2","level":"warning","message":{"text":"retrieval_planner.boost_claim_results (cognitive 16): retrieval_planner.boost_claim_results has cognitive complexity 16 (threshold 15). Drivers by points: boolean chains 8, if/else 5 (7 pts), loops 1 (nesting depth added 2). 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":"core_memory/claim/retrieval_planner.py"},"region":{"startLine":135}}}],"partialFingerprints":{"codehealthFindingId/v1":"ecc9a69cab6ea7c64b2a48fb1f68bf7846ea6c8fa143f62b1217b2e747a36521"}},{"ruleId":"D2","level":"warning","message":{"text":"root_cause.normalize_causal_hints (cognitive 16): root_cause.normalize_causal_hints has cognitive complexity 16 (threshold 15). Drivers by points: boolean chains 8, if/else 8. 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":"core_memory/graph/root_cause.py"},"region":{"startLine":98}}}],"partialFingerprints":{"codehealthFindingId/v1":"bbf91db6f5f93c350890c477c91d00a92c72aa902004cac2d598e2de56698c3b"}},{"ruleId":"D2","level":"warning","message":{"text":"root_cause._trace_package (cognitive 16): root_cause._trace_package has cognitive complexity 16 (threshold 15). Drivers by points: if/else 4 (8 pts), boolean chains 4, loops 2, 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":"core_memory/graph/root_cause.py"},"region":{"startLine":788}}}],"partialFingerprints":{"codehealthFindingId/v1":"ee097630f9492b0b287315cc2f286bead3cf06ff6583109876a617769b17457a"}},{"ruleId":"D2","level":"warning","message":{"text":"root_cause._junction_members (cognitive 16): root_cause._junction_members has cognitive complexity 16 (threshold 15). Drivers by points: if/else 7 (14 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":"core_memory/graph/root_cause.py"},"region":{"startLine":836}}}],"partialFingerprints":{"codehealthFindingId/v1":"4c43775d2e55c93d4f4a47e7b7e5b0cb2fa52c44b560c8aa73015ecfd7cf2b0f"}},{"ruleId":"D2","level":"warning","message":{"text":"ingest_discord._parse_message (cognitive 16): ingest_discord._parse_message has cognitive complexity 16 (threshold 15). Drivers by points: boolean chains 10, if/else 6. 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":"core_memory/integrations/mcp/tools/ingest_discord.py"},"region":{"startLine":25}}}],"partialFingerprints":{"codehealthFindingId/v1":"0dce4675c7ecc81c3dcdd3f7da2f88f648bd44f182741c91300a0feb14cdf837"}},{"ruleId":"D2","level":"warning","message":{"text":"status.status_handler (cognitive 16): status.status_handler has cognitive complexity 16 (threshold 15). Drivers by points: boolean chains 11, if/else 2 (3 pts), error handling 1, ternaries 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":"core_memory/integrations/mcp/tools/status.py"},"region":{"startLine":40}}}],"partialFingerprints":{"codehealthFindingId/v1":"e06a9ae33f22beef69b5b59dca203f18c0b1f815b36471c4a99d9f58c7c0697f"}},{"ruleId":"D2","level":"warning","message":{"text":"Neo4jClient._prune_scope (cognitive 16): Neo4jClient._prune_scope has cognitive complexity 16 (threshold 15). Drivers by points: boolean chains 14, if/else 2. 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":"core_memory/integrations/neo4j/client.py"},"region":{"startLine":305}}}],"partialFingerprints":{"codehealthFindingId/v1":"3fe81247f8c769b734e2c696926e9694dfaf843418e3531764620c4bbd511de5"}},{"ruleId":"D2","level":"warning","message":{"text":"agent_end_bridge._extract_trace_list (cognitive 16): agent_end_bridge._extract_trace_list has cognitive complexity 16 (threshold 15). Drivers by points: ternaries 2 (7 pts), if/else 3 (6 pts), loops 2 (3 pts) (nesting depth added 9). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"core_memory/integrations/openclaw/agent_end_bridge.py"},"region":{"startLine":134}}}],"partialFingerprints":{"codehealthFindingId/v1":"cb066816dc92e950b6e6ae6148d4db462fa92f5220e05a8292162a8b3ee914fa"}},{"ruleId":"D2","level":"warning","message":{"text":"archive_index.rebuild_archive_index (cognitive 16): archive_index.rebuild_archive_index has cognitive complexity 16 (threshold 15). Drivers by points: if/else 4 (10 pts), error handling 1 (3 pts), loops 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":"core_memory/persistence/archive_index.py"},"region":{"startLine":90}}}],"partialFingerprints":{"codehealthFindingId/v1":"0948c89745ab5e6b834ad52b8434e71ca320152f07261bbb5e3e42979839008f"}},{"ruleId":"D2","level":"warning","message":{"text":"calibration._judge_prior_by_edge_key (cognitive 16): calibration._judge_prior_by_edge_key has cognitive complexity 16 (threshold 15). Drivers by points: boolean chains 5, if/else 3 (5 pts), error handling 2 (3 pts), 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":"core_memory/persistence/calibration.py"},"region":{"startLine":56}}}],"partialFingerprints":{"codehealthFindingId/v1":"191686b91f86e9555ab0aa1ae6cfdd5a2ef92ec16295b4467e792519abce00ab"}},{"ruleId":"D2","level":"warning","message":{"text":"entity_merge_flow._entity_similarity (cognitive 16): entity_merge_flow._entity_similarity has cognitive complexity 16 (threshold 15). Drivers by points: boolean chains 8, if/else 6 (7 pts), ternaries 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":"core_memory/persistence/entity_merge_flow.py"},"region":{"startLine":24}}}],"partialFingerprints":{"codehealthFindingId/v1":"4c8f6b2d858979cdf266f3bbb238686db28834a3ba28980075de121302abad65"}},{"ruleId":"D2","level":"warning","message":{"text":"myelination_rewards.reward_dreamer_candidate_decision (cognitive 16): myelination_rewards.reward_dreamer_candidate_decision has cognitive complexity 16 (threshold 15). Drivers by points: boolean chains 10, if/else 5, ternaries 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":"core_memory/persistence/myelination_rewards.py"},"region":{"startLine":427}}}],"partialFingerprints":{"codehealthFindingId/v1":"aa07e19be3217e30dc5ee16def044c068f5c0c265f708939f71f1a3bd92e9323"}},{"ruleId":"D2","level":"warning","message":{"text":"myelination_rewards.reward_soul_authoring_decision (cognitive 16): myelination_rewards.reward_soul_authoring_decision has cognitive complexity 16 (threshold 15). Drivers by points: if/else 4 (6 pts), boolean chains 5, 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":"core_memory/persistence/myelination_rewards.py"},"region":{"startLine":473}}}],"partialFingerprints":{"codehealthFindingId/v1":"ded61f61e5b139cd01d56ef21ca92c396ec2f54584ab5a0cc96061ea6e0d27ce"}},{"ruleId":"D2","level":"warning","message":{"text":"retrieval_feedback.read_retrieval_feedback (cognitive 16): retrieval_feedback.read_retrieval_feedback has cognitive complexity 16 (threshold 15). Drivers by points: if/else 6 (11 pts), boolean chains 2, error handling 1 (2 pts), loops 1 (nesting depth added 6). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"core_memory/persistence/retrieval_feedback.py"},"region":{"startLine":148}}}],"partialFingerprints":{"codehealthFindingId/v1":"9caf52e794a934dc0fbdffb95fdfa9fd104a07abd014e8f01557104cd7b73d8e"}},{"ruleId":"D2","level":"warning","message":{"text":"semantic_task_receipts._compact_run (cognitive 16): semantic_task_receipts._compact_run has cognitive complexity 16 (threshold 15). Drivers by points: boolean chains 15, ternaries 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":"core_memory/persistence/semantic_task_receipts.py"},"region":{"startLine":161}}}],"partialFingerprints":{"codehealthFindingId/v1":"9e525a00f8a08e12c1c1203b951e468f44c347cdda2c20262ef6c4bc9236f621"}},{"ruleId":"D2","level":"warning","message":{"text":"ProviderSemanticTaskRuntime.run (cognitive 16): ProviderSemanticTaskRuntime.run has cognitive complexity 16 (threshold 15). Drivers by points: boolean chains 12, if/else 2, error handling 1, ternaries 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":"core_memory/policy/semantic_task_runtime.py"},"region":{"startLine":254}}}],"partialFingerprints":{"codehealthFindingId/v1":"c027ead9147f0b11e7bb301ee8703e6794decc11661844ca2f4557c4eda4ea80"}},{"ruleId":"D2","level":"warning","message":{"text":"lexical._field_tokens (cognitive 16): lexical._field_tokens has cognitive complexity 16 (threshold 15). Drivers by points: boolean chains 9, if/else 2 (5 pts), loops 2 (nesting depth added 3). 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":"core_memory/retrieval/lexical.py"},"region":{"startLine":84}}}],"partialFingerprints":{"codehealthFindingId/v1":"40db1a4f83a7cb7a0e779a551bdf9059f234c9ff0e65d8027431c81ed9889966"}},{"ruleId":"D2","level":"warning","message":{"text":"memory_reason._synthesize_why_answer_from_chains (cognitive 16): memory_reason._synthesize_why_answer_from_chains has cognitive complexity 16 (threshold 15). Drivers by points: if/else 6 (9 pts), boolean chains 5, loops 1, ternaries 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":"core_memory/retrieval/tools/memory_reason.py"},"region":{"startLine":318}}}],"partialFingerprints":{"codehealthFindingId/v1":"736c53d4a891f74ed4764d5ff219ab9caa9a7fdac8adc38075c93721137400f2"}},{"ruleId":"D2","level":"warning","message":{"text":"PgvectorBackend.search (cognitive 16): PgvectorBackend.search has cognitive complexity 16 (threshold 15). Drivers by points: if/else 6 (11 pts), ternaries 2 (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":"core_memory/retrieval/vector_backend.py"},"region":{"startLine":463}}}],"partialFingerprints":{"codehealthFindingId/v1":"3cb17008e4af0ed107bc670ed956ef0dabfb1d81302cee12285d66ec32ca5f86"}},{"ruleId":"D2","level":"warning","message":{"text":"coverage._normalized_string_set (cognitive 16): coverage._normalized_string_set has cognitive complexity 16 (threshold 15). Drivers by points: if/else 6 (12 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":"core_memory/runtime/associations/coverage.py"},"region":{"startLine":913}}}],"partialFingerprints":{"codehealthFindingId/v1":"4fee97572fec6c9e24479c87a191fd850ad3af79c1c35b8bac3a8d8e6afcf2b2"}},{"ruleId":"D2","level":"warning","message":{"text":"coverage._candidate_association_payload (cognitive 16): coverage._candidate_association_payload has cognitive complexity 16 (threshold 15). Drivers by points: boolean chains 11, if/else 3, ternaries 2. 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":"core_memory/runtime/associations/coverage.py"},"region":{"startLine":1808}}}],"partialFingerprints":{"codehealthFindingId/v1":"470e2778b3037e2cd82dae9f28e768dbbd00cce456154412e27a5c6112f865a7"}},{"ruleId":"D2","level":"warning","message":{"text":"coverage._select_sweep_bead_ids (cognitive 16): coverage._select_sweep_bead_ids has cognitive complexity 16 (threshold 15). Drivers by points: if/else 5 (7 pts), boolean chains 6, loops 1 (2 pts), ternaries 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":"core_memory/runtime/associations/coverage.py"},"region":{"startLine":2138}}}],"partialFingerprints":{"codehealthFindingId/v1":"c103b45970d45bb35d77df1b3c9180b4428823f1eba54edb6eff97f618f697d5"}},{"ruleId":"D2","level":"warning","message":{"text":"convergence.enqueue_narrative_candidates (cognitive 16): convergence.enqueue_narrative_candidates has cognitive complexity 16 (threshold 15). Drivers by points: if/else 5 (8 pts), boolean chains 5, loops 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":"core_memory/runtime/dreamer/convergence.py"},"region":{"startLine":140}}}],"partialFingerprints":{"codehealthFindingId/v1":"109fb8ea28d19c26022a3c566234091965a20a3a04f62c7fef4cf820f9c1a936"}},{"ruleId":"D2","level":"warning","message":{"text":"dreamer_bridge._maybe_auto_endorse_goal (cognitive 16): dreamer_bridge._maybe_auto_endorse_goal has cognitive complexity 16 (threshold 15). Drivers by points: boolean chains 9, if/else 6, error handling 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":"core_memory/soul/dreamer_bridge.py"},"region":{"startLine":277}}}],"partialFingerprints":{"codehealthFindingId/v1":"0534ace6b00900b4b472461a1abca189b14d893c39ce649b7c7331ed1174b322"}},{"ruleId":"D2","level":"warning","message":{"text":"transcript_ingest.ingest_transcript (cognitive 16): transcript_ingest.ingest_transcript has cognitive complexity 16 (threshold 15). Drivers by points: boolean chains 14, if/else 2. 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":"core_memory/transcript_ingest.py"},"region":{"startLine":545}}}],"partialFingerprints":{"codehealthFindingId/v1":"0dd3f33722b52332f2174ae6a57c039a9f8c92c496de29ae7a1fdef09de80cbd"}},{"ruleId":"D2","level":"warning","message":{"text":"check_architecture_guards.check_markdown_links (cognitive 16): check_architecture_guards.check_markdown_links has cognitive complexity 16 (threshold 15). Drivers by points: if/else 3 (10 pts), error handling 1 (3 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":"scripts/check_architecture_guards.py"},"region":{"startLine":528}}}],"partialFingerprints":{"codehealthFindingId/v1":"00547c9de079274fba4d1dd2e4a907567af5c6276cb967ff990d58b9cef3fc88"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: associations/coverage.py: FileTooLong \u2014 2945 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 2445 over it, 5.89\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":"core_memory/runtime/associations/coverage.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"fd329665c7f4fd050ee74ec160a34189bdeb088bb0ff6d81e270e81242bde208"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: http/server.py: FileTooLong \u2014 2160 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 1660 over it, 4.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":"core_memory/integrations/http/server.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"e1c204980105a133a50919ed3729364052f9148ec0fa5c703376321da9a27a76"}},{"ruleId":"D3","level":"warning","message":{"text":"TooManyMethods: MemoryStore: TooManyMethods \u2014 89 methods. The bar is 30 methods; this is 59 over it, 2.97\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":"core_memory/persistence/store.py"},"region":{"startLine":41}}}],"partialFingerprints":{"codehealthFindingId/v1":"c1d947be13902a98ce704cf066360b2851c591b4eb9e18c9959ed35292e0ce60"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: retrieval/semantic_index.py: FileTooLong \u2014 1463 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 963 over it, 2.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":"core_memory/retrieval/semantic_index.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"ae6814be00d0928d568b56b4ac8326d9eb689237d8630d4231052645a297e700"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: pipeline/canonical.py: FileTooLong \u2014 1300 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 800 over it, 2.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":"core_memory/retrieval/pipeline/canonical.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"e0211532bd6e9d967a7d2cfe37e11d1f6f20ea50da0409ed21ef5542739e456e"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: graph/root_cause.py: FileTooLong \u2014 1183 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 683 over it, 2.37\u00D7 the bar. To reduce it, split the file along the responsibilities already in it: move each cohesive group of declarations into its own sibling file in the same module or package, so no one file has to be read whole to change one of them."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"core_memory/graph/root_cause.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"d65a23da5e457a0f33b489431a06c5ff507be5d6bca428b8a765b5b5731b4b3b"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: management/__init__.py: FileTooLong \u2014 1170 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 670 over it, 2.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":"core_memory/management/__init__.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"669b59be0fdf7876801f4bec23e960cdf3218ce6fa97f60e802efcc1d8e9870b"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: soul/summary.py: FileTooLong \u2014 966 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 466 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":"core_memory/soul/summary.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"2692affea20f7d18b8975abc54c38016686ec5166ec8fe81fc24fdbdad08f33a"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: dreamer/candidates.py: FileTooLong \u2014 950 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 450 over it, 1.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":"core_memory/runtime/dreamer/candidates.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"0dd6f61ccc52c7080a5f02d2621871d81f669a4e8434882310621a7dc61e5a09"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: turn/reauthoring.py: FileTooLong \u2014 950 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 450 over it, 1.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":"core_memory/runtime/turn/reauthoring.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"76e9824ef27b9e7c54216ae390adc0712fd62634f6bc93701a548d40623c9649"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: graph/core.py: FileTooLong \u2014 888 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 388 over it, 1.78\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":"core_memory/graph/core.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"078f8ae853202c8e9caac2a9151455bf84e1539d15680868de1182ab646ab079"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: association/crawler_contract.py: FileTooLong \u2014 872 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 372 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":"core_memory/association/crawler_contract.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"2c4a2de250282141a6ee55401ddf32c77af6636870f8a614618cfe3f694eaa7d"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: scripts/check_architecture_guards.py: FileTooLong \u2014 853 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 353 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":"scripts/check_architecture_guards.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"cdef1c7835b4c785da1f213482c9d247ca80e9ea6dcbd5c6fa08401d60494ef3"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: tools/memory_reason.py: FileTooLong \u2014 832 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 332 over it, 1.66\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":"core_memory/retrieval/tools/memory_reason.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"a4ab9fef6f2d3a56aba2b9c145463084accc11268cd1d6df4c4c3abf29a3281b"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: session/session_enrichment_delta.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":"core_memory/runtime/session/session_enrichment_delta.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"b74906fc515f5211336a4904d1fa5b1ace138fbab5569c30a1ca097d569095a0"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: graph/roadmap.py: FileTooLong \u2014 776 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 276 over it, 1.55\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":"core_memory/graph/roadmap.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"37bb3e3621b7bc0dc3250a7097e79395b64b597c3ebc0d16edd198d3e9d0911d"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: retrieval/agent.py: FileTooLong \u2014 759 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 259 over it, 1.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":"core_memory/retrieval/agent.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"47187496f79372a23aefa5ca30db8e43ffc63f551d78eba55c24737f7efae275"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: persistence/store_management_ops.py: FileTooLong \u2014 747 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 247 over it, 1.49\u00D7 the bar. To reduce it, split the file along the responsibilities already in it: move each cohesive group of declarations into its own sibling file in the same module or package, so no one file has to be read whole to change one of them."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"core_memory/persistence/store_management_ops.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"9049a8d4416cb47059739a5d18519f2c4a6861ace77114dc8d17f5a0470cf7cd"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: retrieval/roadmap_planner.py: FileTooLong \u2014 744 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 244 over it, 1.49\u00D7 the bar. To reduce it, split the file along the responsibilities already in it: move each cohesive group of declarations into its own sibling file in the same module or package, so no one file has to be read whole to change one of them."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"core_memory/retrieval/roadmap_planner.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"41029d2d54eff6313de3245256bf4aa2010b25a6a6de3b50ea3fc95a633baa2f"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: goals/progress.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":"core_memory/runtime/goals/progress.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"03608205f08299326eaa6385d77c0d2300725b0fc7145e8cf6e0222385d3e7cb"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: handlers/setup.py: FileTooLong \u2014 704 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 204 over it, 1.41\u00D7 the bar. To reduce it, split the file along the responsibilities already in it: move each cohesive group of declarations into its own sibling file in the same module or package, so no one file has to be read whole to change one of them."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"core_memory/cli/handlers/setup.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"9aac19e71f29d2b1c8b16d395ff010a997b185dd5b17219c1a8c218570e17036"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: ingest/external_evidence.py: FileTooLong \u2014 700 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 200 over it, 1.40\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":"core_memory/runtime/ingest/external_evidence.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"965e4b5e4620503acba52f1bd80b902cb8e65230ebcdb681bdad95c5d59cc10e"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: runtime/engine.py: FileTooLong \u2014 698 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 198 over it, 1.40\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":"core_memory/runtime/engine.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"24de32c721af27ba6ebb10d8c64f7f35e4ee230f41c38d64dc76004c47712d62"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: schema/models.py: FileTooLong \u2014 647 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 147 over it, 1.29\u00D7 the bar. To reduce it, split the file along the responsibilities already in it: move each cohesive group of declarations into its own sibling file in the same module or package, so no one file has to be read whole to change one of them."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"core_memory/schema/models.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"29cb8e6eb62fe8b5774f419b7e4aef55b7d9c4b80593c628bbf411873b489a1e"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: soul/dreamer_bridge.py: FileTooLong \u2014 583 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 83 over it, 1.17\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":"core_memory/soul/dreamer_bridge.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"e519c91030f6cb0fb917fac8875daf22d488f182fc5b33a5d213a3e10aea1bd5"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: queue/side_effect_queue.py: FileTooLong \u2014 560 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 60 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":"core_memory/runtime/queue/side_effect_queue.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"568c62a0777eb1afab5302e806d6e28d15de73c7700fa48639a2fe5c8a145b9c"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: integrations/api.py: FileTooLong \u2014 538 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 38 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":"core_memory/integrations/api.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"e6d0b15bb4d2c18f9eb5c9acacae611b0a6ebd67e05a370d488174cd51a7e78d"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: persistence/promotion_service.py: FileTooLong \u2014 527 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 27 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":"core_memory/persistence/promotion_service.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"20866cc28f8e1fa44b283ebf1a2e8ad5927d7be5137212d8deb497f1e2140859"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: schema/agent_authored_updates.py: FileTooLong \u2014 527 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 27 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":"core_memory/schema/agent_authored_updates.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"8a9bf975b02e2951de2bc2524e2dbc2e42f9b2065f709609903b6776743099c0"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: persistence/store.py: FileTooLong \u2014 522 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 22 over it, 1.04\u00D7 the bar. To reduce it, split the file along the responsibilities already in it: move each cohesive group of declarations into its own sibling file in the same module or package, so no one file has to be read whole to change one of them."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"core_memory/persistence/store.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"1fa8ba3b95c2a4f01c8b461f4e31d2639dc999ac8247d9529ece290ddea42f1b"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: mcp/protocol_server.py: FileTooLong \u2014 514 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 14 over it, 1.03\u00D7 the bar. To reduce it, split the file along the responsibilities already in it: move each cohesive group of declarations into its own sibling file in the same module or package, so no one file has to be read whole to change one of them."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"core_memory/integrations/mcp/protocol_server.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"4162e885e61a01ab3131d49dc157c3d3f786f8c1e22dfae81bcae906ecb2dcaa"}},{"ruleId":"D4","level":"warning","message":{"text":"Near-duplicate member pair (115 shared lines): core_memory/runtime/turn/reauthoring.py:634-900 | core_memory/runtime/turn/reauthoring.py:935-1146 \u2014 These two members are variants of one another: 115 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":"core_memory/runtime/turn/reauthoring.py"},"region":{"startLine":634}}}],"partialFingerprints":{"codehealthFindingId/v1":"42419f0e2e1fe01abe97343785ffe86ba21de65ca6530b7e083d2976faed7a28"}},{"ruleId":"D4","level":"warning","message":{"text":"Edited copy of a member (22 corresponding lines): core_memory/persistence/store_validation_helpers.py:7-31 | core_memory/schema/promotion.py:54-78 \u2014 These two members are one piece of code written twice and then edited apart: 22 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":"core_memory/persistence/store_validation_helpers.py"},"region":{"startLine":7}}}],"partialFingerprints":{"codehealthFindingId/v1":"f350681e15f6e6a63f85fcf5911a8819095c1027d337ecb0ad7b9570ff19f3ee"}},{"ruleId":"D4","level":"warning","message":{"text":"Members sharing a duplicated core (6 members, 50\u002B identical tokens): core_memory/persistence/myelination_rewards.py:147-161 | core_memory/persistence/myelination_rewards.py:601-627 | core_memory/persistence/retrieval_feedback.py:149-177 | core_memory/runtime/dreamer/eval.py:132-147 | core_memory/runtime/dreamer/projection.py:270-285 | core_memory/soul/store.py:83-98 \u2014 These 6 members share a duplicated core: a run of at least 50 identical tokens appears in every one of them. That run is NOT broken out as duplicated-block rows below \u2014 it is what admitted this row, and the blocks below cover only the part of it that clears the block floor, so they understate the correspondence. Read the members as one construct written 6 times. The repair is at the members\u0027 grain \u2014 factor the shared implementation out once and have all of them call it with their differences as parameters or as an injected step, or, where the difference is systematic, generate them from one template. Extracting the individual blocks below is not the same fix: it leaves every body in place and the next edit still has to be made 6 times."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"core_memory/persistence/myelination_rewards.py"},"region":{"startLine":147}}}],"partialFingerprints":{"codehealthFindingId/v1":"579a983d2385f572a11184e022f00e66b3c21cb7d1c00e634355826d79978ac6"}},{"ruleId":"D4","level":"warning","message":{"text":"Members sharing a duplicated core (5 members, 50\u002B identical tokens): core_memory/graph/storylines.py:40-55 | core_memory/persistence/semantic_task_receipts.py:95-107 | core_memory/persistence/session_surface.py:16-36 | core_memory/runtime/associations/coverage.py:187-200 | core_memory/runtime/associations/coverage.py:204-216 \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":"core_memory/graph/storylines.py"},"region":{"startLine":40}}}],"partialFingerprints":{"codehealthFindingId/v1":"91560186b43443502d44943a536f4896e460416a1f082bd16a14fcc01ef602fb"}},{"ruleId":"D4","level":"warning","message":{"text":"Members sharing a duplicated core (5 members, 50\u002B identical tokens): core_memory/integrations/pydanticai/semantic_tasks.py:37-47 | core_memory/policy/bead_judge.py:300-310 | core_memory/policy/bead_typing.py:120-130 | core_memory/policy/rationale.py:168-178 | core_memory/policy/semantic_task_runtime.py:197-207 \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":"core_memory/integrations/pydanticai/semantic_tasks.py"},"region":{"startLine":37}}}],"partialFingerprints":{"codehealthFindingId/v1":"ec47e9d80a6d4a25c5cc61d18b0affc303629db4937fc5f2b35443b74e8dc825"}},{"ruleId":"D4","level":"warning","message":{"text":"Members sharing a duplicated core (5 members, 50\u002B identical tokens): core_memory/persistence/retrieval_feedback.py:18-29 | core_memory/runtime/dreamer/eval.py:17-28 | core_memory/runtime/dreamer/longitudinal.py:11-22 | core_memory/runtime/observability/self_model_drift.py:22-33 | core_memory/temporal/resolution.py:8-19 \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":"core_memory/persistence/retrieval_feedback.py"},"region":{"startLine":18}}}],"partialFingerprints":{"codehealthFindingId/v1":"8fb8d880e71b3efa6a568545fbd06e3b464887a678a4c3937b15a6bcf7b1fa29"}},{"ruleId":"D4","level":"warning","message":{"text":"Members sharing a duplicated core (4 members, 50\u002B identical tokens): core_memory/integrations/mcp/tools/ingest.py:197-298 | core_memory/integrations/mcp/tools/ingest_discord.py:80-172 | core_memory/integrations/mcp/tools/ingest_slack.py:77-153 | core_memory/integrations/mcp/tools/ingest_zoom.py:130-237 \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":"core_memory/integrations/mcp/tools/ingest.py"},"region":{"startLine":197}}}],"partialFingerprints":{"codehealthFindingId/v1":"d82f766415fd98f7534c36b33a5fe0ecbc8ed40a472e11a37e637199b4b2ca06"}},{"ruleId":"D4","level":"warning","message":{"text":"Members sharing a duplicated core (4 members, 50\u002B identical tokens): core_memory/integrations/openclaw/agent_end_bridge.py:325-353 | core_memory/integrations/openclaw/compaction_bridge.py:62-77 | core_memory/integrations/openclaw/hosted_capture_bridge.py:279-305 | core_memory/integrations/openclaw/read_bridge.py:136-160 \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":"core_memory/integrations/openclaw/agent_end_bridge.py"},"region":{"startLine":325}}}],"partialFingerprints":{"codehealthFindingId/v1":"875242d994ada5e2798440ede1def6996ab2bf7a8b8d3ff7ae81123aab1bfdd5"}},{"ruleId":"D4","level":"warning","message":{"text":"Members sharing a duplicated core (4 members, 50\u002B identical tokens): core_memory/runtime/dreamer/convergence.py:146-209 | core_memory/runtime/dreamer/goal_decay.py:125-176 | core_memory/runtime/dreamer/goal_discovery.py:136-187 | core_memory/runtime/dreamer/tension_discovery.py:69-123 \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":"core_memory/runtime/dreamer/convergence.py"},"region":{"startLine":146}}}],"partialFingerprints":{"codehealthFindingId/v1":"cb0791ac1361572f85d1892e6326b2d335b940846eb83f9be8b835b16819a10d"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (33\u201364 lines \u00D7 2): core_memory/runtime/turn/reauthoring.py:645-708 | core_memory/runtime/turn/reauthoring.py:945-977 \u2014 both copies are in the same file, so extract the block 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 \u0060core_memory/runtime/turn/reauthoring.py:645\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":"core_memory/runtime/turn/reauthoring.py"},"region":{"startLine":645}}}],"partialFingerprints":{"codehealthFindingId/v1":"b43a9789dc875ec4e91f6a24a106fcb5c657572615eef8c55c9afaebbf3675ad"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (44\u201359 lines \u00D7 2): core_memory/runtime/turn/reauthoring.py:816-874 | core_memory/runtime/turn/reauthoring.py:1077-1120 \u2014 both copies are in the same file, so extract the block 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 \u0060core_memory/runtime/turn/reauthoring.py:816\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":"core_memory/runtime/turn/reauthoring.py"},"region":{"startLine":816}}}],"partialFingerprints":{"codehealthFindingId/v1":"aea066e1465a9df912fae9131dea19d1074606f3125692ff63248533d8c5570c"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (36\u201343 lines \u00D7 2): core_memory/persistence/store_text_hygiene_ops.py:95-130 | core_memory/policy/hygiene.py:140-182 \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":"core_memory/persistence/store_text_hygiene_ops.py"},"region":{"startLine":95}}}],"partialFingerprints":{"codehealthFindingId/v1":"8f8271c1d62675da6890c76e0d4eabb27fd0713a745a9978db49a4bea108e3a4"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (21\u201343 lines \u00D7 2): core_memory/runtime/turn/reauthoring.py:678-720 | core_memory/runtime/turn/reauthoring.py:1002-1022 \u2014 both copies are in the same file, so extract the block 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 \u0060core_memory/runtime/turn/reauthoring.py:1002\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":"core_memory/runtime/turn/reauthoring.py"},"region":{"startLine":678}}}],"partialFingerprints":{"codehealthFindingId/v1":"471f4975c6d5c0e31db5ec5e18cd90cbdc3d7bfb0301aea6c52176bb77e56634"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (13\u201337 lines \u00D7 3): core_memory/runtime/dreamer/goal_decay.py:139-175 | core_memory/runtime/dreamer/goal_discovery.py:147-159 | core_memory/runtime/dreamer/tension_discovery.py:82-94 \u2014 before extracting anything, compare \u0060core_memory/runtime/dreamer/goal_decay.py\u0060 and \u0060core_memory/runtime/dreamer/goal_discovery.py\u0060 as WHOLE FILES: this scan already matched 4 separate duplicated blocks between them, totalling at least 84 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. If that is what happened, the fix is to keep one copy and have the other call it (or delete it), which resolves this row and its siblings together \u2014 extracting one helper per block leaves the fork in place. Read the line range as the matched WINDOW rather than a finished unit: at \u0060core_memory/runtime/dreamer/goal_discovery.py:147\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":"core_memory/runtime/dreamer/goal_decay.py"},"region":{"startLine":139}}}],"partialFingerprints":{"codehealthFindingId/v1":"db2e29fdb9263eb6e01373b883a18d1d14ee297719126117cca8bcbba2315e44"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (29 lines \u00D7 2): core_memory/persistence/store_autonomy_ops.py:21-49 | core_memory/schema/promotion.py:98-126 \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":"core_memory/persistence/store_autonomy_ops.py"},"region":{"startLine":21}}}],"partialFingerprints":{"codehealthFindingId/v1":"fa11184d0cf4b537f03274768c6ad169bcc0832504870db8e6e10778017f5016"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (28 lines \u00D7 2): core_memory/integrations/github/connector.py:73-100 | core_memory/integrations/github/connector.py:109-136 \u2014 both copies are in the same file, so extract the block 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. \u2605 These copies have DRIFTED, and that is worth reading before extracting anything: just before the matched lines, \u0060core_memory/integrations/github/connector.py:71\u0060 calls \u0060_s\u0060, \u0060get\u0060 and \u0060core_memory/integrations/github/connector.py:108\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":"core_memory/integrations/github/connector.py"},"region":{"startLine":73}}}],"partialFingerprints":{"codehealthFindingId/v1":"ae763874a1bdd603cbfe1a5fd756990404f2ccb8ce0fbda9c50f58bc7d95cbbe"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (28 lines \u00D7 2): core_memory/runtime/observability/reviewer_quick_value.py:119-146 | core_memory/runtime/observability/reviewer_quick_value.py:152-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. Read the line range as the matched WINDOW rather than a finished unit: at \u0060core_memory/runtime/observability/reviewer_quick_value.py:119\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":"core_memory/runtime/observability/reviewer_quick_value.py"},"region":{"startLine":119}}}],"partialFingerprints":{"codehealthFindingId/v1":"c227655a6cf8c8c6092cda2ddeb835b84bc5055991910542c40aeda59e433e22"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (27 lines \u00D7 2): core_memory/persistence/store_retrieval_context.py:40-66 | core_memory/retrieval/context_recall.py:66-92 \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":"core_memory/persistence/store_retrieval_context.py"},"region":{"startLine":40}}}],"partialFingerprints":{"codehealthFindingId/v1":"71494cf3cbddf9ea4902e44e340d25ea5d3c13cd0a29638b7e693f2dca8723fa"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (24 lines \u00D7 2): core_memory/graph/root_cause.py:349-372 | core_memory/retrieval/causal_recall.py:108-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 \u0060core_memory/graph/root_cause.py:349\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. Note first that the copies are not typed on the same thing: the declarations holding them bind \u0060bead\u0060 to \u0060Mapping[str, Any]\u0060 in one and \u0060dict[str, Any]\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":"core_memory/graph/root_cause.py"},"region":{"startLine":349}}}],"partialFingerprints":{"codehealthFindingId/v1":"85cf925a65414f9687a5e56311f95cb8cfab02ad7a356d3d33cfc870a34c0d56"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (24 lines \u00D7 2): core_memory/soul/summary.py:882-905 | core_memory/soul/summary.py:907-930 \u2014 both copies are in the same file, so extract the block into one function there and call it from each site \u2014 the copies drift apart the first time only one of them is edited. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"core_memory/soul/summary.py"},"region":{"startLine":882}}}],"partialFingerprints":{"codehealthFindingId/v1":"f8832f81a9942abdf9e868aa828fbbc515e5034dfc001239d930ab4c2fe64ae3"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (23 lines \u00D7 2): core_memory/integrations/openclaw/compaction_bridge.py:36-58 | core_memory/runtime/queue/compaction_queue.py:76-98 \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":"core_memory/integrations/openclaw/compaction_bridge.py"},"region":{"startLine":36}}}],"partialFingerprints":{"codehealthFindingId/v1":"1c36094f6b8ed1c7aab2e4723f990e9c8ff21b0d57e6d5abd8b058590d2c68cc"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (23 lines \u00D7 2): core_memory/runtime/dreamer/candidates.py:743-765 | core_memory/runtime/dreamer/candidates.py:802-824 \u2014 both copies are in the same file, so extract the block 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 \u0060core_memory/runtime/dreamer/candidates.py:802\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":"core_memory/runtime/dreamer/candidates.py"},"region":{"startLine":743}}}],"partialFingerprints":{"codehealthFindingId/v1":"4c1db403f7255d16a9812a8dda1efbea94622eb6512d90245f78b35db0e088e7"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (22 lines \u00D7 2): core_memory/policy/bead_typing.py:149-170 | core_memory/policy/rationale.py:200-221 \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 \u0060core_memory/policy/bead_typing.py:149\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, \u0060core_memory/policy/bead_typing.py:148\u0060 calls \u0060format\u0060 and \u0060core_memory/policy/rationale.py:199\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":"core_memory/policy/bead_typing.py"},"region":{"startLine":149}}}],"partialFingerprints":{"codehealthFindingId/v1":"cca31fc8155164fd9e9b24130b6261c6795ac88910af48ec97fa79ca85701e2a"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (19\u201321 lines \u00D7 2): core_memory/runtime/turn/ingress.py:170-190 | core_memory/runtime/turn/ingress.py:193-211 \u2014 both copies are in the same file, so extract the block 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 \u0060core_memory/runtime/turn/ingress.py:170\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":"core_memory/runtime/turn/ingress.py"},"region":{"startLine":170}}}],"partialFingerprints":{"codehealthFindingId/v1":"16b8e8c68d81858382336ecf59e5e2344806922819eab0ab67ae0d4c621597d5"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (16\u201320 lines \u00D7 2): core_memory/integrations/crewai/memory.py:87-106 | core_memory/integrations/crewai/memory.py:150-165 \u2014 both copies are in the same file, so extract the block 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":"core_memory/integrations/crewai/memory.py"},"region":{"startLine":87}}}],"partialFingerprints":{"codehealthFindingId/v1":"97ae5ab711dada4f18c75fb8fa3255f1038d5417b311b16b594381f277a2bd0a"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (19 lines \u00D7 2): core_memory/integrations/mcp/protocol_server.py:396-414 | core_memory/integrations/mcp/protocol_server.py:523-546 \u2014 both copies are in the same file, so extract the block 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 \u0060core_memory/integrations/mcp/protocol_server.py:396\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":"core_memory/integrations/mcp/protocol_server.py"},"region":{"startLine":396}}}],"partialFingerprints":{"codehealthFindingId/v1":"6df74137d71e6ad736ce3cf6f9d4c49275fb573cf77286e712088594f4f4caab"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (15\u201319 lines \u00D7 2): core_memory/persistence/graph/kuzu_backend.py:240-258 | core_memory/persistence/graph/neo4j_backend.py:149-163 \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 \u0060core_memory/persistence/graph/kuzu_backend.py:240\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 \u0060return\u0060 at the foot of the matched lines is the enclosing body\u0027s own terminal exit, not an early one: it moves with them unchanged, and each site calls the extracted unit from the position that \u0060return\u0060 occupied \u2014 no decision has to be handed back and re-acted on. Note that the copies do not run to the end of the range shown: their LAST lines are different code, not the same code under different names \u2014 the matched region ends inside that line. Extract the lines above it, and read the last line of each site separately."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"core_memory/persistence/graph/kuzu_backend.py"},"region":{"startLine":240}}}],"partialFingerprints":{"codehealthFindingId/v1":"78d7090dfc080daca53ce7656ba495431436a572addcfcb361e947857cf625e2"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (18\u201319 lines \u00D7 2): core_memory/persistence/store_approval_ops.py:84-102 | core_memory/persistence/store_lifecycle_ops.py:76-93 \u2014 the copies sit in sibling files of one directory, so a shared home is within easy reach: extract the block into a single shared function the call sites can all reach \u2014 a file they already depend on, or a new one alongside them \u2014 and call it from both call sites, so a change lands once. 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, \u0060core_memory/persistence/store_approval_ops.py:103\u0060 calls \u0060raise_confidence_class_for_bead\u0060 and \u0060core_memory/persistence/store_lifecycle_ops.py:94\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":"core_memory/persistence/store_approval_ops.py"},"region":{"startLine":84}}}],"partialFingerprints":{"codehealthFindingId/v1":"1107e6dfca6bf5e315c4adfd7b3a1360014fec92c88148d9c5c06e9f31d94ebf"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (19 lines \u00D7 2): core_memory/retrieval/pipeline/canonical.py:1421-1439 | core_memory/retrieval/pipeline/canonical.py:1549-1567 \u2014 both copies are in the same file, so extract the block 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":"core_memory/retrieval/pipeline/canonical.py"},"region":{"startLine":1421}}}],"partialFingerprints":{"codehealthFindingId/v1":"913d7f28a56c50e45d10ba31412b89023fa7c1a05dd1c84b443731e580ca4289"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (19 lines \u00D7 2): core_memory/runtime/engine.py:814-832 | core_memory/runtime/turn/turn_flow.py:105-123 \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 \u0060core_memory/runtime/engine.py:814\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":"core_memory/runtime/engine.py"},"region":{"startLine":814}}}],"partialFingerprints":{"codehealthFindingId/v1":"35d6b4d5fe650338b035cff35fb75c3869fd98def40cba22935b66133da9b57d"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (17\u201318 lines \u00D7 2): core_memory/integrations/openclaw/agent_end_bridge.py:202-219 | core_memory/integrations/openclaw/hosted_capture_bridge.py:78-94 \u2014 the copies sit in sibling files of one directory, so a shared home is within easy reach: extract the block into a single shared function the call sites can all reach \u2014 a file they already depend on, or a new one alongside them \u2014 and call it from both call sites, so a change lands once."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"core_memory/integrations/openclaw/agent_end_bridge.py"},"region":{"startLine":202}}}],"partialFingerprints":{"codehealthFindingId/v1":"58cbb77468ba2a54c864c1808dd2d95326c3a8ed2250f026d3d5d5b59b5d164a"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (11\u201318 lines \u00D7 2): core_memory/persistence/backend.py:381-391 | core_memory/retrieval/vector_backend.py:473-490 \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":"core_memory/persistence/backend.py"},"region":{"startLine":381}}}],"partialFingerprints":{"codehealthFindingId/v1":"72d98fd90de6a137697625e81a423530e318890d90b3efae2309015beff60e7e"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (18 lines \u00D7 2): core_memory/persistence/myelination_rewards.py:602-619 | core_memory/persistence/retrieval_feedback.py:150-167 \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":"core_memory/persistence/myelination_rewards.py"},"region":{"startLine":602}}}],"partialFingerprints":{"codehealthFindingId/v1":"81601e1f0dec05e4e845c6cd0cf731119e6ba88f888034a50af25db20b0cf67d"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (18 lines \u00D7 2): core_memory/persistence/store_text_hygiene_ops.py:41-58 | core_memory/retrieval/query_norm.py:56-73 \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":"core_memory/persistence/store_text_hygiene_ops.py"},"region":{"startLine":41}}}],"partialFingerprints":{"codehealthFindingId/v1":"07a8be5ddf798e38329a37bbddde4dd38ff18fe0b899a3235313cd3dd3aac087"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (18 lines \u00D7 2): core_memory/retrieval/lexical.py:162-179 | core_memory/retrieval/lexical.py:209-226 \u2014 both copies are in the same file, so extract the block 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":"core_memory/retrieval/lexical.py"},"region":{"startLine":162}}}],"partialFingerprints":{"codehealthFindingId/v1":"56144d90f7b31ddbb94ebcfe37ab159c82da02154bf412f337e010e1f7caed17"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (16\u201317 lines \u00D7 2): core_memory/association/crawler_contract.py:545-561 | core_memory/association/crawler_contract.py:942-957 \u2014 both copies are in the same file, so extract the block into one function there and call it from each site \u2014 the copies drift apart the first time only one of them is edited. Read the line range as the matched WINDOW rather than a finished unit: at \u0060core_memory/association/crawler_contract.py:545\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":"core_memory/association/crawler_contract.py"},"region":{"startLine":545}}}],"partialFingerprints":{"codehealthFindingId/v1":"12722e36cabbcce62a42a9ce0c1f7ac9ccd098808ed84ea9a92f55662780139c"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (17 lines \u00D7 2): core_memory/integrations/http/server.py:826-842 | core_memory/integrations/http/server.py:2258-2274 \u2014 both copies are in the same file, so extract the block into one function there and call it from each site \u2014 the copies drift apart the first time only one of them is edited. 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":"core_memory/integrations/http/server.py"},"region":{"startLine":826}}}],"partialFingerprints":{"codehealthFindingId/v1":"38ef2feb7f21ec245e58bc4cf48ace7227e762a81b72f174e579d69c6459ced7"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (14\u201317 lines \u00D7 2): core_memory/persistence/entity_merge_flow.py:29-45 | core_memory/runtime/dreamer/candidates.py:65-78 \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. 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":"core_memory/persistence/entity_merge_flow.py"},"region":{"startLine":29}}}],"partialFingerprints":{"codehealthFindingId/v1":"4f9e6ef2318a49304871986657acf47e50244198ec53f525be1ccda686c9b82e"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (17 lines \u00D7 2): core_memory/runtime/turn/reauthoring.py:880-896 | core_memory/runtime/turn/reauthoring.py:1126-1142 \u2014 both copies are in the same file, so extract the block 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 \u0060core_memory/runtime/turn/reauthoring.py:880\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":"core_memory/runtime/turn/reauthoring.py"},"region":{"startLine":880}}}],"partialFingerprints":{"codehealthFindingId/v1":"ee3f1a7b1048ede4e58c1e617c4cceff6f0541bb06853aab1749064461523626"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (15\u201316 lines \u00D7 2): core_memory/association/crawler_contract.py:1018-1032 | core_memory/association/crawler_contract.py:1042-1057 \u2014 both copies are in the same file, so extract the block 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":"core_memory/association/crawler_contract.py"},"region":{"startLine":1018}}}],"partialFingerprints":{"codehealthFindingId/v1":"f8f270a0387a46a57f1b40d787eb3f7f844a019731dccaa2372c972d5ae011eb"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (16 lines \u00D7 2): core_memory/integrations/mcp/tools/ingest_discord.py:80-96 | core_memory/integrations/mcp/tools/ingest_slack.py:77-92 \u2014 before extracting anything, compare \u0060core_memory/integrations/mcp/tools/ingest_discord.py\u0060 and \u0060core_memory/integrations/mcp/tools/ingest_slack.py\u0060 as WHOLE FILES: this scan already matched 6 separate duplicated blocks between them, totalling at least 76 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. If that is what happened, the fix is to keep one copy and have the other call it (or delete it), which resolves this row and its siblings together \u2014 extracting one helper per block leaves the fork in place."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"core_memory/integrations/mcp/tools/ingest_discord.py"},"region":{"startLine":80}}}],"partialFingerprints":{"codehealthFindingId/v1":"4ff7b34d6fe65659e0921f8aae2f634fbe0a5d0d6d3341e9682f86b0c9e513d5"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (16 lines \u00D7 2): core_memory/integrations/mcp/tools/ingest_discord.py:139-154 | core_memory/integrations/mcp/tools/ingest_zoom.py:204-219 \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":"core_memory/integrations/mcp/tools/ingest_discord.py"},"region":{"startLine":139}}}],"partialFingerprints":{"codehealthFindingId/v1":"809568a4b730b11b677360d922c129bda79bc376a32a95e5f043dd7b5f9f8e03"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (14\u201316 lines \u00D7 2): core_memory/integrations/pydanticai/run.py:115-128 | core_memory/integrations/pydanticai/run.py:219-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. 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":"core_memory/integrations/pydanticai/run.py"},"region":{"startLine":115}}}],"partialFingerprints":{"codehealthFindingId/v1":"bd44bcb00dfa4afd9578ec587c5989b408824765c6321251a754a848030b3693"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (14\u201316 lines \u00D7 2): core_memory/runtime/associations/coverage.py:2043-2058 | core_memory/runtime/associations/coverage.py:3379-3392 \u2014 both copies are in the same file, so extract the block 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 \u0060core_memory/runtime/associations/coverage.py:2043\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":"core_memory/runtime/associations/coverage.py"},"region":{"startLine":2043}}}],"partialFingerprints":{"codehealthFindingId/v1":"aa8a7d8d81ee22369a79e1f9e88ceb6907df8533978e6e28b2c22ffd18867405"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (15 lines \u00D7 4): core_memory/integrations/mcp/tools/ingest.py:282-298 | core_memory/integrations/mcp/tools/ingest_discord.py:157-172 | core_memory/integrations/mcp/tools/ingest_slack.py:139-153 | core_memory/integrations/mcp/tools/ingest_zoom.py:222-237 \u2014 before extracting anything, compare \u0060core_memory/integrations/mcp/tools/ingest_discord.py\u0060 and \u0060core_memory/integrations/mcp/tools/ingest_slack.py\u0060 as WHOLE FILES: this scan already matched 6 separate duplicated blocks between them, totalling at least 76 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. If that is what happened, the fix is to keep one copy and have the other call it (or delete it), which resolves this row and its siblings together \u2014 extracting one helper per block leaves the fork in place. The 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":"core_memory/integrations/mcp/tools/ingest.py"},"region":{"startLine":282}}}],"partialFingerprints":{"codehealthFindingId/v1":"2bd1573a8ff8707dc7ab11c93def5ebd8900aaf93c2bfc6d10db448cfa84e2de"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (15 lines \u00D7 2): core_memory/integrations/openclaw/runtime.py:53-67 | core_memory/integrations/openclaw/runtime.py:93-107 \u2014 both copies are in the same file, so extract the block 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 \u0060core_memory/integrations/openclaw/runtime.py:53\u0060 it begins part-way through the construct above it, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"core_memory/integrations/openclaw/runtime.py"},"region":{"startLine":53}}}],"partialFingerprints":{"codehealthFindingId/v1":"fb2d314c117e93a55ecf24d428113b0981270b087985299f38695934c1f42fc1"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (15 lines \u00D7 2): core_memory/persistence/event_schema_audit.py:158-172 | core_memory/persistence/event_schema_audit.py:174-188 \u2014 both copies are in the same file, so extract the block 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":"core_memory/persistence/event_schema_audit.py"},"region":{"startLine":158}}}],"partialFingerprints":{"codehealthFindingId/v1":"f4ff96cab5dbf63a5c195dd57ef0d47604e21e92fd31687b8558fe2e72062e3d"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (15 lines \u00D7 2): core_memory/runtime/turn/semantic_state.py:253-267 | core_memory/runtime/turn/semantic_state.py:286-300 \u2014 both copies are in the same file, so extract the block 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":"core_memory/runtime/turn/semantic_state.py"},"region":{"startLine":253}}}],"partialFingerprints":{"codehealthFindingId/v1":"62f12e1fd84c38d2c18914a162587b4f9a6dd716e8e960992268cc139fb9d4f0"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (12\u201314 lines \u00D7 2): core_memory/association/crawler_contract.py:511-524 | core_memory/association/crawler_contract.py:929-940 \u2014 both copies are in the same file, so extract the block 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 \u0060core_memory/association/crawler_contract.py:511\u0060 it begins part-way through the construct above it, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that. 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":"core_memory/association/crawler_contract.py"},"region":{"startLine":511}}}],"partialFingerprints":{"codehealthFindingId/v1":"f633ce4d4bf8cebde093d5594d8e444e855ed1ef3bb16748ebbef4954cedb0a3"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (14 lines \u00D7 2): core_memory/persistence/turn_archive.py:254-267 | core_memory/retrieval/semantic_index.py:929-942 \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":"core_memory/persistence/turn_archive.py"},"region":{"startLine":254}}}],"partialFingerprints":{"codehealthFindingId/v1":"7739a061adf839346623c6729be4d7cebd3904d6089e5275b261fa93fb2f1fcf"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (12\u201314 lines \u00D7 2): core_memory/retrieval/tools/memory_reason.py:480-493 | core_memory/retrieval/tools/memory_reason.py:505-516 \u2014 both copies are in the same file, so extract the block 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":"core_memory/retrieval/tools/memory_reason.py"},"region":{"startLine":480}}}],"partialFingerprints":{"codehealthFindingId/v1":"7b02379fa8caf60c1e8ba8dc289244e12b6e76c16dc9d988a7afa739f0258ea0"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (11\u201313 lines \u00D7 3): core_memory/integrations/obsidian/vault.py:114-124 | core_memory/persistence/graph/kuzu_backend.py:241-253 | core_memory/persistence/graph/neo4j_backend.py:150-160 \u2014 the copies span different directories, so extracting a shared function means choosing where it lives: put it somewhere all 3 call sites can already reach \u2014 a location they all depend on today, or a new shared one if there is none \u2014 and call it from each site; until then, every change has to be made 3 times."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"core_memory/integrations/obsidian/vault.py"},"region":{"startLine":114}}}],"partialFingerprints":{"codehealthFindingId/v1":"c88c5bb6d9599fc9e68d8dbb5e946f4a7e603da9934da9c2b79c2d8629990c9e"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9\u201313 lines \u00D7 2): core_memory/soul/dreamer_bridge.py:557-569 | core_memory/soul/dreamer_bridge.py:742-750 \u2014 both copies are in the same file, so extract the block into one function there and call it from each site \u2014 the copies drift apart the first time only one of them is edited. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it. Note first that the copies are not typed on the same thing: the declarations holding them bind \u0060subject\u0060 to \u0060str\u0060 in one and \u0060str = \u0022self\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":"core_memory/soul/dreamer_bridge.py"},"region":{"startLine":557}}}],"partialFingerprints":{"codehealthFindingId/v1":"581013ff36bcc7562d726c692941b19a91f68f2fe86296243149b1807ce5febe"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (13 lines \u00D7 2): scripts/check_architecture_guards.py:605-617 | scripts/check_architecture_guards.py:626-638 \u2014 both copies are in the same file, so extract the block into one function there and call it from each site \u2014 the copies drift apart the first time only one of them is edited."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"scripts/check_architecture_guards.py"},"region":{"startLine":605}}}],"partialFingerprints":{"codehealthFindingId/v1":"c2614765bab735f90c10ee440d755388234b6bedb348a3ec6a599df56269c343"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (12 lines \u00D7 4): core_memory/persistence/myelination_rewards.py:147-158 | core_memory/runtime/dreamer/eval.py:133-144 | core_memory/runtime/dreamer/projection.py:271-282 | core_memory/soul/store.py:84-95 \u2014 the copies span different directories, so extracting a shared function means choosing where it lives: put it somewhere all 4 call sites can already reach \u2014 a location they all depend on today, or a new shared one if there is none \u2014 and call it from each site; until then, every change has to be made 4 times. 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":"core_memory/persistence/myelination_rewards.py"},"region":{"startLine":147}}}],"partialFingerprints":{"codehealthFindingId/v1":"c7e6e9e82309986c7bd5d908f93b26454287c690c16c2f9683ada94e07eea563"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (12 lines \u00D7 3): core_memory/persistence/semantic_task_receipts.py:96-107 | core_memory/runtime/associations/coverage.py:189-200 | core_memory/runtime/associations/coverage.py:205-216 \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 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":"core_memory/persistence/semantic_task_receipts.py"},"region":{"startLine":96}}}],"partialFingerprints":{"codehealthFindingId/v1":"97b4ff5580b750205d8f9e82aa97ff3e4dec3996117f19e812cce70905918ae4"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (12 lines \u00D7 2): core_memory/integrations/mcp/tools/ingest_discord.py:65-76 | core_memory/integrations/mcp/tools/ingest_slack.py:62-73 \u2014 before extracting anything, compare \u0060core_memory/integrations/mcp/tools/ingest_discord.py\u0060 and \u0060core_memory/integrations/mcp/tools/ingest_slack.py\u0060 as WHOLE FILES: this scan already matched 6 separate duplicated blocks between them, totalling at least 76 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. If that is what happened, the fix is to keep one copy and have the other call it (or delete it), which resolves this row and its siblings together \u2014 extracting one helper per block leaves the fork in place. The 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":"core_memory/integrations/mcp/tools/ingest_discord.py"},"region":{"startLine":65}}}],"partialFingerprints":{"codehealthFindingId/v1":"1a1b91c6f69049bdcc7fc6f8c224a37d0b3be8c014d15f48bfdce763558276b0"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (12 lines \u00D7 2): core_memory/integrations/mcp/tools/ingest_discord.py:104-115 | core_memory/integrations/mcp/tools/ingest_slack.py:99-110 \u2014 before extracting anything, compare \u0060core_memory/integrations/mcp/tools/ingest_discord.py\u0060 and \u0060core_memory/integrations/mcp/tools/ingest_slack.py\u0060 as WHOLE FILES: this scan already matched 6 separate duplicated blocks between them, totalling at least 76 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. If that is what happened, the fix is to keep one copy and have the other call it (or delete it), which resolves this row and its siblings together \u2014 extracting one helper per block leaves the fork in place. Read the line range as the matched WINDOW rather than a finished unit: at \u0060core_memory/integrations/mcp/tools/ingest_discord.py:104\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":"core_memory/integrations/mcp/tools/ingest_discord.py"},"region":{"startLine":104}}}],"partialFingerprints":{"codehealthFindingId/v1":"439fa2f4c2229a0a9d3fab3743946cb6c2498d70091409af9002383f501a807d"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (12 lines \u00D7 2): core_memory/management/__init__.py:1331-1342 | core_memory/management/__init__.py:1355-1366 \u2014 both copies are in the same file, so extract the block 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":"core_memory/management/__init__.py"},"region":{"startLine":1331}}}],"partialFingerprints":{"codehealthFindingId/v1":"79f52989b1de2c087f18b2d9b0c6facb7dca1b65ef5c3e0e1300e4dae2dc6aa1"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (12 lines \u00D7 2): core_memory/persistence/backend.py:311-322 | core_memory/persistence/backend.py:357-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":"core_memory/persistence/backend.py"},"region":{"startLine":311}}}],"partialFingerprints":{"codehealthFindingId/v1":"27b2b54acd24670793236c002a6da8139d34679e275ee301b669aae7403145ac"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (12 lines \u00D7 2): core_memory/persistence/graph/graphiti_backend.py:165-176 | core_memory/persistence/graph/graphiti_backend.py:179-190 \u2014 both copies are in the same file, so extract the block 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":"core_memory/persistence/graph/graphiti_backend.py"},"region":{"startLine":165}}}],"partialFingerprints":{"codehealthFindingId/v1":"7fb340898bed9845c60f2ca8a812d8ef024f07e7b29d41d1f970b58d9a1de9cc"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (12 lines \u00D7 2): core_memory/persistence/store_approval_ops.py:131-144 | core_memory/persistence/store_lifecycle_ops.py:55-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. Read the line range as the matched WINDOW rather than a finished unit: at \u0060core_memory/persistence/store_approval_ops.py:131\u0060 it does not close everything it opens, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that. \u2605 These copies have DRIFTED, and that is worth reading before extracting anything: just before the matched lines, \u0060core_memory/persistence/store_lifecycle_ops.py:51\u0060 calls \u0060str\u0060, \u0060get\u0060, \u0060strip\u0060 and \u0060core_memory/persistence/store_approval_ops.py:129\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":"core_memory/persistence/store_approval_ops.py"},"region":{"startLine":131}}}],"partialFingerprints":{"codehealthFindingId/v1":"185c754b0ddfe4e614e14190f94d752bb1610206d0208c738f77dcd0e7d165f9"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (12 lines \u00D7 2): core_memory/runtime/dreamer/eval.py:32-43 | core_memory/runtime/dreamer/longitudinal.py:26-37 \u2014 before extracting anything, compare \u0060core_memory/runtime/dreamer/eval.py\u0060 and \u0060core_memory/runtime/dreamer/longitudinal.py\u0060 as WHOLE FILES: this scan already matched 11 separate duplicated blocks between them, totalling at least 95 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. If that is what happened, the fix is to keep one copy and have the other call it (or delete it), which resolves this row and its siblings together \u2014 extracting one helper per block leaves the fork in place. The 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":"core_memory/runtime/dreamer/eval.py"},"region":{"startLine":32}}}],"partialFingerprints":{"codehealthFindingId/v1":"13dda2fab4646e65e710a596931cd3b5e5a335afcf6635688d39d8d1586f9319"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (12 lines \u00D7 2): core_memory/runtime/dreamer/eval.py:266-277 | core_memory/runtime/dreamer/longitudinal.py:183-194 \u2014 before extracting anything, compare \u0060core_memory/runtime/dreamer/eval.py\u0060 and \u0060core_memory/runtime/dreamer/longitudinal.py\u0060 as WHOLE FILES: this scan already matched 11 separate duplicated blocks between them, totalling at least 95 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. If that is what happened, the fix is to keep one copy and have the other call it (or delete it), which resolves this row and its siblings together \u2014 extracting one helper per block leaves the fork in place. The 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":"core_memory/runtime/dreamer/eval.py"},"region":{"startLine":266}}}],"partialFingerprints":{"codehealthFindingId/v1":"529d2515b1c78bfa138d9e1aa9a299d315bbc8afd5327ffd4e6c71f269c41d40"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (11 lines \u00D7 3): core_memory/graph/core.py:152-162 | core_memory/persistence/store_validation_helpers.py:21-31 | core_memory/schema/promotion.py:68-78 \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 \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":"core_memory/graph/core.py"},"region":{"startLine":152}}}],"partialFingerprints":{"codehealthFindingId/v1":"5686020fa8832310b7a9f3e712f20c5233b6c21341c83eb6976e8d570f02d591"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (11 lines \u00D7 3): core_memory/persistence/retrieval_feedback.py:19-29 | core_memory/runtime/observability/self_model_drift.py:23-33 | core_memory/temporal/resolution.py:9-19 \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":"core_memory/persistence/retrieval_feedback.py"},"region":{"startLine":19}}}],"partialFingerprints":{"codehealthFindingId/v1":"d7d166fbfd0edb2cd3a5f9f2e06c720fcd160140957cf00e4b2ee1ffa8d384e1"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (11 lines \u00D7 2): core_memory/claim/retrieval_planner.py:44-54 | core_memory/retrieval/evidence_scoring.py:49-59 \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":"core_memory/claim/retrieval_planner.py"},"region":{"startLine":44}}}],"partialFingerprints":{"codehealthFindingId/v1":"ff93c81358ed01f790157702bef3207af24383dcd75a6247099caf0bca081973"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (11 lines \u00D7 2): core_memory/persistence/events.py:195-205 | core_memory/persistence/events.py:210-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. 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":"core_memory/persistence/events.py"},"region":{"startLine":195}}}],"partialFingerprints":{"codehealthFindingId/v1":"00007ead79e9cf7a59e95fe3d23c5a812dfdae5c484a3c94edfd177a5a040945"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (11 lines \u00D7 2): core_memory/persistence/store_reporting.py:28-38 | core_memory/persistence/store_reporting.py:85-95 \u2014 both copies are in the same file, so extract the block 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, \u0060core_memory/persistence/store_reporting.py:83\u0060 calls \u0060get\u0060 and \u0060core_memory/persistence/store_reporting.py:27\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":"core_memory/persistence/store_reporting.py"},"region":{"startLine":28}}}],"partialFingerprints":{"codehealthFindingId/v1":"1f102dde6f9380bae1781a5f33a250b7a02508124eeee2b1674883d0f1069219"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (11 lines \u00D7 2): core_memory/persistence/store_retrieval_context.py:74-84 | core_memory/retrieval/context_recall.py:100-110 \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":"core_memory/persistence/store_retrieval_context.py"},"region":{"startLine":74}}}],"partialFingerprints":{"codehealthFindingId/v1":"fca5f7b7ec84d417d3ba8968b5bf557dc6e4903865e1dd9d388f084910a5c09a"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (10\u201311 lines \u00D7 2): core_memory/retrieval/semantic_index.py:798-807 | core_memory/retrieval/semantic_index.py:833-843 \u2014 both copies are in the same file, so extract the block 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":"core_memory/retrieval/semantic_index.py"},"region":{"startLine":798}}}],"partialFingerprints":{"codehealthFindingId/v1":"4c7e84d65e1c363f14ed8a88009c87a9f44856a8beec0f39d211ca4cc4e37bb3"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (11 lines \u00D7 2): core_memory/runtime/dreamer/eval.py:18-28 | core_memory/runtime/dreamer/longitudinal.py:12-22 \u2014 before extracting anything, compare \u0060core_memory/runtime/dreamer/eval.py\u0060 and \u0060core_memory/runtime/dreamer/longitudinal.py\u0060 as WHOLE FILES: this scan already matched 11 separate duplicated blocks between them, totalling at least 95 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. If that is what happened, the fix is to keep one copy and have the other call it (or delete it), which resolves this row and its siblings together \u2014 extracting one helper per block leaves the fork in place. The 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":"core_memory/runtime/dreamer/eval.py"},"region":{"startLine":18}}}],"partialFingerprints":{"codehealthFindingId/v1":"c3323b71ee74b2d9ff943f14057a25cc95e2ca946a3beba8343f03180bed3ac3"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (11 lines \u00D7 2): scripts/check_architecture_guards.py:1030-1040 | scripts/check_architecture_guards.py:1063-1073 \u2014 both copies are in the same file, so extract the block 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/check_architecture_guards.py"},"region":{"startLine":1030}}}],"partialFingerprints":{"codehealthFindingId/v1":"bc1216253590419aefeb82f9fa3b181fc10a321bda62bf0f290fc47d31b988d4"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (10 lines \u00D7 6): core_memory/persistence/myelination_rewards.py:149-158 | core_memory/persistence/myelination_rewards.py:610-619 | core_memory/persistence/retrieval_feedback.py:158-167 | core_memory/runtime/dreamer/eval.py:135-144 | core_memory/runtime/dreamer/projection.py:273-282 | core_memory/soul/store.py:86-95 \u2014 there are 6 copies across 5 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 6 sites; resolving a subset leaves the remainder to drift apart. 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":"core_memory/persistence/myelination_rewards.py"},"region":{"startLine":149}}}],"partialFingerprints":{"codehealthFindingId/v1":"549b4764046972c65953876768eb7cd950810c8cf896d14076eba7cbfac639d2"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9\u201310 lines \u00D7 5): core_memory/persistence/retrieval_feedback.py:18-26 | core_memory/runtime/dreamer/eval.py:17-26 | core_memory/runtime/dreamer/longitudinal.py:11-20 | core_memory/runtime/observability/self_model_drift.py:22-30 | core_memory/temporal/resolution.py:8-16 \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. 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 \u0060value\u0060 to \u0060str | None\u0060 in one and \u0060Any\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":"core_memory/persistence/retrieval_feedback.py"},"region":{"startLine":18}}}],"partialFingerprints":{"codehealthFindingId/v1":"7a4ed4b45889cdfccf1ceb2244406185c5944bfdb2798b17ec0e848a7e90ad61"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (10 lines \u00D7 4): core_memory/runtime/dreamer/convergence.py:157-166 | core_memory/runtime/dreamer/goal_decay.py:134-143 | core_memory/runtime/dreamer/goal_discovery.py:142-151 | core_memory/runtime/dreamer/tension_discovery.py:77-86 \u2014 before extracting anything, compare \u0060core_memory/runtime/dreamer/goal_decay.py\u0060 and \u0060core_memory/runtime/dreamer/goal_discovery.py\u0060 as WHOLE FILES: this scan already matched 4 separate duplicated blocks between them, totalling at least 84 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. If that is what happened, the fix is to keep one copy and have the other call it (or delete it), which resolves this row and its siblings together \u2014 extracting one helper per block leaves the fork in place. The 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":"core_memory/runtime/dreamer/convergence.py"},"region":{"startLine":157}}}],"partialFingerprints":{"codehealthFindingId/v1":"a7a3922b4b9fd1784392f1f0b23a1ba8500cf725560a1a1d109ec1245b515adb"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (10 lines \u00D7 3): core_memory/association/crawler_contract.py:143-152 | core_memory/runtime/ingest/external_evidence.py:106-115 | core_memory/schema/models.py:265-274 \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":"core_memory/association/crawler_contract.py"},"region":{"startLine":143}}}],"partialFingerprints":{"codehealthFindingId/v1":"ac7e6c8ac48fd7f60f41fbb8791142cdf51b7265eee626b406b57052988ce494"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9\u201310 lines \u00D7 3): core_memory/integrations/openclaw/agent_end_bridge.py:328-337 | core_memory/integrations/openclaw/compaction_bridge.py:63-72 | core_memory/integrations/openclaw/hosted_capture_bridge.py:281-289 \u2014 the copies sit in sibling files of one directory, so a shared home is within easy reach: extract the block into a single shared function the call sites can all reach \u2014 a file they already depend on, or a new one alongside them \u2014 and call it from all 3 call sites, so a change lands once. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"core_memory/integrations/openclaw/agent_end_bridge.py"},"region":{"startLine":328}}}],"partialFingerprints":{"codehealthFindingId/v1":"405f0148db6ddddf8b6cadb6d1097eca6fac5f0c0b718e7da94072afaf7a9603"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (10 lines \u00D7 3): core_memory/persistence/retrieval_feedback.py:38-47 | core_memory/runtime/dreamer/eval.py:35-44 | core_memory/runtime/dreamer/longitudinal.py:29-38 \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":"core_memory/persistence/retrieval_feedback.py"},"region":{"startLine":38}}}],"partialFingerprints":{"codehealthFindingId/v1":"e39a4783b7494f173f8cd394efddb36f37127f2dd52bc5a5e39c85051ee96ed1"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (8\u201310 lines \u00D7 2): core_memory/integrations/mcp/tools/ingest_discord.py:122-131 | core_memory/integrations/mcp/tools/ingest_slack.py:112-119 \u2014 before extracting anything, compare \u0060core_memory/integrations/mcp/tools/ingest_discord.py\u0060 and \u0060core_memory/integrations/mcp/tools/ingest_slack.py\u0060 as WHOLE FILES: this scan already matched 6 separate duplicated blocks between them, totalling at least 76 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. If that is what happened, the fix is to keep one copy and have the other call it (or delete it), which resolves this row and its siblings together \u2014 extracting one helper per block leaves the fork in place. Read the line range as the matched WINDOW rather than a finished unit: at \u0060core_memory/integrations/mcp/tools/ingest_discord.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."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"core_memory/integrations/mcp/tools/ingest_discord.py"},"region":{"startLine":122}}}],"partialFingerprints":{"codehealthFindingId/v1":"23cdb16543a5abd7a290e169d4c9b197737b11a1c0653501e8b05162027c707c"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (10 lines \u00D7 2): core_memory/integrations/openclaw/agent_end_bridge.py:266-275 | core_memory/integrations/openclaw/hosted_capture_bridge.py:119-128 \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":"core_memory/integrations/openclaw/agent_end_bridge.py"},"region":{"startLine":266}}}],"partialFingerprints":{"codehealthFindingId/v1":"407cb859908d40f2c46e4406ee64d193774281b51f45889b7889e4b1ecc0d688"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (10 lines \u00D7 2): core_memory/persistence/metrics_ops.py:31-40 | core_memory/persistence/store_metrics_runtime.py:30-39 \u2014 before extracting anything, compare \u0060core_memory/persistence/metrics_ops.py\u0060 and \u0060core_memory/persistence/store_metrics_runtime.py\u0060 as WHOLE FILES: this scan already matched 3 separate duplicated blocks between them, totalling at least 31 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. If that is what happened, the fix is to keep one copy and have the other call it (or delete it), which resolves this row and its siblings together \u2014 extracting one helper per block leaves the fork in place. 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, \u0060core_memory/persistence/store_metrics_runtime.py:28\u0060 calls \u0060read_metrics_state_for_store\u0060, \u0060_default_state\u0060 and \u0060core_memory/persistence/metrics_ops.py:30\u0060 does not \u2014 after which the two agree again for 3 more lines. One of those two behaviours is the intended one and the other is what a copy-paste left behind, so decide which BEFORE unifying them: extracting the shared part will silently settle it, and if the copy that skips the call is the wrong one, that bug is already live."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"core_memory/persistence/metrics_ops.py"},"region":{"startLine":31}}}],"partialFingerprints":{"codehealthFindingId/v1":"7431e2ad4ec9b3ce7ea9a38b8399b8b538ac17c42f898e45387530ce0a8333d2"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9\u201310 lines \u00D7 2): core_memory/policy/bead_judge.py:350-358 | core_memory/policy/rationale.py:214-223 \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 \u0060core_memory/policy/rationale.py:214\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":"core_memory/policy/bead_judge.py"},"region":{"startLine":350}}}],"partialFingerprints":{"codehealthFindingId/v1":"e73c23f8463ce050070b65c5b812113d6c20f953d82aa29afeb807a754d362a8"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (10 lines \u00D7 2): core_memory/retrieval/adapters/pipehouse_adapter.py:18-27 | core_memory/retrieval/fanout.py:17-26 \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":"core_memory/retrieval/adapters/pipehouse_adapter.py"},"region":{"startLine":18}}}],"partialFingerprints":{"codehealthFindingId/v1":"3d5155b7e333c97f55bf25889fcc64ac07a3fda146fea9583f678f99eb4e7857"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (10 lines \u00D7 2): core_memory/runtime/dreamer/eval.py:65-74 | core_memory/runtime/dreamer/longitudinal.py:59-68 \u2014 before extracting anything, compare \u0060core_memory/runtime/dreamer/eval.py\u0060 and \u0060core_memory/runtime/dreamer/longitudinal.py\u0060 as WHOLE FILES: this scan already matched 11 separate duplicated blocks between them, totalling at least 95 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. If that is what happened, the fix is to keep one copy and have the other call it (or delete it), which resolves this row and its siblings together \u2014 extracting one helper per block leaves the fork in place. The 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":"core_memory/runtime/dreamer/eval.py"},"region":{"startLine":65}}}],"partialFingerprints":{"codehealthFindingId/v1":"407cf0f6811284727c30799ea92c3233109ef404148131b989e8f44da830acf9"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7\u201310 lines \u00D7 2): core_memory/runtime/observability/reviewer_quick_value.py:73-82 | core_memory/runtime/observability/reviewer_quick_value.py:88-94 \u2014 both copies are in the same file, so extract the block 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 \u0060core_memory/runtime/observability/reviewer_quick_value.py:73\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":"core_memory/runtime/observability/reviewer_quick_value.py"},"region":{"startLine":73}}}],"partialFingerprints":{"codehealthFindingId/v1":"21c71aac2801757739469b5ac22e6f824fe0fa9102a17e563a34152c05925763"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9 lines \u00D7 4): core_memory/graph/storylines.py:43-51 | core_memory/persistence/semantic_task_receipts.py:96-104 | core_memory/runtime/associations/coverage.py:189-197 | core_memory/runtime/associations/coverage.py:205-213 \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. 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":"core_memory/graph/storylines.py"},"region":{"startLine":43}}}],"partialFingerprints":{"codehealthFindingId/v1":"75f1db48ecc735b567c9a401781ffcb68c0b1d0d257eb7b6114ec0338c2301c7"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (8\u20139 lines \u00D7 4): core_memory/integrations/openclaw/agent_end_bridge.py:327-334 | core_memory/integrations/openclaw/compaction_bridge.py:62-70 | core_memory/integrations/openclaw/hosted_capture_bridge.py:280-287 | core_memory/integrations/openclaw/read_bridge.py:138-145 \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. 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":"core_memory/integrations/openclaw/agent_end_bridge.py"},"region":{"startLine":327}}}],"partialFingerprints":{"codehealthFindingId/v1":"3d4986da815d6adae03977d34f91a2862f82b8b89b54dff5bef82b3c82832afb"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9 lines \u00D7 3): core_memory/retrieval/pipeline/snap.py:54-62 | core_memory/retrieval/pipeline/snap.py:65-73 | core_memory/retrieval/pipeline/snap.py:76-84 \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":"core_memory/retrieval/pipeline/snap.py"},"region":{"startLine":54}}}],"partialFingerprints":{"codehealthFindingId/v1":"849734fbb37964953c49e416e9aa7693b9ec67fad5e67290a014831c08de4485"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7\u20139 lines \u00D7 2): core_memory/cli/__init__.py:130-138 | core_memory/cli/__init__.py:246-252 \u2014 both copies are in the same file, so extract the block into one function there and call it from each site \u2014 the copies drift apart the first time only one of them is edited."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"core_memory/cli/__init__.py"},"region":{"startLine":130}}}],"partialFingerprints":{"codehealthFindingId/v1":"f6922c0532b9ad3f84a44d7eed18150d6ac2b04f07756576ff02c2048a841e68"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9 lines \u00D7 2): core_memory/cli/parsers/extended.py:15-23 | core_memory/cli/parsers/extended.py:25-33 \u2014 both copies are in the same file, so extract the block 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":"core_memory/cli/parsers/extended.py"},"region":{"startLine":15}}}],"partialFingerprints":{"codehealthFindingId/v1":"26af7a29d1b78c40b9929d89f96f17fb6bfdb4ce33ec9fb10ee947ab7cea253c"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9 lines \u00D7 2): core_memory/config/feature_flags.py:16-24 | core_memory/integrations/neo4j/config.py:52-60 \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":"core_memory/config/feature_flags.py"},"region":{"startLine":16}}}],"partialFingerprints":{"codehealthFindingId/v1":"6d1fe35552ae891ae35a24c254b36fb0cf7a66fe862c27ab7ed90293d77db4e1"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9 lines \u00D7 2): core_memory/graph/root_cause.py:306-314 | core_memory/graph/root_cause.py:329-337 \u2014 both copies are in the same file, so extract the block into one function there and call it from each site \u2014 the copies drift apart the first time only one of them is edited."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"core_memory/graph/root_cause.py"},"region":{"startLine":306}}}],"partialFingerprints":{"codehealthFindingId/v1":"ce5ba884d126147112cbd58eee6b42b060be978a423a8e26b261ab2e61e29c2c"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9 lines \u00D7 2): core_memory/integrations/mcp/tools/transcript_snapshot_state.py:158-166 | core_memory/integrations/mcp/tools/transcript_snapshot_state.py:190-198 \u2014 both copies are in the same file, so extract the block 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, \u0060core_memory/integrations/mcp/tools/transcript_snapshot_state.py:189\u0060 calls \u0060str\u0060 and \u0060core_memory/integrations/mcp/tools/transcript_snapshot_state.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":"core_memory/integrations/mcp/tools/transcript_snapshot_state.py"},"region":{"startLine":158}}}],"partialFingerprints":{"codehealthFindingId/v1":"587f7ea3c124917db1ba4403d38575f010e130312930182466050e52c1da3eae"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9 lines \u00D7 2): core_memory/persistence/store_claim_ops.py:378-386 | core_memory/persistence/store_claim_ops.py:394-402 \u2014 both copies are in the same file, so extract the block 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":"core_memory/persistence/store_claim_ops.py"},"region":{"startLine":378}}}],"partialFingerprints":{"codehealthFindingId/v1":"82f8fffdfe2059068cfabd86b6dca84d17ffbf71f9c6149818d30ddf8a872d85"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9 lines \u00D7 2): core_memory/runtime/dreamer/eval.py:161-169 | core_memory/runtime/dreamer/longitudinal.py:73-81 \u2014 before extracting anything, compare \u0060core_memory/runtime/dreamer/eval.py\u0060 and \u0060core_memory/runtime/dreamer/longitudinal.py\u0060 as WHOLE FILES: this scan already matched 11 separate duplicated blocks between them, totalling at least 95 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. If that is what happened, the fix is to keep one copy and have the other call it (or delete it), which resolves this row and its siblings together \u2014 extracting one helper per block leaves the fork in place. The \u0060return\u0060 at the foot of the matched lines is the enclosing body\u0027s own terminal exit, not an early one: it moves with them unchanged, and each site calls the extracted unit from the position that \u0060return\u0060 occupied \u2014 no decision has to be handed back and re-acted on."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"core_memory/runtime/dreamer/eval.py"},"region":{"startLine":161}}}],"partialFingerprints":{"codehealthFindingId/v1":"854bf2d503466801deac3e426b378bcd6636d034b5b5052d9994858ca90fc31b"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9 lines \u00D7 2): core_memory/runtime/dreamer/geometry.py:129-137 | core_memory/soul/assembly_depth.py:150-158 \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":"core_memory/runtime/dreamer/geometry.py"},"region":{"startLine":129}}}],"partialFingerprints":{"codehealthFindingId/v1":"224002a9b26702d13e813342e1c758574edb2d2806807d9b642f34156a40d4ea"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9 lines \u00D7 2): core_memory/runtime/turn/reauthoring.py:100-108 | core_memory/runtime/turn/semantic_state.py:355-363 \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":"core_memory/runtime/turn/reauthoring.py"},"region":{"startLine":100}}}],"partialFingerprints":{"codehealthFindingId/v1":"00d4407b3ea3f15d903843e26a95e9e6b5dd7843df072047249cff6fdb1de7ce"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (8 lines \u00D7 5): core_memory/graph/storylines.py:42-49 | core_memory/persistence/semantic_task_receipts.py:95-102 | core_memory/persistence/session_surface.py:23-30 | core_memory/runtime/associations/coverage.py:188-195 | core_memory/runtime/associations/coverage.py:204-211 \u2014 there are 5 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 5 sites; resolving a subset leaves the remainder to drift apart. 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":"core_memory/graph/storylines.py"},"region":{"startLine":42}}}],"partialFingerprints":{"codehealthFindingId/v1":"56fb1650a9186ed96051fe9a048978581e0547c2062bb6e602dcc3f1ad7b3791"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (8 lines \u00D7 5): core_memory/integrations/pydanticai/semantic_tasks.py:37-44 | core_memory/policy/bead_judge.py:300-307 | core_memory/policy/bead_typing.py:120-127 | core_memory/policy/rationale.py:168-175 | core_memory/policy/semantic_task_runtime.py:197-204 \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. \u2605 These copies have DRIFTED, and that is worth reading before extracting anything: just after the matched lines, \u0060core_memory/policy/bead_judge.py:308\u0060 calls \u0060isinstance\u0060 and \u0060core_memory/integrations/pydanticai/semantic_tasks.py:45\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":"core_memory/integrations/pydanticai/semantic_tasks.py"},"region":{"startLine":37}}}],"partialFingerprints":{"codehealthFindingId/v1":"0d03938faa63fc664e39ffee27b123fb3c53df99164ce72feedf00b81d6763f4"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (8 lines \u00D7 3): core_memory/integrations/mcp/tools/ingest_discord.py:104-111 | core_memory/integrations/mcp/tools/ingest_slack.py:99-106 | core_memory/integrations/mcp/tools/ingest_zoom.py:164-171 \u2014 before extracting anything, compare \u0060core_memory/integrations/mcp/tools/ingest_discord.py\u0060 and \u0060core_memory/integrations/mcp/tools/ingest_slack.py\u0060 as WHOLE FILES: this scan already matched 6 separate duplicated blocks between them, totalling at least 76 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. If that is what happened, the fix is to keep one copy and have the other call it (or delete it), which resolves this row and its siblings together \u2014 extracting one helper per block leaves the fork in place. Read the line range as the matched WINDOW rather than a finished unit: at \u0060core_memory/integrations/mcp/tools/ingest_discord.py:104\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":"core_memory/integrations/mcp/tools/ingest_discord.py"},"region":{"startLine":104}}}],"partialFingerprints":{"codehealthFindingId/v1":"19df9c2a5b731e61879119691aa86a9dde8b050d3dd0b870fdfb22a6cd46ed31"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (8 lines \u00D7 2): core_memory/cli/handlers/integrations.py:21-28 | core_memory/cli/handlers/integrations.py:39-46 \u2014 both copies are in the same file, so extract the block 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":"core_memory/cli/handlers/integrations.py"},"region":{"startLine":21}}}],"partialFingerprints":{"codehealthFindingId/v1":"71798ac4e8db061b426b0a373ca1041c9f21eb951451000c98b8eabf6ff4286a"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (8 lines \u00D7 2): core_memory/integrations/http/server.py:1078-1085 | core_memory/integrations/http/server.py:1158-1165 \u2014 both copies are in the same file, so extract the block 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 \u0060core_memory/integrations/http/server.py:1078\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":"core_memory/integrations/http/server.py"},"region":{"startLine":1078}}}],"partialFingerprints":{"codehealthFindingId/v1":"542cd7ce39f0b3cc4cafdcf520a272bb08bd60ced588371cdd096a4dc8c21cc9"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (8 lines \u00D7 2): core_memory/management/__init__.py:1014-1021 | core_memory/management/__init__.py:1101-1108 \u2014 both copies are in the same file, so extract the block 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 \u0060core_memory/management/__init__.py:1014\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":"core_memory/management/__init__.py"},"region":{"startLine":1014}}}],"partialFingerprints":{"codehealthFindingId/v1":"de79a7ead75a520583086eb58b42a7834e725b52003c6b8b1005464017ac2412"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (8 lines \u00D7 2): core_memory/persistence/store_autonomy_ops.py:12-19 | core_memory/schema/promotion.py:88-96 \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":"core_memory/persistence/store_autonomy_ops.py"},"region":{"startLine":12}}}],"partialFingerprints":{"codehealthFindingId/v1":"9fcbebae1a3ee2a6ab556b249f404e3b037b00695ee6866e4298f42fc214f1a6"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (8 lines \u00D7 2): core_memory/persistence/store_claim_ops.py:180-187 | core_memory/policy/association_inference_v21.py:78-85 \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":"core_memory/persistence/store_claim_ops.py"},"region":{"startLine":180}}}],"partialFingerprints":{"codehealthFindingId/v1":"a7b2c9a54a0b107eb171cc48a8d9e3ebe9a36f33dd4840313da3528120d3722d"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (8 lines \u00D7 2): core_memory/persistence/store_validation_helpers.py:142-149 | core_memory/persistence/store_validation_helpers.py:153-160 \u2014 both copies are in the same file, so extract the block 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":"core_memory/persistence/store_validation_helpers.py"},"region":{"startLine":142}}}],"partialFingerprints":{"codehealthFindingId/v1":"ffeb0e698a54ee0393d3b43a648cc1490238ee5543f62181c2e84ba075aafaf2"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (8 lines \u00D7 2): core_memory/provider_config.py:150-157 | core_memory/provider_config.py:182-189 \u2014 both copies are in the same file, so extract the block into one function there and call it from each site \u2014 the copies drift apart the first time only one of them is edited."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"core_memory/provider_config.py"},"region":{"startLine":150}}}],"partialFingerprints":{"codehealthFindingId/v1":"fe374f182a7e48c5149b633957335015aa4094b5c5a51a90488b4b14a90ea8c5"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (8 lines \u00D7 2): core_memory/retrieval/pipeline/canonical.py:950-957 | core_memory/retrieval/pipeline/canonical.py:960-967 \u2014 both copies are in the same file, so extract the block into one function there and call it from each site \u2014 the copies drift apart the first time only one of them is edited. 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":"core_memory/retrieval/pipeline/canonical.py"},"region":{"startLine":950}}}],"partialFingerprints":{"codehealthFindingId/v1":"8d90d4921cdb0da5b5049168c6223b0d9e980cc3d3cc81b271b9e8226af46504"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (8 lines \u00D7 2): core_memory/runtime/dreamer/refinement.py:183-190 | core_memory/runtime/dreamer/research.py:342-349 \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 \u0060core_memory/runtime/dreamer/refinement.py:183\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":"core_memory/runtime/dreamer/refinement.py"},"region":{"startLine":183}}}],"partialFingerprints":{"codehealthFindingId/v1":"1c6126d012bfbc7db2030414660fd4b10d998d338c5c1dd5d2cf8afa1434b12d"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 3): core_memory/graph/core.py:143-149 | core_memory/persistence/store_validation_helpers.py:11-17 | core_memory/schema/promotion.py:58-64 \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":"core_memory/graph/core.py"},"region":{"startLine":143}}}],"partialFingerprints":{"codehealthFindingId/v1":"3ce14d380efa0df0a82d5603bc5a560beee6e53f4449be0d4e3cc21ff35a1d5d"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 2): core_memory/integrations/http/server.py:642-648 | core_memory/integrations/http/server.py:716-722 \u2014 both copies are in the same file, so extract the block 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":"core_memory/integrations/http/server.py"},"region":{"startLine":642}}}],"partialFingerprints":{"codehealthFindingId/v1":"9e827a0b06b0d6d332895a914c53ce7bd195ef976180f2b799f7f31e5e0a4c94"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 2): core_memory/integrations/http/server.py:2107-2113 | core_memory/integrations/http/server.py:2115-2121 \u2014 both copies are in the same file, so extract the block 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 \u0060core_memory/integrations/http/server.py:2107\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":"core_memory/integrations/http/server.py"},"region":{"startLine":2107}}}],"partialFingerprints":{"codehealthFindingId/v1":"5a78cabe5a8bba23fdb8c610818d073b254c4caed36ef54811b1247b6e51819f"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 2): core_memory/integrations/mcp/protocol_server.py:256-262 | core_memory/integrations/mcp/protocol_server.py:303-309 \u2014 both copies are in the same file, so extract the block 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 \u0060core_memory/integrations/mcp/protocol_server.py:256\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":"core_memory/integrations/mcp/protocol_server.py"},"region":{"startLine":256}}}],"partialFingerprints":{"codehealthFindingId/v1":"9b2f5c774f0406c58fd12b8de29984c41271791ca973eb9201fd78df7273724a"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 2): core_memory/persistence/dreamer_candidate_store.py:47-53 | core_memory/runtime/dreamer/analysis.py:273-279 \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":"core_memory/persistence/dreamer_candidate_store.py"},"region":{"startLine":47}}}],"partialFingerprints":{"codehealthFindingId/v1":"0fa904d5bf429bef58014548eec45e19823f050ef9fd47082a9c376d5ff7b027"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (2\u20137 lines \u00D7 4): core_memory/retrieval/agent.py:207-213 | core_memory/retrieval/agent.py:216-217 | core_memory/retrieval/agent.py:249-255 | core_memory/retrieval/agent.py:258-259 \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. Note that the copies do not run to the end of the range shown: their LAST lines are different code, not the same code under different names \u2014 the matched region ends inside that line. Extract the lines above it, and read the last line of each site separately. \u2605 These copies have DRIFTED, and that is worth reading before extracting anything: just after the matched lines, \u0060core_memory/retrieval/agent.py:213\u0060 calls \u0060get\u0060 and \u0060core_memory/retrieval/agent.py:217\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":"core_memory/retrieval/agent.py"},"region":{"startLine":207}}}],"partialFingerprints":{"codehealthFindingId/v1":"97cb7ee7af9a7fb49d104e5cc36d702b918fbd19b0bb43a3cf78484f1ac00e89"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 2): core_memory/retrieval/semantic_index.py:1160-1166 | core_memory/retrieval/semantic_index.py:1170-1176 \u2014 both copies are in the same file, so extract the block 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":"core_memory/retrieval/semantic_index.py"},"region":{"startLine":1160}}}],"partialFingerprints":{"codehealthFindingId/v1":"b2ac28639a201b636490998938420398dc74a01b1d571e33ecbf58bbafd0c6a6"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 2): core_memory/retrieval/tools/memory_reason.py:783-789 | core_memory/retrieval/tools/memory_reason.py:791-797 \u2014 both copies are in the same file, so extract the block 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":"core_memory/retrieval/tools/memory_reason.py"},"region":{"startLine":783}}}],"partialFingerprints":{"codehealthFindingId/v1":"7d7ef302e92f8ce12828dfd5efebe68b4a634aff279612d38624a167587c93e1"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 3): core_memory/association/slo.py:50-55 | core_memory/graph/traversal.py:125-130 | core_memory/retrieval/causal_recall.py:490-495 \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. \u2605 These copies have DRIFTED, and that is worth reading before extracting anything: just after the matched lines, \u0060core_memory/retrieval/causal_recall.py:496\u0060 calls \u0060str\u0060, \u0060get\u0060, \u0060strip\u0060 and \u0060core_memory/graph/traversal.py:131\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":"core_memory/association/slo.py"},"region":{"startLine":50}}}],"partialFingerprints":{"codehealthFindingId/v1":"e57a10e1f2cc107a54cf1440e74eb3c0ddde87e13469ba6a185104eceeb1dc93"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 3): core_memory/graph/traversal.py:50-55 | core_memory/graph/traversal.py:126-131 | core_memory/integrations/neo4j/sync.py:226-231 \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 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":"core_memory/graph/traversal.py"},"region":{"startLine":50}}}],"partialFingerprints":{"codehealthFindingId/v1":"34e0910371d3f2ac5e0e2a98deb45b1ccbc51a360ee371ccc28fb5f3b95c9526"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 3): core_memory/runtime/dreamer/goal_decay.py:147-176 | core_memory/runtime/dreamer/goal_discovery.py:182-187 | core_memory/runtime/dreamer/tension_discovery.py:118-123 \u2014 before extracting anything, compare \u0060core_memory/runtime/dreamer/goal_decay.py\u0060 and \u0060core_memory/runtime/dreamer/goal_discovery.py\u0060 as WHOLE FILES: this scan already matched 4 separate duplicated blocks between them, totalling at least 84 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. If that is what happened, the fix is to keep one copy and have the other call it (or delete it), which resolves this row and its siblings together \u2014 extracting one helper per block leaves the fork in place. Read the line range as the matched WINDOW rather than a finished unit: at \u0060core_memory/runtime/dreamer/goal_discovery.py:182\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":"core_memory/runtime/dreamer/goal_decay.py"},"region":{"startLine":147}}}],"partialFingerprints":{"codehealthFindingId/v1":"fe2d56d1794b02636ab3937812d84be62a7a9fe08236a2c427ce5013e3e387b3"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2): core_memory/cli/handlers/graph.py:52-57 | core_memory/cli/handlers/store.py:144-149 \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":"core_memory/cli/handlers/graph.py"},"region":{"startLine":52}}}],"partialFingerprints":{"codehealthFindingId/v1":"dc6fcac25fa14f4e5f7356ba1a92ba85e559f2be6a81ff7833d41f03495ced4f"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2): core_memory/graph/core.py:196-201 | core_memory/graph/traversal.py:49-54 \u2014 the copies sit in sibling files of one directory, so a shared home is within easy reach: extract the block into a single shared function the call sites can all reach \u2014 a file they already depend on, or a new one alongside them \u2014 and call it from both call sites, so a change lands once. 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":"core_memory/graph/core.py"},"region":{"startLine":196}}}],"partialFingerprints":{"codehealthFindingId/v1":"da7034889bf05f157f1be57957b6190c555a6e17cbfb351f32c23fe9604df439"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2): core_memory/graph/core.py:204-209 | core_memory/graph/core.py:541-548 \u2014 both copies are in the same file, so extract the block 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":"core_memory/graph/core.py"},"region":{"startLine":204}}}],"partialFingerprints":{"codehealthFindingId/v1":"e23346637e62612f0a9563bc58c2f461b339ed76772ea9395920e610435a6b98"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2): core_memory/graph/core.py:751-756 | core_memory/runtime/dreamer/analysis.py:70-75 \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":"core_memory/graph/core.py"},"region":{"startLine":751}}}],"partialFingerprints":{"codehealthFindingId/v1":"7d52db421928e3bb28d383b4e1f8eac8160370cd7e883c84a522c29769820cbe"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2): core_memory/integrations/http/server.py:2305-2310 | core_memory/integrations/http/server.py:2730-2735 \u2014 both copies are in the same file, so extract the block 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, \u0060core_memory/integrations/http/server.py:2311\u0060 calls \u0060str\u0060 and \u0060core_memory/integrations/http/server.py:2736\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":"core_memory/integrations/http/server.py"},"region":{"startLine":2305}}}],"partialFingerprints":{"codehealthFindingId/v1":"a2820c3350b0be4baefbbdb8abbfcb3150ea70061d30437a2715d5f1f15153b0"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2): core_memory/integrations/neo4j/sync.py:184-189 | core_memory/integrations/neo4j/sync.py:225-230 \u2014 both copies are in the same file, so extract the block 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":"core_memory/integrations/neo4j/sync.py"},"region":{"startLine":184}}}],"partialFingerprints":{"codehealthFindingId/v1":"298db8de3d5880392b4a54dd62041375c9e4a721f6bec555f8a93ed176f04cd3"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2): core_memory/integrations/pydanticai/semantic_tasks.py:28-33 | core_memory/policy/semantic_task_runtime.py:211-216 \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":"core_memory/integrations/pydanticai/semantic_tasks.py"},"region":{"startLine":28}}}],"partialFingerprints":{"codehealthFindingId/v1":"449dd8615e544dd80bec4ab7709d0053b84e3ef6878f7f67fa643c71147aad3d"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2): core_memory/integrations/pydanticai/semantic_tasks.py:190-195 | core_memory/policy/semantic_task_runtime.py:336-341 \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":"core_memory/integrations/pydanticai/semantic_tasks.py"},"region":{"startLine":190}}}],"partialFingerprints":{"codehealthFindingId/v1":"127dde0c5601db345cf99bcf21f499ce36157ab2468dad8b860db71beaf29073"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2): core_memory/management/__init__.py:1002-1007 | core_memory/management/__init__.py:1072-1077 \u2014 both copies are in the same file, so extract the block 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 \u0060core_memory/management/__init__.py:1002\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":"core_memory/management/__init__.py"},"region":{"startLine":1002}}}],"partialFingerprints":{"codehealthFindingId/v1":"a441b44f8e5b115c06093bbb98fbecf43ecad8b5aff3a17c4d5dc1b1f543e405"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2): core_memory/management/__init__.py:1029-1034 | core_memory/management/__init__.py:1085-1090 \u2014 both copies are in the same file, so extract the block 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 \u0060core_memory/management/__init__.py:1029\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":"core_memory/management/__init__.py"},"region":{"startLine":1029}}}],"partialFingerprints":{"codehealthFindingId/v1":"4aaa759ce46afd629f36d8dbc644b89296f4800124dc70521bb3e5b34a4cadd2"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2): core_memory/management/__init__.py:1075-1080 | core_memory/management/__init__.py:1088-1093 \u2014 both copies are in the same file, so extract the block 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, \u0060core_memory/management/__init__.py:1094\u0060 calls \u0060_clean_str\u0060, \u0060get\u0060 and \u0060core_memory/management/__init__.py:1081\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":"core_memory/management/__init__.py"},"region":{"startLine":1075}}}],"partialFingerprints":{"codehealthFindingId/v1":"5f263ff9b60c1eda965280c0857d4d165b34fe30be93aa0ac8ad9dea65d41c25"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2): core_memory/management/__init__.py:1226-1231 | core_memory/management/__init__.py:1270-1275 \u2014 both copies are in the same file, so extract the block 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":"core_memory/management/__init__.py"},"region":{"startLine":1226}}}],"partialFingerprints":{"codehealthFindingId/v1":"fbf258fa013f9bb20ac514582dab35559a39a820a874207dd3f5cba8b83804d7"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2): core_memory/persistence/retrieval_feedback.py:201-206 | core_memory/schema/bead_projection.py:128-133 \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":"core_memory/persistence/retrieval_feedback.py"},"region":{"startLine":201}}}],"partialFingerprints":{"codehealthFindingId/v1":"a41abccb1411db245bd231de495f935b58a3fd5a0dc61627138c7c18faf2c5e3"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2): core_memory/persistence/store_session_ops.py:41-46 | core_memory/persistence/store_session_ops.py:50-55 \u2014 both copies are in the same file, so extract the block 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":"core_memory/persistence/store_session_ops.py"},"region":{"startLine":41}}}],"partialFingerprints":{"codehealthFindingId/v1":"1e4a414ca94cc348754a36211e281f0b63f49b9a3fbb2634218ac13a226f9348"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2): core_memory/persistence/store_validation_helpers.py:105-110 | core_memory/persistence/store_validation_helpers.py:112-117 \u2014 both copies are in the same file, so extract the block 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":"core_memory/persistence/store_validation_helpers.py"},"region":{"startLine":105}}}],"partialFingerprints":{"codehealthFindingId/v1":"970e4568ac624bb5b4450dfbbd2ecb979bcdd23cfbfc0f6fc1b29e49b8359b1e"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2): core_memory/retrieval/causal_recall.py:498-503 | core_memory/soul/summary.py:412-417 \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":"core_memory/retrieval/causal_recall.py"},"region":{"startLine":498}}}],"partialFingerprints":{"codehealthFindingId/v1":"74cb0768f7177e822eb0f75b9492837ee4f7c3378653e96238151366f693d8ce"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2): core_memory/retrieval/normalize.py:13-18 | core_memory/retrieval/query_norm.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 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":"core_memory/retrieval/normalize.py"},"region":{"startLine":13}}}],"partialFingerprints":{"codehealthFindingId/v1":"8a13ac39608749d7bb2629ff00d7446f47da1e3ea09ac771f352e32d249f7406"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2): core_memory/runtime/observability/myelination.py:265-270 | core_memory/runtime/observability/myelination.py:275-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. Read the line range as the matched WINDOW rather than a finished unit: at \u0060core_memory/runtime/observability/myelination.py:265\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":"core_memory/runtime/observability/myelination.py"},"region":{"startLine":265}}}],"partialFingerprints":{"codehealthFindingId/v1":"fc110137880b0d239816d79babdcc103b0c3ec6ce0ee6c2d742f541f1c5071c0"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2): core_memory/runtime/observability/reviewer_quick_value.py:89-94 | core_memory/runtime/observability/reviewer_quick_value.py:97-102 \u2014 both copies are in the same file, so extract the block 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 \u0060core_memory/runtime/observability/reviewer_quick_value.py:89\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":"core_memory/runtime/observability/reviewer_quick_value.py"},"region":{"startLine":89}}}],"partialFingerprints":{"codehealthFindingId/v1":"9ba782c01f3e5b9a4e9d6a97dd635385d220c6beef5ea2b7e13d36279558e548"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 4): core_memory/retrieval/agent.py:512-516 | core_memory/retrieval/agent.py:553-557 | core_memory/retrieval/agent.py:584-588 | core_memory/retrieval/agent.py:758-762 \u2014 all 4 copies are in the same file, so extract the block into one function there and call it from every one of those sites \u2014 resolving only two of them leaves the rest to drift apart the first time one is edited. Read the line range as the matched WINDOW rather than a finished unit: at \u0060core_memory/retrieval/agent.py:512\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":"core_memory/retrieval/agent.py"},"region":{"startLine":512}}}],"partialFingerprints":{"codehealthFindingId/v1":"9a828c31e0d2ed611bcaba3bffba06246e4fcde966840305c6e47b049c8d86f3"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 3): core_memory/graph/traversal.py:126-130 | core_memory/integrations/neo4j/sync.py:226-230 | core_memory/retrieval/causal_recall.py:491-495 \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. \u2605 These copies have DRIFTED, and that is worth reading before extracting anything: just after the matched lines, \u0060core_memory/retrieval/causal_recall.py:496\u0060 calls \u0060str\u0060, \u0060get\u0060, \u0060strip\u0060 and \u0060core_memory/graph/traversal.py:131\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":"core_memory/graph/traversal.py"},"region":{"startLine":126}}}],"partialFingerprints":{"codehealthFindingId/v1":"7757a87c3f11d88a1ac8ea2f8b3fe71fc391fc49f3ff8ed874ae69edd07dbeb9"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 3): core_memory/retrieval/normalize.py:13-17 | core_memory/retrieval/query_norm.py:79-83 | core_memory/retrieval/rerank.py:38-42 \u2014 the copies sit in sibling files of one directory, so a shared home is within easy reach: extract the block into a single shared function the call sites can all reach \u2014 a file they already depend on, or a new one alongside them \u2014 and call it from all 3 call sites, so a change lands once."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"core_memory/retrieval/normalize.py"},"region":{"startLine":13}}}],"partialFingerprints":{"codehealthFindingId/v1":"2f4d121ad3de988f3b0f483fd492a8a4d808bac230cd4c606ef32eb4f2949295"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 3): core_memory/runtime/observability/reviewer_quick_value.py:90-94 | core_memory/runtime/observability/reviewer_quick_value.py:98-102 | core_memory/runtime/observability/reviewer_quick_value.py:229-233 \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 \u0060core_memory/runtime/observability/reviewer_quick_value.py:90\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":"core_memory/runtime/observability/reviewer_quick_value.py"},"region":{"startLine":90}}}],"partialFingerprints":{"codehealthFindingId/v1":"82b7dacc2a449392ebe13e8ff2b271062a60ecf5e1c2987319725a746b761725"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): core_memory/association/crawler_contract.py:603-607 | core_memory/association/crawler_contract.py:1014-1019 \u2014 both copies are in the same file, so extract the block 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, \u0060core_memory/association/crawler_contract.py:610\u0060 calls \u0060_association_in_session_scope\u0060 and \u0060core_memory/association/crawler_contract.py:1020\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":"core_memory/association/crawler_contract.py"},"region":{"startLine":603}}}],"partialFingerprints":{"codehealthFindingId/v1":"7e8fd208d887a53c02d9553bded3ed603847a552348cef6d936d46cdc0d3ddfc"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): core_memory/cli/__init__.py:159-163 | core_memory/cli/parsers/extended.py:132-136 \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":"core_memory/cli/__init__.py"},"region":{"startLine":159}}}],"partialFingerprints":{"codehealthFindingId/v1":"e00d809624ba9db9adba2860ba0bd3059dbe5c1d6960ddb73fcca9ebfe5f1db0"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): core_memory/cli/__init__.py:231-235 | core_memory/cli/parsers/extended.py:55-59 \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":"core_memory/cli/__init__.py"},"region":{"startLine":231}}}],"partialFingerprints":{"codehealthFindingId/v1":"fa5b8c7e91ffb36bd00c7b807579e5ec308a95792e2d60db49e23496239ef8b7"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): core_memory/cli/handlers/metrics.py:118-122 | core_memory/cli/handlers/metrics.py:132-136 \u2014 both copies are in the same file, so extract the block 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":"core_memory/cli/handlers/metrics.py"},"region":{"startLine":118}}}],"partialFingerprints":{"codehealthFindingId/v1":"ee9b4546e73e67ee3f37284d24beaa8d299ca151c09e30f2cb9b3011e6fcbbdb"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 3): core_memory/cli/parsers/extended.py:73-77 | core_memory/cli/parsers/extended.py:79-83 | core_memory/cli/parsers/ops.py:40-44 \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. 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":"core_memory/cli/parsers/extended.py"},"region":{"startLine":73}}}],"partialFingerprints":{"codehealthFindingId/v1":"5cd8a328932bbbfaa8a7de7f6028c431ba4fc4b29dc9bb48d2b9e96e5fe88baa"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): core_memory/graph/core.py:197-201 | core_memory/retrieval/causal_recall.py:491-495 \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":"core_memory/graph/core.py"},"region":{"startLine":197}}}],"partialFingerprints":{"codehealthFindingId/v1":"96a5e2ad0ef1b54babe2d4d198468f848a9bc13f1c7de1c3bf34cf8814666ca8"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): core_memory/graph/junctions.py:212-216 | core_memory/soul/dreamer_bridge.py:389-393 \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":"core_memory/graph/junctions.py"},"region":{"startLine":212}}}],"partialFingerprints":{"codehealthFindingId/v1":"08a2de90acf9778b313f72b8ec678e34a1b0be4429b0d5ce58363fc44ec6310f"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): core_memory/integrations/http/server.py:2495-2499 | core_memory/integrations/langchain/memory.py:93-99 \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 \u0060core_memory/integrations/http/server.py:2495\u0060 it does not close everything it opens, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that. Note that the copies do not run to the end of the range shown: their LAST lines are different code, not the same code under different names \u2014 the matched region ends inside that line. Extract the lines above it, and read the last line of each site separately."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"core_memory/integrations/http/server.py"},"region":{"startLine":2495}}}],"partialFingerprints":{"codehealthFindingId/v1":"b9d98b01da87078e830109b17a2007137bac9704a251d404d048d83f1c904d52"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 3): core_memory/integrations/mcp/protocol_server.py:162-175 | core_memory/integrations/mcp/protocol_server.py:207-229 | core_memory/integrations/mcp/protocol_server.py:290-294 \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 \u0060core_memory/integrations/mcp/protocol_server.py:162\u0060 it does not close everything it opens, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that. Note that the copies do not run to the end of the range shown: their LAST lines are different code, not the same code under different names \u2014 the matched region ends inside that line. Extract the lines above it, and read the last line of each site separately."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"core_memory/integrations/mcp/protocol_server.py"},"region":{"startLine":162}}}],"partialFingerprints":{"codehealthFindingId/v1":"689ee1fcfcdbe370b8e1be4b2f1d75ee3fb77d135dd03c6bbfb82efa4369caa5"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): core_memory/integrations/neo4j/sync.py:250-254 | core_memory/integrations/neo4j/sync.py:261-265 \u2014 both copies are in the same file, so extract the block 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":"core_memory/integrations/neo4j/sync.py"},"region":{"startLine":250}}}],"partialFingerprints":{"codehealthFindingId/v1":"62724bccc4d5021c8009e94853b17bc99a8440536367290afefcfcd1d62260f0"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): core_memory/integrations/openclaw/agent_end_bridge.py:193-198 | core_memory/integrations/openclaw/hosted_capture_bridge.py:199-203 \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":"core_memory/integrations/openclaw/agent_end_bridge.py"},"region":{"startLine":193}}}],"partialFingerprints":{"codehealthFindingId/v1":"ba065fe42c2cc8ad53d405cfa207106c78d6a09f5cdb0636171e88fca9bdce0f"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): core_memory/integrations/openclaw/read_bridge.py:37-41 | core_memory/integrations/openclaw/read_bridge.py:104-108 \u2014 both copies are in the same file, so extract the block 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":"core_memory/integrations/openclaw/read_bridge.py"},"region":{"startLine":37}}}],"partialFingerprints":{"codehealthFindingId/v1":"db963fe54853af249f275bc48abd52b5d77ceeb7238ddae2498c7375cb5acfc9"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): core_memory/management/__init__.py:436-440 | core_memory/management/__init__.py:492-496 \u2014 both copies are in the same file, so extract the block 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":"core_memory/management/__init__.py"},"region":{"startLine":436}}}],"partialFingerprints":{"codehealthFindingId/v1":"a13ca373a78da84dd986af28301d8429149914f9f244f21629bb141680dcb637"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): core_memory/persistence/myelination_rewards.py:212-216 | core_memory/runtime/observability/myelination.py:90-94 \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":"core_memory/persistence/myelination_rewards.py"},"region":{"startLine":212}}}],"partialFingerprints":{"codehealthFindingId/v1":"87c7efff64f39149b63f95341510156fc7b46eebd5eb1c33f3a84d6a4dbc8b04"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): core_memory/runtime/associations/coverage.py:1222-1226 | core_memory/runtime/associations/coverage.py:1232-1236 \u2014 both copies are in the same file, so extract the block 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 \u0060core_memory/runtime/associations/coverage.py:1222\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":"core_memory/runtime/associations/coverage.py"},"region":{"startLine":1222}}}],"partialFingerprints":{"codehealthFindingId/v1":"34cc98f272511fc161bbe9430d0da87aeff33c92564203f2188a5a96b38a8842"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): core_memory/runtime/dreamer/eval.py:191-195 | core_memory/runtime/dreamer/longitudinal.py:99-103 \u2014 before extracting anything, compare \u0060core_memory/runtime/dreamer/eval.py\u0060 and \u0060core_memory/runtime/dreamer/longitudinal.py\u0060 as WHOLE FILES: this scan already matched 11 separate duplicated blocks between them, totalling at least 95 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. If that is what happened, the fix is to keep one copy and have the other call it (or delete it), which resolves this row and its siblings together \u2014 extracting one helper per block leaves the fork in place. The 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":"core_memory/runtime/dreamer/eval.py"},"region":{"startLine":191}}}],"partialFingerprints":{"codehealthFindingId/v1":"9e50dafa56a019de4121cd70c968f2dc793d9628c93904d67b761368f3ecef06"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): core_memory/runtime/dreamer/geometry.py:129-133 | core_memory/soul/tension_signals.py:59-63 \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. \u2605 These copies have DRIFTED, and that is worth reading before extracting anything: just after the matched lines, \u0060core_memory/soul/tension_signals.py:64\u0060 calls \u0060normalize_relation_type\u0060, \u0060get\u0060 and \u0060core_memory/runtime/dreamer/geometry.py:134\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":"core_memory/runtime/dreamer/geometry.py"},"region":{"startLine":129}}}],"partialFingerprints":{"codehealthFindingId/v1":"cabd55e32c3199f67add5987e44554fd78944e98fd9319307b46c1c30a7a473f"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (3\u20135 lines \u00D7 3): core_memory/runtime/dreamer/goal_discovery.py:87-92 | core_memory/soul/assembly_depth.py:143-145 | core_memory/soul/identity_value_signals.py:75-79 \u2014 the copies span different directories, so extracting a shared function means choosing where it lives: put it somewhere all 3 call sites can already reach \u2014 a location they all depend on today, or a new shared one if there is none \u2014 and call it from each site; until then, every change has to be made 3 times. Note that the copies do not run to the end of the range shown: their LAST lines are different code, not the same code under different names \u2014 the matched region ends inside that line. Extract the lines above it, and read the last line of each site separately. \u2605 These copies have DRIFTED, and that is worth reading before extracting anything: just after the matched lines, \u0060core_memory/runtime/dreamer/goal_discovery.py:92\u0060 calls \u0060_read_index\u0060, \u0060str\u0060, \u0060get\u0060 and \u0060core_memory/soul/assembly_depth.py:145\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":"core_memory/runtime/dreamer/goal_discovery.py"},"region":{"startLine":87}}}],"partialFingerprints":{"codehealthFindingId/v1":"538d68a987f9b734a7d7ddd5007baffcfa12d869406953ddf91aee83d8dee539"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): core_memory/runtime/turn/ingress.py:28-32 | core_memory/runtime/turn/ingress.py:54-58 \u2014 both copies are in the same file, so extract the block 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":"core_memory/runtime/turn/ingress.py"},"region":{"startLine":28}}}],"partialFingerprints":{"codehealthFindingId/v1":"5b8024680f1cd7ab9022a88ed4aa132ae4df8ea20292ec9b8c41864ed73851f9"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): core_memory/soul/store.py:369-373 | core_memory/soul/store.py:386-390 \u2014 both copies are in the same file, so extract the block 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":"core_memory/soul/store.py"},"region":{"startLine":369}}}],"partialFingerprints":{"codehealthFindingId/v1":"61a5c7fb8092629fd5aea2acb81fd6f94da4ed6db3a126f765917d15564bab46"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): core_memory/integrations/obsidian/protocol.py:16-20 | core_memory/persistence/graph/protocol.py:14-70 \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. 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":"core_memory/integrations/obsidian/protocol.py"},"region":{"startLine":16}}}],"partialFingerprints":{"codehealthFindingId/v1":"6468628fb8077c816e028f9a523ce6ceb48676189be784e0e9d5192b4d80e25d"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 4): core_memory/association/edge_lifecycle.py:41-45 | core_memory/graph/worldlines.py:39-43 | core_memory/retrieval/agent.py:99-103 | core_memory/retrieval/causal_recall.py:37-41 \u2014 the copies span different directories, so extracting a shared function means choosing where it lives: put it somewhere all 4 call sites can already reach \u2014 a location they all depend on today, or a new shared one if there is none \u2014 and call it from each site; until then, every change has to be made 4 times. 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: the declarations holding them bind \u0060root\u0060 to \u0060str | Path\u0060 in one and \u0060str\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":"core_memory/association/edge_lifecycle.py"},"region":{"startLine":41}}}],"partialFingerprints":{"codehealthFindingId/v1":"cd32098f444aee71d58b774271aad5566bdb20ef3465278179a4bd3c7e9002c6"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 4): core_memory/graph/junctions.py:34-38 | core_memory/graph/roadmap.py:58-62 | core_memory/graph/root_cause.py:121-125 | core_memory/retrieval/roadmap_planner.py:42-46 \u2014 the copies span different directories, so extracting a shared function means choosing where it lives: put it somewhere all 4 call sites can already reach \u2014 a location they all depend on today, or a new shared one if there is none \u2014 and call it from each site; until then, every change has to be made 4 times. 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":"core_memory/graph/junctions.py"},"region":{"startLine":34}}}],"partialFingerprints":{"codehealthFindingId/v1":"29a0da1125df6fc9b0d36a9fcb418ca66027e1d68e9f92e1adfe2ecc336cefb1"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9 lines \u00D7 2): core_memory/graph/root_cause.py:63-71 | core_memory/retrieval/causal_recall.py:25-33 \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":"core_memory/graph/root_cause.py"},"region":{"startLine":63}}}],"partialFingerprints":{"codehealthFindingId/v1":"e3b881ae775fdbd0cf7625fa431e8460056341de7a5b6839e23f5cbc4a7cf7f2"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2): core_memory/integrations/mcp/tools/capture.py:11-16 | core_memory/integrations/mcp/tools/sync_transcript_snapshot.py:30-35 \u2014 the copies sit in sibling files of one directory, so a shared home is within easy reach: extract the block into a single shared function the call sites can all reach \u2014 a file they already depend on, or a new one alongside them \u2014 and call it from both call sites, so a change lands once. 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":"core_memory/integrations/mcp/tools/capture.py"},"region":{"startLine":11}}}],"partialFingerprints":{"codehealthFindingId/v1":"ca3ffff75409e205f50a4ce8d0c3c1689542278dc12e6d9ad5353fbb58ac3427"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2): core_memory/persistence/archive_index.py:16-21 | core_memory/runtime/state.py:148-153 \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":"core_memory/persistence/archive_index.py"},"region":{"startLine":16}}}],"partialFingerprints":{"codehealthFindingId/v1":"8558dc28284555746374883ca9312ee096510c8a5ce0179b10afaaf8d09e6609"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 4): core_memory/persistence/side_effect_outbox.py:29-34 | core_memory/runtime/dreamer/eval.py:48-53 | core_memory/runtime/dreamer/longitudinal.py:42-47 | core_memory/runtime/queue/compaction_queue.py:33-38 \u2014 before extracting anything, compare \u0060core_memory/runtime/dreamer/eval.py\u0060 and \u0060core_memory/runtime/dreamer/longitudinal.py\u0060 as WHOLE FILES: this scan already matched 11 separate duplicated blocks between them, totalling at least 95 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. If that is what happened, the fix is to keep one copy and have the other call it (or delete it), which resolves this row and its siblings together \u2014 extracting one helper per block leaves the fork in place. The 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":"core_memory/persistence/side_effect_outbox.py"},"region":{"startLine":29}}}],"partialFingerprints":{"codehealthFindingId/v1":"d155838852b67f319c2e5108fe2812a121a0ed3ae0d10f772d2c52a8cd32bd03"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): core_memory/policy/semantic_task_runtime.py:38-42 | core_memory/provider_config.py:106-110 \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":"core_memory/policy/semantic_task_runtime.py"},"region":{"startLine":38}}}],"partialFingerprints":{"codehealthFindingId/v1":"a42a83204a35350bbbbb09832ef61be9aa291987476e3086ad0f22a2187f20f7"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9 lines \u00D7 5): core_memory/retrieval/pipeline/canonical.py:633-641 | core_memory/retrieval/pipeline/search.py:15-23 | core_memory/retrieval/semantic_index.py:662-670 | core_memory/retrieval/tools/memory_reason.py:99-107 | core_memory/schema/promotion.py:321-329 \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. 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: the declarations holding them bind \u0060ts\u0060 to \u0060str\u0060 in one and \u0060str | None\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":"core_memory/retrieval/pipeline/canonical.py"},"region":{"startLine":633}}}],"partialFingerprints":{"codehealthFindingId/v1":"65514714b679944639ff72501539e2ebc7cae18646d977edc22e4d6e90e072c8"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 4): core_memory/runtime/associations/coverage.py:91-97 | core_memory/runtime/ingest/external_evidence.py:53-59 | core_memory/runtime/ingest/source_envelope.py:22-28 | core_memory/schema/models.py:295-301 \u2014 the copies span different directories, so extracting a shared function means choosing where it lives: put it somewhere all 4 call sites can already reach \u2014 a location they all depend on today, or a new shared one if there is none \u2014 and call it from each site; until then, every change has to be made 4 times. 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":"core_memory/runtime/associations/coverage.py"},"region":{"startLine":91}}}],"partialFingerprints":{"codehealthFindingId/v1":"c942fa4ad9ae1c7f4a37cc3ce813b0a3ef38bf6c4354dceb82f362acdcb961d8"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (8 lines \u00D7 5): core_memory/runtime/dreamer/candidates.py:50-57 | core_memory/runtime/dreamer/geometry.py:48-55 | core_memory/runtime/dreamer/refinement.py:51-58 | core_memory/runtime/dreamer/research.py:31-38 | core_memory/soul/summary.py:56-63 \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. 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, \u0060core_memory/runtime/dreamer/geometry.py:43\u0060 calls \u0060_manifest_path\u0060, \u0060Path\u0060 and \u0060core_memory/runtime/dreamer/refinement.py:47\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":"core_memory/runtime/dreamer/candidates.py"},"region":{"startLine":50}}}],"partialFingerprints":{"codehealthFindingId/v1":"72f7e619552e3db63290f8de68d44b28cbab5da21e49a3fc4a484c24a3ccc104"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): core_memory/runtime/dreamer/eval.py:57-61 | core_memory/runtime/dreamer/longitudinal.py:51-55 \u2014 before extracting anything, compare \u0060core_memory/runtime/dreamer/eval.py\u0060 and \u0060core_memory/runtime/dreamer/longitudinal.py\u0060 as WHOLE FILES: this scan already matched 11 separate duplicated blocks between them, totalling at least 95 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. If that is what happened, the fix is to keep one copy and have the other call it (or delete it), which resolves this row and its siblings together \u2014 extracting one helper per block leaves the fork in place. The 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":"core_memory/runtime/dreamer/eval.py"},"region":{"startLine":57}}}],"partialFingerprints":{"codehealthFindingId/v1":"73e8fecebffc4642e87c4d9210aa0d4ac0b0f08fbb86d09c686e4fb068887515"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 7): core_memory/runtime/dreamer/goal_decay.py:37-43 | core_memory/runtime/dreamer/goal_discovery.py:34-40 | core_memory/runtime/dreamer/projection.py:45-51 | core_memory/runtime/dreamer/tension_discovery.py:36-42 | core_memory/soul/assembly_depth.py:45-51 | core_memory/soul/identity_value_signals.py:27-33 | core_memory/soul/tension_signals.py:19-25 \u2014 before extracting anything, compare \u0060core_memory/runtime/dreamer/goal_decay.py\u0060 and \u0060core_memory/runtime/dreamer/goal_discovery.py\u0060 as WHOLE FILES: this scan already matched 4 separate duplicated blocks between them, totalling at least 84 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. If that is what happened, the fix is to keep one copy and have the other call it (or delete it), which resolves this row and its siblings together \u2014 extracting one helper per block leaves the fork in place. The 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":"core_memory/runtime/dreamer/goal_decay.py"},"region":{"startLine":37}}}],"partialFingerprints":{"codehealthFindingId/v1":"bea8eedbdce69cfc5d25083a87cfc46d26ae5998c0f6cf0c61d87a2bb1b19c58"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (15 lines \u00D7 2): core_memory/persistence/metrics_ops.py:51-65 | core_memory/persistence/store_metrics_runtime.py:50-64 \u2014 before extracting anything, compare \u0060core_memory/persistence/metrics_ops.py\u0060 and \u0060core_memory/persistence/store_metrics_runtime.py\u0060 as WHOLE FILES: this scan already matched 3 separate duplicated blocks between them, totalling at least 31 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. If that is what happened, the fix is to keep one copy and have the other call it (or delete it), which resolves this row and its siblings together \u2014 extracting one helper per block leaves the fork in place. 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":"core_memory/persistence/metrics_ops.py"},"region":{"startLine":51}}}],"partialFingerprints":{"codehealthFindingId/v1":"f50bb4a5914c49482010433f00e3f76218019a6cf2686fa1cb469aa2f5768745"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2): core_memory/persistence/metrics_ops.py:69-74 | core_memory/persistence/store_metrics_runtime.py:68-73 \u2014 before extracting anything, compare \u0060core_memory/persistence/metrics_ops.py\u0060 and \u0060core_memory/persistence/store_metrics_runtime.py\u0060 as WHOLE FILES: this scan already matched 3 separate duplicated blocks between them, totalling at least 31 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. If that is what happened, the fix is to keep one copy and have the other call it (or delete it), which resolves this row and its siblings together \u2014 extracting one helper per block leaves the fork in place. 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":"core_memory/persistence/metrics_ops.py"},"region":{"startLine":69}}}],"partialFingerprints":{"codehealthFindingId/v1":"1d8044c1b5f9f8ff26cd68701d6d1d2a1664c9f37048c12cd5b95f9c53882950"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 2): core_memory/integrations/neo4j/client.py:237-243 | core_memory/integrations/neo4j/client.py:252-258 \u2014 both copies are in the same file, so extract the block 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":"core_memory/integrations/neo4j/client.py"},"region":{"startLine":237}}}],"partialFingerprints":{"codehealthFindingId/v1":"279ee2619c60f4bf4245761d5c5b268a1967589c4120d6639cfd3347d00625b1"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2): core_memory/integrations/openclaw/agent_end_bridge.py:224-229 | core_memory/integrations/openclaw/hosted_capture_bridge.py:96-101 \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":"core_memory/integrations/openclaw/agent_end_bridge.py"},"region":{"startLine":224}}}],"partialFingerprints":{"codehealthFindingId/v1":"ace2e35d6c5336fba58de9e1dd8d5ad512057dd21defc5775b0df2319b28cd0a"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): core_memory/management/__init__.py:479-483 | core_memory/management/__init__.py:486-490 \u2014 both copies are in the same file, so extract the block 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 \u0060core_memory/management/__init__.py:479\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":"core_memory/management/__init__.py"},"region":{"startLine":479}}}],"partialFingerprints":{"codehealthFindingId/v1":"43515836b30bf6f7768bdec726dfe9b64c36e5ad9783e26bdd6f92f251eae611"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 2): core_memory/persistence/goal_lifecycle_v2.py:101-107 | core_memory/persistence/promotion_service.py:308-314 \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":"core_memory/persistence/goal_lifecycle_v2.py"},"region":{"startLine":101}}}],"partialFingerprints":{"codehealthFindingId/v1":"4a797c1e44160cddbe978b66834715ae5ea39da74946b17e18c6c15697db9d45"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2): core_memory/policy/incidents.py:86-91 | core_memory/policy/incidents.py:108-113 \u2014 both copies are in the same file, so extract the block 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":"core_memory/policy/incidents.py"},"region":{"startLine":86}}}],"partialFingerprints":{"codehealthFindingId/v1":"e3d215840cf67219e8e19d3e14ffe7e0a88bbd6094c4ad1930e343b6f3af6354"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): core_memory/runtime/dreamer/candidates.py:42-46 | core_memory/schema/normalization.py:642-646 \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":"core_memory/runtime/dreamer/candidates.py"},"region":{"startLine":42}}}],"partialFingerprints":{"codehealthFindingId/v1":"4fc831428e2d2cae6d6d2b8d9def2c3d39236038b76b28f4bf160ac13064c523"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): core_memory/runtime/dreamer/eval.py:315-319 | core_memory/runtime/dreamer/longitudinal.py:131-135 \u2014 before extracting anything, compare \u0060core_memory/runtime/dreamer/eval.py\u0060 and \u0060core_memory/runtime/dreamer/longitudinal.py\u0060 as WHOLE FILES: this scan already matched 11 separate duplicated blocks between them, totalling at least 95 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. If that is what happened, the fix is to keep one copy and have the other call it (or delete it), which resolves this row and its siblings together \u2014 extracting one helper per block leaves the fork in place. The \u0060return\u0060 at the foot of the matched lines is the enclosing body\u0027s own terminal exit, not an early one: it moves with them unchanged, and each site calls the extracted unit from the position that \u0060return\u0060 occupied \u2014 no decision has to be handed back and re-acted on."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"core_memory/runtime/dreamer/eval.py"},"region":{"startLine":315}}}],"partialFingerprints":{"codehealthFindingId/v1":"83d02bd463a0ceb03b853963b140d464d5f278a3bc5b2696ac61164564dd5271"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2): core_memory/runtime/dreamer/goal_discovery.py:99-104 | core_memory/soul/identity_value_signals.py:87-92 \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":"core_memory/runtime/dreamer/goal_discovery.py"},"region":{"startLine":99}}}],"partialFingerprints":{"codehealthFindingId/v1":"8fd03620fed88638284f9d4d9ed9f0843c3bb6076ba967422ce146f9def9c5dc"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): core_memory/runtime/turn/reauthoring.py:228-232 | core_memory/runtime/turn/reauthoring.py:249-253 \u2014 both copies are in the same file, so extract the block 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":"core_memory/runtime/turn/reauthoring.py"},"region":{"startLine":228}}}],"partialFingerprints":{"codehealthFindingId/v1":"1529d7b525391b5569bed4e977772ff05bae77c4cc97c3ecf9f79569c527b674"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (23 lines \u00D7 3): examples/claim_layer_demo.py:47-69 | examples/claim_layer_demo.py:86-108 | examples/claim_layer_demo.py:151-173 \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":"examples/claim_layer_demo.py"},"region":{"startLine":47}}}],"partialFingerprints":{"codehealthFindingId/v1":"3b0a2c475d683493884649227d2584c75fe4220d3a1e1fc5f79b7147db0aa6b1"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (15 lines \u00D7 2): demo/app.py:728-749 | demo/app.py:767-781 \u2014 both copies are in the same file, so extract the block 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 \u0060demo/app.py:767\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":"demo/app.py"},"region":{"startLine":728}}}],"partialFingerprints":{"codehealthFindingId/v1":"0bd5cab107aa1caa00bb331dc4dd18b16fc663c87f882a7b39b5ddb695922b75"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (14 lines \u00D7 2): examples/claim_layer_demo.py:71-84 | examples/claim_layer_demo.py:135-148 \u2014 both copies are in the same file, so extract the block into one function there and call it from each site \u2014 the copies drift apart the first time only one of them is edited."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"examples/claim_layer_demo.py"},"region":{"startLine":71}}}],"partialFingerprints":{"codehealthFindingId/v1":"a31a27ba1d180bb8158520c9bfcba42586d3fac74911eda2d7983100fa0db68f"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 2): examples/http_springai_client.py:90-97 | examples/http_springai_client.py:99-105 \u2014 both copies are in the same file, so extract the block into one function there and call it from each site \u2014 the copies drift apart the first time only one of them is edited. Read the line range as the matched WINDOW rather than a finished unit: at \u0060examples/http_springai_client.py:90\u0060 it begins part-way through the construct above it, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"examples/http_springai_client.py"},"region":{"startLine":90}}}],"partialFingerprints":{"codehealthFindingId/v1":"999756beb7c4635e22f47238aac14e44614cd8755a724a13e87b72a937248b58"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: core_memory/runtime/queue/side_effect_queue.py: core_memory/runtime/queue/side_effect_queue.py changed 24 times in last 90 days, max cyclomatic complexity 105 in side_effect_queue.process_side_effect_event at line 117. 2 of those changes were fix/bug commits, and the other 22 changed it for other reasons \u2014 this file is under both repair and feature pressure. Before the next change lands here, make sure the area it touches is under test, then split that area out of the file so the following change is smaller than this one \u2014 a file this often edited pays the complexity back every time. Counted over 2026-05-08..2026-08-06, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-05-08 14:26:39 -05:00\u0027 --until=\u00272026-08-06 14:26:39 -05:00\u0027 --full-history --no-merges -- core_memory/runtime/queue/side_effect_queue.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":"core_memory/runtime/queue/side_effect_queue.py"},"region":{"startLine":117}}}],"partialFingerprints":{"codehealthFindingId/v1":"dbd6bf4dae36715970b5d152b596a4c38c4cf68569f5199400de574594d066de"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: core_memory/retrieval/pipeline/canonical.py: core_memory/retrieval/pipeline/canonical.py changed 16 times in last 90 days, max cyclomatic complexity 150 in canonical.search_request at line 891. 2 of those changes were fix/bug commits, and the other 14 changed it for other reasons \u2014 this file is under both repair and feature pressure. Before the next change lands here, make sure the area it touches is under test, then split that area out of the file so the following change is smaller than this one \u2014 a file this often edited pays the complexity back every time. Counted over 2026-05-08..2026-08-06, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-05-08 14:26:39 -05:00\u0027 --until=\u00272026-08-06 14:26:39 -05:00\u0027 --full-history --no-merges -- core_memory/retrieval/pipeline/canonical.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":"core_memory/retrieval/pipeline/canonical.py"},"region":{"startLine":891}}}],"partialFingerprints":{"codehealthFindingId/v1":"79d1bfba80d2ff5e7cf28e6f29af07b93c4a81ab2a609c0acd737b94e3fa9e33"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: core_memory/runtime/dreamer/candidates.py: core_memory/runtime/dreamer/candidates.py changed 10 times in last 90 days, max cyclomatic complexity 204 in candidates.decide_dreamer_candidate at line 334. 2 of those changes were fix/bug commits, and the other 8 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-05-08..2026-08-06, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-05-08 14:26:39 -05:00\u0027 --until=\u00272026-08-06 14:26:39 -05:00\u0027 --full-history --no-merges -- core_memory/runtime/dreamer/candidates.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":"core_memory/runtime/dreamer/candidates.py"},"region":{"startLine":334}}}],"partialFingerprints":{"codehealthFindingId/v1":"0261d4da51d5dafac3f97ac44caad3f5239588d6c8b9b201aa7656a1f45a9d12"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: core_memory/association/crawler_contract.py: core_memory/association/crawler_contract.py changed 16 times in last 90 days, max cyclomatic complexity 110 in crawler_contract.apply_crawler_updates at line 767. 2 of those changes were fix/bug commits, and the other 14 changed it for other reasons \u2014 this file is under both repair and feature pressure. Before the next change lands here, make sure the area it touches is under test, then split that area out of the file so the following change is smaller than this one \u2014 a file this often edited pays the complexity back every time. Counted over 2026-05-08..2026-08-06, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-05-08 14:26:39 -05:00\u0027 --until=\u00272026-08-06 14:26:39 -05:00\u0027 --full-history --no-merges -- core_memory/association/crawler_contract.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":"core_memory/association/crawler_contract.py"},"region":{"startLine":767}}}],"partialFingerprints":{"codehealthFindingId/v1":"0632393e9ef431de3629315403131c8576aadf7d90cd51b27a6fc9782db9dd90"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: core_memory/management/__init__.py: core_memory/management/__init__.py changed 10 times in last 90 days, max cyclomatic complexity 173 in management.maintain at line 829. 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-05-08..2026-08-06, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-05-08 14:26:39 -05:00\u0027 --until=\u00272026-08-06 14:26:39 -05:00\u0027 --full-history --no-merges -- core_memory/management/__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":"core_memory/management/__init__.py"},"region":{"startLine":829}}}],"partialFingerprints":{"codehealthFindingId/v1":"246f83ce19b3c36f3c09e0d74a6c42fb5faf2036bfa10239105492c8f42e0dcf"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: core_memory/runtime/turn/turn_flow.py: core_memory/runtime/turn/turn_flow.py changed 13 times in last 90 days, max cyclomatic complexity 99 in turn_flow.process_turn_finalized_impl at line 29. 2 of those changes were fix/bug commits, and the other 11 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-05-08..2026-08-06, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-05-08 14:26:39 -05:00\u0027 --until=\u00272026-08-06 14:26:39 -05:00\u0027 --full-history --no-merges -- core_memory/runtime/turn/turn_flow.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":"core_memory/runtime/turn/turn_flow.py"},"region":{"startLine":29}}}],"partialFingerprints":{"codehealthFindingId/v1":"6bb75499127bb3377cb4a8bfb4ad6a0fb2348c4825ae8f69785e6bc6f01eec78"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: core_memory/runtime/associations/coverage.py: core_memory/runtime/associations/coverage.py changed 17 times in last 90 days, max cyclomatic complexity 67 in coverage._apply_judge_result at line 1862. 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-05-08..2026-08-06, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-05-08 14:26:39 -05:00\u0027 --until=\u00272026-08-06 14:26:39 -05:00\u0027 --full-history --no-merges -- core_memory/runtime/associations/coverage.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":"core_memory/runtime/associations/coverage.py"},"region":{"startLine":1862}}}],"partialFingerprints":{"codehealthFindingId/v1":"a31e922d5f3d23dd57c4516c66c34ee110de3788039fc23c46acd9602fa8c0e4"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: core_memory/runtime/engine.py: core_memory/runtime/engine.py changed 27 times in last 90 days, max cyclomatic complexity 39 in engine._resolve_reviewed_updates at line 302. 4 of those changes were fix/bug commits, and the other 23 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-05-08..2026-08-06, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-05-08 14:26:39 -05:00\u0027 --until=\u00272026-08-06 14:26:39 -05:00\u0027 --full-history --no-merges -- core_memory/runtime/engine.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":"core_memory/runtime/engine.py"},"region":{"startLine":302}}}],"partialFingerprints":{"codehealthFindingId/v1":"27b16b32eb39500bba029b94f7aa1e8710c7a33e24899be0b5934edb731bef2d"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: benchmarks/causal_continuity/reporting.py: benchmarks/causal_continuity/reporting.py changed 11 times in last 90 days, max cyclomatic complexity 95 in reporting.build_evidence_manifest 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-05-08..2026-08-06, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-05-08 14:26:39 -05:00\u0027 --until=\u00272026-08-06 14:26:39 -05:00\u0027 --full-history --no-merges -- benchmarks/causal_continuity/reporting.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":"benchmarks/causal_continuity/reporting.py"},"region":{"startLine":93}}}],"partialFingerprints":{"codehealthFindingId/v1":"3127eb543b16a844ddeec52c1bc2d7770740a9df239d1654125aceef7d3cad0f"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: core_memory/retrieval/semantic_index.py: core_memory/retrieval/semantic_index.py changed 12 times in last 90 days, max cyclomatic complexity 85 in semantic_index.semantic_lookup at line 1546. 3 of those changes were fix/bug commits, and the other 9 changed it for other reasons \u2014 this file is under both repair and feature pressure. Before the next change lands here, make sure the area it touches is under test, then split that area out of the file so the following change is smaller than this one \u2014 a file this often edited pays the complexity back every time. Counted over 2026-05-08..2026-08-06, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-05-08 14:26:39 -05:00\u0027 --until=\u00272026-08-06 14:26:39 -05:00\u0027 --full-history --no-merges -- core_memory/retrieval/semantic_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":"core_memory/retrieval/semantic_index.py"},"region":{"startLine":1546}}}],"partialFingerprints":{"codehealthFindingId/v1":"c1ae0c3912b940578d1e2d1e7ecff01483cb2fef69eae77fa48eb78de408242e"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: core_memory/soul/dreamer_bridge.py: core_memory/soul/dreamer_bridge.py changed 14 times in last 90 days, max cyclomatic complexity 68 in dreamer_bridge.propose_soul_from_dreamer at line 536. 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-05-08..2026-08-06, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-05-08 14:26:39 -05:00\u0027 --until=\u00272026-08-06 14:26:39 -05:00\u0027 --full-history --no-merges -- core_memory/soul/dreamer_bridge.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":"core_memory/soul/dreamer_bridge.py"},"region":{"startLine":536}}}],"partialFingerprints":{"codehealthFindingId/v1":"0dfe1b4348ddfbf9cf126fc8af52fc330ee944bdfeaa54aa8b37257aecb679ab"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: core_memory/integrations/http/server.py: core_memory/integrations/http/server.py changed 49 times in last 90 days, max cyclomatic complexity 19 in server.memory_association_candidate_decide at line 2000. 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-05-08..2026-08-06, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-05-08 14:26:39 -05:00\u0027 --until=\u00272026-08-06 14:26:39 -05:00\u0027 --full-history --no-merges -- core_memory/integrations/http/server.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":"core_memory/integrations/http/server.py"},"region":{"startLine":2000}}}],"partialFingerprints":{"codehealthFindingId/v1":"ea87767254e9e7a3e1c059803484d41fffc9370d9eb2b908a7fd2355734979b6"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: core_memory/retrieval/agent.py: core_memory/retrieval/agent.py changed 18 times in last 90 days, max cyclomatic complexity 51 in agent.recall at line 817. 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-05-08..2026-08-06, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-05-08 14:26:39 -05:00\u0027 --until=\u00272026-08-06 14:26:39 -05:00\u0027 --full-history --no-merges -- core_memory/retrieval/agent.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":"core_memory/retrieval/agent.py"},"region":{"startLine":817}}}],"partialFingerprints":{"codehealthFindingId/v1":"ebd7e8218a41e72a5b48d45cb6d4ef5dbfc5d1a42121f95b3d1f06ec6c0e0e0e"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: core_memory/runtime/passes/enrichment.py: core_memory/runtime/passes/enrichment.py changed 10 times in last 90 days, max cyclomatic complexity 91 in enrichment.run_turn_enrichment at line 115. 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-05-08..2026-08-06, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-05-08 14:26:39 -05:00\u0027 --until=\u00272026-08-06 14:26:39 -05:00\u0027 --full-history --no-merges -- core_memory/runtime/passes/enrichment.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":"core_memory/runtime/passes/enrichment.py"},"region":{"startLine":115}}}],"partialFingerprints":{"codehealthFindingId/v1":"9b2723794787c6d7b3d8444ad4fdd24be9928df9ef6f7627b2517de2a71196ff"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: core_memory/persistence/store_add_bead_ops.py: core_memory/persistence/store_add_bead_ops.py changed 25 times in last 90 days, max cyclomatic complexity 34 in store_add_bead_ops.add_bead_for_store at line 33. 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-05-08..2026-08-06, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-05-08 14:26:39 -05:00\u0027 --until=\u00272026-08-06 14:26:39 -05:00\u0027 --full-history --no-merges -- core_memory/persistence/store_add_bead_ops.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":"core_memory/persistence/store_add_bead_ops.py"},"region":{"startLine":33}}}],"partialFingerprints":{"codehealthFindingId/v1":"c170d4bf9f988f578c88fa9ae4d40cde5c6e87615b9832bfd6c5b0948c42a43c"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: core_memory/persistence/store_validation_helpers.py: core_memory/persistence/store_validation_helpers.py changed 6 times in last 90 days, max cyclomatic complexity 127 in store_validation_helpers.required_field_issues_for_store 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-05-08..2026-08-06, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-05-08 14:26:39 -05:00\u0027 --until=\u00272026-08-06 14:26:39 -05:00\u0027 --full-history --no-merges -- core_memory/persistence/store_validation_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":"core_memory/persistence/store_validation_helpers.py"},"region":{"startLine":42}}}],"partialFingerprints":{"codehealthFindingId/v1":"5ac5117b3e1b9d2ca4736f75f292837b1c8cbdbf35e7dd78c3bd731e770d7b4a"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: core_memory/runtime/flush/flush_flow.py: core_memory/runtime/flush/flush_flow.py changed 7 times in last 90 days, max cyclomatic complexity 103 in flush_flow.process_flush_impl 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-05-08..2026-08-06, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-05-08 14:26:39 -05:00\u0027 --until=\u00272026-08-06 14:26:39 -05:00\u0027 --full-history --no-merges -- core_memory/runtime/flush/flush_flow.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":"core_memory/runtime/flush/flush_flow.py"},"region":{"startLine":29}}}],"partialFingerprints":{"codehealthFindingId/v1":"1bf78adec1f3911dd372a413fd9bf13edced733c4d9f275a01eac9acbef80162"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: core_memory/soul/summary.py: core_memory/soul/summary.py changed 8 times in last 90 days, max cyclomatic complexity 78 in summary._build_light_cone at line 603. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-05-08..2026-08-06, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-05-08 14:26:39 -05:00\u0027 --until=\u00272026-08-06 14:26:39 -05:00\u0027 --full-history --no-merges -- core_memory/soul/summary.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":"core_memory/soul/summary.py"},"region":{"startLine":603}}}],"partialFingerprints":{"codehealthFindingId/v1":"c05f8b1fefda1c2f53e7b98428935f0eba72e914625f2e3d541a6badd9c48e66"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: core_memory/schema/models.py: core_memory/schema/models.py changed 12 times in last 90 days, max cyclomatic complexity 46 in models._normalize_bead_payload at line 310. 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-05-08..2026-08-06, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-05-08 14:26:39 -05:00\u0027 --until=\u00272026-08-06 14:26:39 -05:00\u0027 --full-history --no-merges -- core_memory/schema/models.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":"core_memory/schema/models.py"},"region":{"startLine":310}}}],"partialFingerprints":{"codehealthFindingId/v1":"cf19c03b6c206d6ea1b3f6ad6b08434f9b0561add8997f4645157486c74400aa"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: core_memory/transcript_ingest.py: core_memory/transcript_ingest.py changed 8 times in last 90 days, max cyclomatic complexity 65 in transcript_ingest.normalize_transcript_payload at line 192. 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-05-08..2026-08-06, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-05-08 14:26:39 -05:00\u0027 --until=\u00272026-08-06 14:26:39 -05:00\u0027 --full-history --no-merges -- core_memory/transcript_ingest.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":"core_memory/transcript_ingest.py"},"region":{"startLine":192}}}],"partialFingerprints":{"codehealthFindingId/v1":"4fcd7620ac7e93e25d46cbba06a545e42344509048de6ebcebe844ce4ce96bba"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: core_memory/integrations/api.py: core_memory/integrations/api.py changed 8 times in last 90 days, max cyclomatic complexity 60 in api.inspect_state at line 349. 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-05-08..2026-08-06, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-05-08 14:26:39 -05:00\u0027 --until=\u00272026-08-06 14:26:39 -05:00\u0027 --full-history --no-merges -- core_memory/integrations/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":"core_memory/integrations/api.py"},"region":{"startLine":349}}}],"partialFingerprints":{"codehealthFindingId/v1":"3583a70be934c0d742098f537eee1c01a5880bd429f5fc43da43423517ebac64"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: core_memory/retrieval/contracts.py: core_memory/retrieval/contracts.py changed 8 times in last 90 days, max cyclomatic complexity 59 in contracts.recall_result_from_memory_execute at line 306. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-05-08..2026-08-06, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-05-08 14:26:39 -05:00\u0027 --until=\u00272026-08-06 14:26:39 -05:00\u0027 --full-history --no-merges -- core_memory/retrieval/contracts.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":"core_memory/retrieval/contracts.py"},"region":{"startLine":306}}}],"partialFingerprints":{"codehealthFindingId/v1":"eaa36cb739d413fb97f19f779bee28a9883657af62cfbf822c9536fafc245403"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: core_memory/runtime/passes/agent_authored_contract.py: core_memory/runtime/passes/agent_authored_contract.py changed 7 times in last 90 days, max cyclomatic complexity 65 in agent_authored_contract.validate_agent_authored_updates 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-05-08..2026-08-06, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-05-08 14:26:39 -05:00\u0027 --until=\u00272026-08-06 14:26:39 -05:00\u0027 --full-history --no-merges -- core_memory/runtime/passes/agent_authored_contract.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":"core_memory/runtime/passes/agent_authored_contract.py"},"region":{"startLine":93}}}],"partialFingerprints":{"codehealthFindingId/v1":"3955ae44830f7f5b75326af15d2564226d523ea6d67908c93d43af30f9891a77"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: benchmarks/locomo_like/runner.py: benchmarks/locomo_like/runner.py changed 5 times in last 90 days, max cyclomatic complexity 90 in runner._materialize_case 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-05-08..2026-08-06, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-05-08 14:26:39 -05:00\u0027 --until=\u00272026-08-06 14:26:39 -05:00\u0027 --full-history --no-merges -- benchmarks/locomo_like/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":"benchmarks/locomo_like/runner.py"},"region":{"startLine":182}}}],"partialFingerprints":{"codehealthFindingId/v1":"fd3625a1948639c7e2fdd545e38c205b7b0e0b7292cfcd5071deb2760b2d1d8b"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: core_memory/policy/bead_judge.py: core_memory/policy/bead_judge.py changed 19 times in last 90 days, max cyclomatic complexity 23 in bead_judge._normalize_judged_fields at line 371. 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-05-08..2026-08-06, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-05-08 14:26:39 -05:00\u0027 --until=\u00272026-08-06 14:26:39 -05:00\u0027 --full-history --no-merges -- core_memory/policy/bead_judge.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":"core_memory/policy/bead_judge.py"},"region":{"startLine":371}}}],"partialFingerprints":{"codehealthFindingId/v1":"2b5e38be750f17f20764e33f5b987eecbd4e4fa2f0d711a47224bf494791d94e"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: core_memory/runtime/ingest/external_evidence.py: core_memory/runtime/ingest/external_evidence.py changed 13 times in last 90 days, max cyclomatic complexity 31 in external_evidence._find_existing_external_bead at line 242. 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-05-08..2026-08-06, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-05-08 14:26:39 -05:00\u0027 --until=\u00272026-08-06 14:26:39 -05:00\u0027 --full-history --no-merges -- core_memory/runtime/ingest/external_evidence.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":"core_memory/runtime/ingest/external_evidence.py"},"region":{"startLine":242}}}],"partialFingerprints":{"codehealthFindingId/v1":"751f881372efa7b0a0dacac290d872d29b1b3e0e6f658eca571916b029fa7afb"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: core_memory/retrieval/hybrid.py: core_memory/retrieval/hybrid.py changed 6 times in last 90 days, max cyclomatic complexity 66 in hybrid.hybrid_lookup 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-05-08..2026-08-06, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-05-08 14:26:39 -05:00\u0027 --until=\u00272026-08-06 14:26:39 -05:00\u0027 --full-history --no-merges -- core_memory/retrieval/hybrid.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":"core_memory/retrieval/hybrid.py"},"region":{"startLine":101}}}],"partialFingerprints":{"codehealthFindingId/v1":"3018273357d322a97dfe60f6464dcb99dfac7de266b8bdef5c361aafe581af34"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: core_memory/graph/core.py: core_memory/graph/core.py changed 6 times in last 90 days, max cyclomatic complexity 55 in core.backfill_causal_links at line 257. 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-05-08..2026-08-06, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-05-08 14:26:39 -05:00\u0027 --until=\u00272026-08-06 14:26:39 -05:00\u0027 --full-history --no-merges -- core_memory/graph/core.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":"core_memory/graph/core.py"},"region":{"startLine":257}}}],"partialFingerprints":{"codehealthFindingId/v1":"c2512465750ed141bb0adefb61bc4191bc1fd8dce2261621d968be73c626ecad"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: core_memory/runtime/session/session_enrichment_delta.py: core_memory/runtime/session/session_enrichment_delta.py changed 4 times in last 90 days, max cyclomatic complexity 81 in session_enrichment_delta.crawler_updates_to_delta 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-05-08..2026-08-06, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-05-08 14:26:39 -05:00\u0027 --until=\u00272026-08-06 14:26:39 -05:00\u0027 --full-history --no-merges -- core_memory/runtime/session/session_enrichment_delta.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":"core_memory/runtime/session/session_enrichment_delta.py"},"region":{"startLine":422}}}],"partialFingerprints":{"codehealthFindingId/v1":"684885ba13a2a7400e7e8f39b99a81a7093ba8ffcdb0fb4603e5044e1e652450"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: demo/app.py: demo/app.py changed 5 times in last 90 days, max cyclomatic complexity 63 in app.benchmark_run_endpoint at line 1099. 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-05-08..2026-08-06, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-05-08 14:26:39 -05:00\u0027 --until=\u00272026-08-06 14:26:39 -05:00\u0027 --full-history --no-merges -- demo/app.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":"demo/app.py"},"region":{"startLine":1099}}}],"partialFingerprints":{"codehealthFindingId/v1":"d254aafd3144c808cf8f48df888335f1d77188c3411fe1304fcb2680a248dbfa"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: core_memory/cli/__init__.py: core_memory/cli/__init__.py changed 9 times in last 90 days, max cyclomatic complexity 33 in cli.main at line 100. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-05-08..2026-08-06, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-05-08 14:26:39 -05:00\u0027 --until=\u00272026-08-06 14:26:39 -05:00\u0027 --full-history --no-merges -- core_memory/cli/__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":"core_memory/cli/__init__.py"},"region":{"startLine":100}}}],"partialFingerprints":{"codehealthFindingId/v1":"650e21f4d615ca79be8b462c1e66c06f286767db3a2285cff007456c8f76f907"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: benchmarks/causal_continuity/runner.py: benchmarks/causal_continuity/runner.py changed 14 times in last 90 days, max cyclomatic complexity 21 in runner.run_suite at line 48. 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-05-08..2026-08-06, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-05-08 14:26:39 -05:00\u0027 --until=\u00272026-08-06 14:26:39 -05:00\u0027 --full-history --no-merges -- benchmarks/causal_continuity/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":"benchmarks/causal_continuity/runner.py"},"region":{"startLine":48}}}],"partialFingerprints":{"codehealthFindingId/v1":"dfc6d81e6c94b392ab2f012e3772cef4f75e99378ac7b572f0e73efc648310d8"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: core_memory/runtime/observability/myelination.py: core_memory/runtime/observability/myelination.py changed 8 times in last 90 days, max cyclomatic complexity 36 in myelination.compute_myelination_bonus_map 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-05-08..2026-08-06, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-05-08 14:26:39 -05:00\u0027 --until=\u00272026-08-06 14:26:39 -05:00\u0027 --full-history --no-merges -- core_memory/runtime/observability/myelination.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":"core_memory/runtime/observability/myelination.py"},"region":{"startLine":57}}}],"partialFingerprints":{"codehealthFindingId/v1":"085974fcf022e6dc789c7399ec7446dbbaaac9d793025d721b57c83ab89ef30b"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: plugins/openclaw-core-memory-bridge/index.js: plugins/openclaw-core-memory-bridge/index.js changed 7 times in last 90 days, max cyclomatic complexity 37 in register at line 19. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-05-08..2026-08-06, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-05-08 14:26:39 -05:00\u0027 --until=\u00272026-08-06 14:26:39 -05:00\u0027 --full-history --no-merges -- plugins/openclaw-core-memory-bridge/index.js\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"plugins/openclaw-core-memory-bridge/index.js"},"region":{"startLine":19}}}],"partialFingerprints":{"codehealthFindingId/v1":"9ceefe5289b5ec199fcfe2840230b31e9d1446a393ab2a7b9054331459e08204"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: core_memory/graph/root_cause.py: core_memory/graph/root_cause.py changed 6 times in last 90 days, max cyclomatic complexity 38 in root_cause._parameterized_best_first_search at line 554. 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-05-08..2026-08-06, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-05-08 14:26:39 -05:00\u0027 --until=\u00272026-08-06 14:26:39 -05:00\u0027 --full-history --no-merges -- core_memory/graph/root_cause.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":"core_memory/graph/root_cause.py"},"region":{"startLine":554}}}],"partialFingerprints":{"codehealthFindingId/v1":"ad3bf085e09d1902c0ddc369ee8828cecb0324004891b535f739c5ebaaf3b87c"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: core_memory/schema/bead_projection.py: core_memory/schema/bead_projection.py changed 6 times in last 90 days, max cyclomatic complexity 37 in bead_projection.build_retrieval_text at line 79. 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-05-08..2026-08-06, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-05-08 14:26:39 -05:00\u0027 --until=\u00272026-08-06 14:26:39 -05:00\u0027 --full-history --no-merges -- core_memory/schema/bead_projection.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":"core_memory/schema/bead_projection.py"},"region":{"startLine":79}}}],"partialFingerprints":{"codehealthFindingId/v1":"41e84b3c8404a6bc405cfed2c936729734c627812e33dcca95867d8e4a5b6824"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: core_memory/persistence/store_relationship_ops.py: core_memory/persistence/store_relationship_ops.py changed 7 times in last 90 days, max cyclomatic complexity 30 in store_relationship_ops.promote_for_store at line 18. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-05-08..2026-08-06, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-05-08 14:26:39 -05:00\u0027 --until=\u00272026-08-06 14:26:39 -05:00\u0027 --full-history --no-merges -- core_memory/persistence/store_relationship_ops.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":"core_memory/persistence/store_relationship_ops.py"},"region":{"startLine":18}}}],"partialFingerprints":{"codehealthFindingId/v1":"b72eef27327d51afd630a835ced78c6422a6412d07dfa9b792a44d09f4b6c8aa"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: core_memory/runtime/observability/reviewer_quick_value.py: core_memory/runtime/observability/reviewer_quick_value.py changed 5 times in last 90 days, max cyclomatic complexity 42 in reviewer_quick_value.reviewer_quick_value_v2 at line 61. 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-05-08..2026-08-06, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-05-08 14:26:39 -05:00\u0027 --until=\u00272026-08-06 14:26:39 -05:00\u0027 --full-history --no-merges -- core_memory/runtime/observability/reviewer_quick_value.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":"core_memory/runtime/observability/reviewer_quick_value.py"},"region":{"startLine":61}}}],"partialFingerprints":{"codehealthFindingId/v1":"c48d91da99dc91863948ac87f905b9c24a1aa302b0638f9b23b4ab922bfb98da"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: core_memory/persistence/promotion_service.py: core_memory/persistence/promotion_service.py changed 6 times in last 90 days, max cyclomatic complexity 34 in promotion_service.promotion_kpis_for_store at line 528. 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-05-08..2026-08-06, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-05-08 14:26:39 -05:00\u0027 --until=\u00272026-08-06 14:26:39 -05:00\u0027 --full-history --no-merges -- core_memory/persistence/promotion_service.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":"core_memory/persistence/promotion_service.py"},"region":{"startLine":528}}}],"partialFingerprints":{"codehealthFindingId/v1":"268cfec1e7e9869cffedb3a03e3336cbd8e36040db8560b3b8a685984d4f441f"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: core_memory/integrations/mcp/tools/sync_transcript_snapshot.py: core_memory/integrations/mcp/tools/sync_transcript_snapshot.py changed 3 times in last 90 days, max cyclomatic complexity 68 in sync_transcript_snapshot.sync_transcript_snapshot_handler at line 217. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-05-08..2026-08-06, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-05-08 14:26:39 -05:00\u0027 --until=\u00272026-08-06 14:26:39 -05:00\u0027 --full-history --no-merges -- core_memory/integrations/mcp/tools/sync_transcript_snapshot.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":"core_memory/integrations/mcp/tools/sync_transcript_snapshot.py"},"region":{"startLine":217}}}],"partialFingerprints":{"codehealthFindingId/v1":"44346ee16a996aeefa5152eca20478bae573e17af484f3d3095cf9fdbef63093"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: scripts/check_architecture_guards.py: scripts/check_architecture_guards.py changed 7 times in last 90 days, max cyclomatic complexity 26 in check_architecture_guards.main at line 1100. 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-05-08..2026-08-06, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-05-08 14:26:39 -05:00\u0027 --until=\u00272026-08-06 14:26:39 -05:00\u0027 --full-history --no-merges -- scripts/check_architecture_guards.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_architecture_guards.py"},"region":{"startLine":1100}}}],"partialFingerprints":{"codehealthFindingId/v1":"761c619ada791fa06d61f7172fba0559a1c5a969e13fc2d5e66785392b100d85"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: core_memory/soul/store.py: core_memory/soul/store.py changed 8 times in last 90 days, max cyclomatic complexity 21 in store.propose_soul_update 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-05-08..2026-08-06, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-05-08 14:26:39 -05:00\u0027 --until=\u00272026-08-06 14:26:39 -05:00\u0027 --full-history --no-merges -- core_memory/soul/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":"core_memory/soul/store.py"},"region":{"startLine":201}}}],"partialFingerprints":{"codehealthFindingId/v1":"589734fed2a8c434100cc1485de5d4351f971b699c5748ead10b82ea971c25a1"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: core_memory/integrations/mcp/tools/ingest.py: core_memory/integrations/mcp/tools/ingest.py changed 3 times in last 90 days, max cyclomatic complexity 54 in ingest.ingest_handler 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-05-08..2026-08-06, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-05-08 14:26:39 -05:00\u0027 --until=\u00272026-08-06 14:26:39 -05:00\u0027 --full-history --no-merges -- core_memory/integrations/mcp/tools/ingest.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":"core_memory/integrations/mcp/tools/ingest.py"},"region":{"startLine":196}}}],"partialFingerprints":{"codehealthFindingId/v1":"fe3a3148ef58cfa6a61b638193f441cd7a8e73cb75bee1feaf670cc64f9ab424"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: core_memory/runtime/queue/jobs.py: core_memory/runtime/queue/jobs.py changed 8 times in last 90 days, max cyclomatic complexity 20 in jobs.enqueue_async_job at line 192. 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-05-08..2026-08-06, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-05-08 14:26:39 -05:00\u0027 --until=\u00272026-08-06 14:26:39 -05:00\u0027 --full-history --no-merges -- core_memory/runtime/queue/jobs.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":"core_memory/runtime/queue/jobs.py"},"region":{"startLine":192}}}],"partialFingerprints":{"codehealthFindingId/v1":"f2d5d4243ebb954111105602942706708f6285bb70cdd61d35ff64a1f33ca254"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: core_memory/runtime/dreamer/eval.py: core_memory/runtime/dreamer/eval.py changed 4 times in last 90 days, max cyclomatic complexity 40 in eval.dreamer_eval_report at line 261. 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-05-08..2026-08-06, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-05-08 14:26:39 -05:00\u0027 --until=\u00272026-08-06 14:26:39 -05:00\u0027 --full-history --no-merges -- core_memory/runtime/dreamer/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":"core_memory/runtime/dreamer/eval.py"},"region":{"startLine":261}}}],"partialFingerprints":{"codehealthFindingId/v1":"b609a09bc98fecf365a8971ed48510d1df4808a167638d78a1964c3eec775c3e"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: core_memory/retrieval/causal_recall.py: core_memory/retrieval/causal_recall.py changed 6 times in last 90 days, max cyclomatic complexity 26 in causal_recall.build_state_packet at line 247. 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-05-08..2026-08-06, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-05-08 14:26:39 -05:00\u0027 --until=\u00272026-08-06 14:26:39 -05:00\u0027 --full-history --no-merges -- core_memory/retrieval/causal_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":"core_memory/retrieval/causal_recall.py"},"region":{"startLine":247}}}],"partialFingerprints":{"codehealthFindingId/v1":"74541f34d7564509e5547f1aa86f7d7d95be86544c6fdd572b07776b72cdf893"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: core_memory/persistence/events.py: core_memory/persistence/events.py changed 4 times in last 90 days, max cyclomatic complexity 38 in events.rebuild_index at line 163. 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-05-08..2026-08-06, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-05-08 14:26:39 -05:00\u0027 --until=\u00272026-08-06 14:26:39 -05:00\u0027 --full-history --no-merges -- core_memory/persistence/events.py\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"core_memory/persistence/events.py"},"region":{"startLine":163}}}],"partialFingerprints":{"codehealthFindingId/v1":"881d43d10ecd9a45b6f6a6a7f8540791cdd59ab994f6c68e3322c75fbd41245a"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: core_memory/integrations/mcp/typed_write.py: core_memory/integrations/mcp/typed_write.py changed 10 times in last 90 days, max cyclomatic complexity 15 in typed_write.write_turn_finalized at line 184. 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-05-08..2026-08-06, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-05-08 14:26:39 -05:00\u0027 --until=\u00272026-08-06 14:26:39 -05:00\u0027 --full-history --no-merges -- core_memory/integrations/mcp/typed_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":"core_memory/integrations/mcp/typed_write.py"},"region":{"startLine":184}}}],"partialFingerprints":{"codehealthFindingId/v1":"9b1af4a501e0557cf904ee6404c259420bcbe77d30ad888cb54d4c54c163f15b"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: core_memory/runtime/dreamer/analysis.py: core_memory/runtime/dreamer/analysis.py changed 5 times in last 90 days, max cyclomatic complexity 30 in analysis._structural_signal_pack at line 204. 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-05-08..2026-08-06, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-05-08 14:26:39 -05:00\u0027 --until=\u00272026-08-06 14:26:39 -05:00\u0027 --full-history --no-merges -- core_memory/runtime/dreamer/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":"core_memory/runtime/dreamer/analysis.py"},"region":{"startLine":204}}}],"partialFingerprints":{"codehealthFindingId/v1":"f10be43b5083b6ed22af2c4bea894f8b2b790b5595536616bbaaa4455faae4b2"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: benchmarks/causal_continuity/t5.py: benchmarks/causal_continuity/t5.py changed 3 times in last 90 days, max cyclomatic complexity 49 in t5.run_t5_thread_fidelity at line 479. 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-05-08..2026-08-06, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-05-08 14:26:39 -05:00\u0027 --until=\u00272026-08-06 14:26:39 -05:00\u0027 --full-history --no-merges -- benchmarks/causal_continuity/t5.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":"benchmarks/causal_continuity/t5.py"},"region":{"startLine":479}}}],"partialFingerprints":{"codehealthFindingId/v1":"ad9a3d222b6a11d35d8d1fadbbb5cb8529d84f3897595312b0ed9ebe790f113c"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: core_memory/persistence/store_management_ops.py: core_memory/persistence/store_management_ops.py changed 5 times in last 90 days, max cyclomatic complexity 29 in store_management_ops.remove_beads_for_store at line 322. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-05-08..2026-08-06, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-05-08 14:26:39 -05:00\u0027 --until=\u00272026-08-06 14:26:39 -05:00\u0027 --full-history --no-merges -- core_memory/persistence/store_management_ops.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":"core_memory/persistence/store_management_ops.py"},"region":{"startLine":322}}}],"partialFingerprints":{"codehealthFindingId/v1":"61ddd94ab4b2d595b7714ac6f8d9dca4eb1f456f4fd670591aa46584fcc5f4fe"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: core_memory/policy/hygiene.py: core_memory/policy/hygiene.py changed 6 times in last 90 days, max cyclomatic complexity 24 in hygiene.curated_type_title_hygiene at line 45. 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-05-08..2026-08-06, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-05-08 14:26:39 -05:00\u0027 --until=\u00272026-08-06 14:26:39 -05:00\u0027 --full-history --no-merges -- core_memory/policy/hygiene.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":"core_memory/policy/hygiene.py"},"region":{"startLine":45}}}],"partialFingerprints":{"codehealthFindingId/v1":"1d7328cf40755c917333e1e4d64db51721961576edcb3ff7a8ba4e6538dfe1f8"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: core_memory/runtime/turn/turn_prep.py: core_memory/runtime/turn/turn_prep.py changed 4 times in last 90 days, max cyclomatic complexity 35 in turn_prep.normalize_turn_request at line 25. 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-05-08..2026-08-06, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-05-08 14:26:39 -05:00\u0027 --until=\u00272026-08-06 14:26:39 -05:00\u0027 --full-history --no-merges -- core_memory/runtime/turn/turn_prep.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":"core_memory/runtime/turn/turn_prep.py"},"region":{"startLine":25}}}],"partialFingerprints":{"codehealthFindingId/v1":"e2c5b87ebacce7b38da72d9fc565915763b8c8032bf7642fb57946d3ff83b67d"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: core_memory/retrieval/pipeline/__init__.py: core_memory/retrieval/pipeline/__init__.py changed 5 times in last 90 days, max cyclomatic complexity 26 in pipeline._normalize_search_request at line 25. 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-05-08..2026-08-06, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-05-08 14:26:39 -05:00\u0027 --until=\u00272026-08-06 14:26:39 -05:00\u0027 --full-history --no-merges -- core_memory/retrieval/pipeline/__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":"core_memory/retrieval/pipeline/__init__.py"},"region":{"startLine":25}}}],"partialFingerprints":{"codehealthFindingId/v1":"27e70594cd93bdd1a58a622d1b8134785c964976d32c67e22a157fb463c70708"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: core_memory/runtime/session/goal_lifecycle.py: core_memory/runtime/session/goal_lifecycle.py changed 5 times in last 90 days, max cyclomatic complexity 25 in goal_lifecycle.resolve_goals_for_turn at line 51. 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-05-08..2026-08-06, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-05-08 14:26:39 -05:00\u0027 --until=\u00272026-08-06 14:26:39 -05:00\u0027 --full-history --no-merges -- core_memory/runtime/session/goal_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":"core_memory/runtime/session/goal_lifecycle.py"},"region":{"startLine":51}}}],"partialFingerprints":{"codehealthFindingId/v1":"c1c708ccb5036c9008248121e98ce1750964832a4e51c3a27bd265db228dbf14"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: core_memory/integrations/openclaw/agent_end_bridge.py: core_memory/integrations/openclaw/agent_end_bridge.py changed 3 times in last 90 days, max cyclomatic complexity 41 in agent_end_bridge.process_agent_end_event 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-05-08..2026-08-06, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-05-08 14:26:39 -05:00\u0027 --until=\u00272026-08-06 14:26:39 -05:00\u0027 --full-history --no-merges -- core_memory/integrations/openclaw/agent_end_bridge.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":"core_memory/integrations/openclaw/agent_end_bridge.py"},"region":{"startLine":182}}}],"partialFingerprints":{"codehealthFindingId/v1":"0fdeeab8bdb939b076c67a0b0a25d67f8c93c0a94f89d146b87e3456be25aa7f"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: core_memory/cli/compat.py: core_memory/cli/compat.py changed 3 times in last 90 days, max cyclomatic complexity 41 in compat.apply_grouped_aliases at line 63. 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-05-08..2026-08-06, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-05-08 14:26:39 -05:00\u0027 --until=\u00272026-08-06 14:26:39 -05:00\u0027 --full-history --no-merges -- core_memory/cli/compat.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":"core_memory/cli/compat.py"},"region":{"startLine":63}}}],"partialFingerprints":{"codehealthFindingId/v1":"b30e763118485643d4338faff0b6a0678930dd44c5b04cd9d0d60767ab548b74"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: benchmarks/causal_continuity/t1.py: benchmarks/causal_continuity/t1.py changed 4 times in last 90 days, max cyclomatic complexity 30 in t1.run_t1_strategy at line 513. 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-05-08..2026-08-06, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-05-08 14:26:39 -05:00\u0027 --until=\u00272026-08-06 14:26:39 -05:00\u0027 --full-history --no-merges -- benchmarks/causal_continuity/t1.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":"benchmarks/causal_continuity/t1.py"},"region":{"startLine":513}}}],"partialFingerprints":{"codehealthFindingId/v1":"bdd62902d104e170adb1d868cd04b44ad1656113c105e1680fb5cfb7307eb76d"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: core_memory/persistence/goal_lifecycle_v2.py: core_memory/persistence/goal_lifecycle_v2.py changed 4 times in last 90 days, max cyclomatic complexity 29 in goal_lifecycle_v2.transition_goal_state_for_store 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-05-08..2026-08-06, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-05-08 14:26:39 -05:00\u0027 --until=\u00272026-08-06 14:26:39 -05:00\u0027 --full-history --no-merges -- core_memory/persistence/goal_lifecycle_v2.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":"core_memory/persistence/goal_lifecycle_v2.py"},"region":{"startLine":77}}}],"partialFingerprints":{"codehealthFindingId/v1":"a8e8c1c5a33372415e0724a5e7e8b37357261346e583c2dbef8974c0da8041c7"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: core_memory/cli/diagnostics.py: core_memory/cli/diagnostics.py changed 4 times in last 90 days, max cyclomatic complexity 29 in diagnostics.doctor_report 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-05-08..2026-08-06, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-05-08 14:26:39 -05:00\u0027 --until=\u00272026-08-06 14:26:39 -05:00\u0027 --full-history --no-merges -- core_memory/cli/diagnostics.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":"core_memory/cli/diagnostics.py"},"region":{"startLine":71}}}],"partialFingerprints":{"codehealthFindingId/v1":"348959793ce0980a9adbbf91cbf8a3ce051a9a9a9ab3e7e5e5c52f46e47b11fb"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: core_memory/runtime/turn/ingress.py: core_memory/runtime/turn/ingress.py changed 4 times in last 90 days, max cyclomatic complexity 29 in ingress.maybe_emit_finalize_memory_event at line 80. 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-05-08..2026-08-06, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-05-08 14:26:39 -05:00\u0027 --until=\u00272026-08-06 14:26:39 -05:00\u0027 --full-history --no-merges -- core_memory/runtime/turn/ingress.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":"core_memory/runtime/turn/ingress.py"},"region":{"startLine":80}}}],"partialFingerprints":{"codehealthFindingId/v1":"2864375628551edb509510e3e6ec0540d2ff621e8bb33593882ae70867e9d55e"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: benchmarks/causal_continuity/real_data.py: benchmarks/causal_continuity/real_data.py changed 3 times in last 90 days, max cyclomatic complexity 37 in real_data.build_real_data_contrast at line 171. 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-05-08..2026-08-06, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-05-08 14:26:39 -05:00\u0027 --until=\u00272026-08-06 14:26:39 -05:00\u0027 --full-history --no-merges -- benchmarks/causal_continuity/real_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":"benchmarks/causal_continuity/real_data.py"},"region":{"startLine":171}}}],"partialFingerprints":{"codehealthFindingId/v1":"12b78f6ca1e2a00c226a1d810736949cf02944f698240a1b42e0cfc410fe9e1e"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: core_memory/graph/roadmap.py: core_memory/graph/roadmap.py changed 2 times in last 90 days, max cyclomatic complexity 55 in roadmap.roadmap_watershed_attribution 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-05-08..2026-08-06, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-05-08 14:26:39 -05:00\u0027 --until=\u00272026-08-06 14:26:39 -05:00\u0027 --full-history --no-merges -- core_memory/graph/roadmap.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":"core_memory/graph/roadmap.py"},"region":{"startLine":486}}}],"partialFingerprints":{"codehealthFindingId/v1":"08b1f0a586c2d2b31c92ab33046fc3e27acd0342a8ad59bbdab3d9c80c1c65ac"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: core_memory/integrations/recall_payload.py: core_memory/integrations/recall_payload.py changed 4 times in last 90 days, max cyclomatic complexity 27 in recall_payload.run_recall_payload 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-05-08..2026-08-06, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-05-08 14:26:39 -05:00\u0027 --until=\u00272026-08-06 14:26:39 -05:00\u0027 --full-history --no-merges -- core_memory/integrations/recall_payload.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":"core_memory/integrations/recall_payload.py"},"region":{"startLine":59}}}],"partialFingerprints":{"codehealthFindingId/v1":"22aa8d3a283c466b8dfaf7870fc44ca1515dd26ab6e024c407b3594f75889d8b"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: core_memory/runtime/session/session_start_flow.py: core_memory/runtime/session/session_start_flow.py changed 4 times in last 90 days, max cyclomatic complexity 27 in session_start_flow.build_session_start_snapshot at line 31. 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-05-08..2026-08-06, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-05-08 14:26:39 -05:00\u0027 --until=\u00272026-08-06 14:26:39 -05:00\u0027 --full-history --no-merges -- core_memory/runtime/session/session_start_flow.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":"core_memory/runtime/session/session_start_flow.py"},"region":{"startLine":31}}}],"partialFingerprints":{"codehealthFindingId/v1":"89dea77c7af27e7c1cb55bc19ab06c0287d0a4f7918ca962d40e95517462588f"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: core_memory/persistence/store_claim_ops.py: core_memory/persistence/store_claim_ops.py changed 3 times in last 90 days, max cyclomatic complexity 35 in store_claim_ops.resolve_current_state at line 448. 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-05-08..2026-08-06, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-05-08 14:26:39 -05:00\u0027 --until=\u00272026-08-06 14:26:39 -05:00\u0027 --full-history --no-merges -- core_memory/persistence/store_claim_ops.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":"core_memory/persistence/store_claim_ops.py"},"region":{"startLine":448}}}],"partialFingerprints":{"codehealthFindingId/v1":"9723a9e4ab48f8eeacc66eb489f05c508b16aedc2979c270fb8ee3e039395c77"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: core_memory/runtime/state.py: core_memory/runtime/state.py changed 6 times in last 90 days, max cyclomatic complexity 17 in TurnEnvelope.finalize_hashes at line 79. 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-05-08..2026-08-06, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-05-08 14:26:39 -05:00\u0027 --until=\u00272026-08-06 14:26:39 -05:00\u0027 --full-history --no-merges -- core_memory/runtime/state.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":"core_memory/runtime/state.py"},"region":{"startLine":79}}}],"partialFingerprints":{"codehealthFindingId/v1":"c7e9d4e1d7e265b823beb001d3f55081da77ddb4684d2b54bd286d974c3b5556"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: core_memory/runtime/dreamer/research.py: core_memory/runtime/dreamer/research.py changed 3 times in last 90 days, max cyclomatic complexity 34 in research._apply_candidate_refinements at line 243. 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-05-08..2026-08-06, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-05-08 14:26:39 -05:00\u0027 --until=\u00272026-08-06 14:26:39 -05:00\u0027 --full-history --no-merges -- core_memory/runtime/dreamer/research.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":"core_memory/runtime/dreamer/research.py"},"region":{"startLine":243}}}],"partialFingerprints":{"codehealthFindingId/v1":"f60a6b099809d20c01ebf7bd5248c401e0f1943df4fa16ae045f0cf07912aa0e"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: core_memory/persistence/store_compaction_ops.py: core_memory/persistence/store_compaction_ops.py changed 4 times in last 90 days, max cyclomatic complexity 25 in store_compaction_ops.compact_for_store at line 14. 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-05-08..2026-08-06, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-05-08 14:26:39 -05:00\u0027 --until=\u00272026-08-06 14:26:39 -05:00\u0027 --full-history --no-merges -- core_memory/persistence/store_compaction_ops.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":"core_memory/persistence/store_compaction_ops.py"},"region":{"startLine":14}}}],"partialFingerprints":{"codehealthFindingId/v1":"894fce2d19080d606a33a68f37f00cd4e051a7f6849a87083cebfb1d0c0a8154"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: core_memory/integrations/openclaw/onboard.py: core_memory/integrations/openclaw/onboard.py changed 4 times in last 90 days, max cyclomatic complexity 25 in onboard.harden_openclaw_plugin_config at line 39. 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-05-08..2026-08-06, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-05-08 14:26:39 -05:00\u0027 --until=\u00272026-08-06 14:26:39 -05:00\u0027 --full-history --no-merges -- core_memory/integrations/openclaw/onboard.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":"core_memory/integrations/openclaw/onboard.py"},"region":{"startLine":39}}}],"partialFingerprints":{"codehealthFindingId/v1":"35218cc162df66f6249f0e1a797ee40593b4a5b753b2fa6325e2820de236fb62"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: core_memory/claim/update_policy.py: core_memory/claim/update_policy.py changed 4 times in last 90 days, max cyclomatic complexity 24 in update_policy.emit_claim_updates at line 123. 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-05-08..2026-08-06, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-05-08 14:26:39 -05:00\u0027 --until=\u00272026-08-06 14:26:39 -05:00\u0027 --full-history --no-merges -- core_memory/claim/update_policy.py\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"core_memory/claim/update_policy.py"},"region":{"startLine":123}}}],"partialFingerprints":{"codehealthFindingId/v1":"5b68c63f91198860dddf05a5e5b2f8dc9d30533d96a475984c679df9b0797ad8"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: core_memory/runtime/observability/tension_meter.py: core_memory/runtime/observability/tension_meter.py changed 3 times in last 90 days, max cyclomatic complexity 32 in tension_meter.compute_tension_resolution_meter at line 108. 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-05-08..2026-08-06, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-05-08 14:26:39 -05:00\u0027 --until=\u00272026-08-06 14:26:39 -05:00\u0027 --full-history --no-merges -- core_memory/runtime/observability/tension_meter.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":"core_memory/runtime/observability/tension_meter.py"},"region":{"startLine":108}}}],"partialFingerprints":{"codehealthFindingId/v1":"ed9f9d91792b4ab0272fa6b61f120f14b3003a4770494c156b01d36abe7db68d"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: core_memory/retrieval/visible_corpus.py: core_memory/retrieval/visible_corpus.py changed 6 times in last 90 days, max cyclomatic complexity 16 in visible_corpus.build_visible_corpus 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-05-08..2026-08-06, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-05-08 14:26:39 -05:00\u0027 --until=\u00272026-08-06 14:26:39 -05:00\u0027 --full-history --no-merges -- core_memory/retrieval/visible_corpus.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":"core_memory/retrieval/visible_corpus.py"},"region":{"startLine":64}}}],"partialFingerprints":{"codehealthFindingId/v1":"af36d32d4223a5093806910fe308bc671f796ab9f42867ca96676af5e485dfd6"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: core_memory/graph/edge_weights.py: core_memory/graph/edge_weights.py changed 5 times in last 90 days, max cyclomatic complexity 18 in edge_weights.normalize_backend_chain at line 149. 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-05-08..2026-08-06, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-05-08 14:26:39 -05:00\u0027 --until=\u00272026-08-06 14:26:39 -05:00\u0027 --full-history --no-merges -- core_memory/graph/edge_weights.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":"core_memory/graph/edge_weights.py"},"region":{"startLine":149}}}],"partialFingerprints":{"codehealthFindingId/v1":"48795db79852bf8f78e0bfca71db7aa96eca2b2f85078ff15925345a172860ce"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: core_memory/cli/handlers/migrate.py: core_memory/cli/handlers/migrate.py changed 4 times in last 90 days, max cyclomatic complexity 22 in migrate.handle_migrate at line 68. 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-05-08..2026-08-06, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-05-08 14:26:39 -05:00\u0027 --until=\u00272026-08-06 14:26:39 -05:00\u0027 --full-history --no-merges -- core_memory/cli/handlers/migrate.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":"core_memory/cli/handlers/migrate.py"},"region":{"startLine":68}}}],"partialFingerprints":{"codehealthFindingId/v1":"85eb23c3573ea8dec05a421f93ce8cf3fdff846a5a03fea9fca4a594fad26bdf"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: core_memory/persistence/store_add_helpers.py: core_memory/persistence/store_add_helpers.py changed 3 times in last 90 days, max cyclomatic complexity 29 in store_add_helpers.find_recent_duplicate_bead_id_for_store at line 121. 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-05-08..2026-08-06, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-05-08 14:26:39 -05:00\u0027 --until=\u00272026-08-06 14:26:39 -05:00\u0027 --full-history --no-merges -- core_memory/persistence/store_add_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":"core_memory/persistence/store_add_helpers.py"},"region":{"startLine":121}}}],"partialFingerprints":{"codehealthFindingId/v1":"5fcc28be0c2c3b5c77994d750914b19aa0994c3e43c44e3ee901a937f797d3fe"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: core_memory/cli/handlers/memory.py: core_memory/cli/handlers/memory.py changed 3 times in last 90 days, max cyclomatic complexity 29 in memory.handle_memory_command at line 8. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-05-08..2026-08-06, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-05-08 14:26:39 -05:00\u0027 --until=\u00272026-08-06 14:26:39 -05:00\u0027 --full-history --no-merges -- core_memory/cli/handlers/memory.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":"core_memory/cli/handlers/memory.py"},"region":{"startLine":8}}}],"partialFingerprints":{"codehealthFindingId/v1":"48f4e3c96301bd0e6127ebb6358f6736aaa577a5f8ba934cdbef3c01bcdef5c0"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: core_memory/policy/semantic_task_runtime.py: core_memory/policy/semantic_task_runtime.py changed 5 times in last 90 days, max cyclomatic complexity 17 in ProviderSemanticTaskRuntime.run at line 254. 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-05-08..2026-08-06, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-05-08 14:26:39 -05:00\u0027 --until=\u00272026-08-06 14:26:39 -05:00\u0027 --full-history --no-merges -- core_memory/policy/semantic_task_runtime.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":"core_memory/policy/semantic_task_runtime.py"},"region":{"startLine":254}}}],"partialFingerprints":{"codehealthFindingId/v1":"0344dd41a6a94ffae66a78dfc76da91496d76ed961080945d6787d9befc08579"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: core_memory/policy/turn_memory_authoring.py: core_memory/policy/turn_memory_authoring.py changed 5 times in last 90 days, max cyclomatic complexity 17 in turn_memory_authoring._value_at_path 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-05-08..2026-08-06, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-05-08 14:26:39 -05:00\u0027 --until=\u00272026-08-06 14:26:39 -05:00\u0027 --full-history --no-merges -- core_memory/policy/turn_memory_authoring.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":"core_memory/policy/turn_memory_authoring.py"},"region":{"startLine":215}}}],"partialFingerprints":{"codehealthFindingId/v1":"6ff5112d23d03e5047e259ca7ded2720a65adf2ea4989c0cd35d66424237b58b"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: core_memory/cli/handlers/graph.py: core_memory/cli/handlers/graph.py changed 2 times in last 90 days, max cyclomatic complexity 42 in graph.handle_graph_command 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-05-08..2026-08-06, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-05-08 14:26:39 -05:00\u0027 --until=\u00272026-08-06 14:26:39 -05:00\u0027 --full-history --no-merges -- core_memory/cli/handlers/graph.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":"core_memory/cli/handlers/graph.py"},"region":{"startLine":20}}}],"partialFingerprints":{"codehealthFindingId/v1":"5b53900632c41c0543c886f96168f56302cb665c44e536be73fe6ec49be3bcd8"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: core_memory/runtime/passes/agent_crawler_invoke.py: core_memory/runtime/passes/agent_crawler_invoke.py changed 3 times in last 90 days, max cyclomatic complexity 27 in agent_crawler_invoke.invoke_turn_crawler_agent 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-05-08..2026-08-06, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-05-08 14:26:39 -05:00\u0027 --until=\u00272026-08-06 14:26:39 -05:00\u0027 --full-history --no-merges -- core_memory/runtime/passes/agent_crawler_invoke.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":"core_memory/runtime/passes/agent_crawler_invoke.py"},"region":{"startLine":20}}}],"partialFingerprints":{"codehealthFindingId/v1":"d0265e6b005ce98611865e1c9d1f2a3aad066493f1924272b111eceac733f62c"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: core_memory/llm_client.py: core_memory/llm_client.py changed 3 times in last 90 days, max cyclomatic complexity 27 in llm_client.chat_complete at line 27. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-05-08..2026-08-06, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-05-08 14:26:39 -05:00\u0027 --until=\u00272026-08-06 14:26:39 -05:00\u0027 --full-history --no-merges -- core_memory/llm_client.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":"core_memory/llm_client.py"},"region":{"startLine":27}}}],"partialFingerprints":{"codehealthFindingId/v1":"50851d739f1a246ad8eef99fcc0d2f3d2adad62cd68bae7de21b4ce116970b9d"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: core_memory/runtime/turn/receipt.py: core_memory/runtime/turn/receipt.py changed 2 times in last 90 days, max cyclomatic complexity 39 in receipt.build_turn_finalized_receipt at line 129. 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-05-08..2026-08-06, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-05-08 14:26:39 -05:00\u0027 --until=\u00272026-08-06 14:26:39 -05:00\u0027 --full-history --no-merges -- core_memory/runtime/turn/receipt.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":"core_memory/runtime/turn/receipt.py"},"region":{"startLine":129}}}],"partialFingerprints":{"codehealthFindingId/v1":"38591efb3eda8f8c15c3dbe335aefaa8814c12e18958ef39ebc396feccad5bb8"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: core_memory/policy/association_inference_v21.py: core_memory/policy/association_inference_v21.py changed 3 times in last 90 days, max cyclomatic complexity 26 in association_inference_v21.validate_and_normalize_inference_payload at line 129. 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-05-08..2026-08-06, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-05-08 14:26:39 -05:00\u0027 --until=\u00272026-08-06 14:26:39 -05:00\u0027 --full-history --no-merges -- core_memory/policy/association_inference_v21.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":"core_memory/policy/association_inference_v21.py"},"region":{"startLine":129}}}],"partialFingerprints":{"codehealthFindingId/v1":"68afe475881fdc847e76737c36349c60860651506a5826b36519aa3364357f42"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: benchmarks/causal_continuity/reproducibility.py: benchmarks/causal_continuity/reproducibility.py changed 3 times in last 90 days, max cyclomatic complexity 25 in reproducibility._t5_ordered_outputs at line 38. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-05-08..2026-08-06, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-05-08 14:26:39 -05:00\u0027 --until=\u00272026-08-06 14:26:39 -05:00\u0027 --full-history --no-merges -- benchmarks/causal_continuity/reproducibility.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":"benchmarks/causal_continuity/reproducibility.py"},"region":{"startLine":38}}}],"partialFingerprints":{"codehealthFindingId/v1":"2121973d10c6bc34743762020bf1c5a59f085e94fcb78ba97855a5c868ed7950"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: core_memory/graph/traversal.py: core_memory/graph/traversal.py changed 2 times in last 90 days, max cyclomatic complexity 37 in traversal._build_adjacency 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-05-08..2026-08-06, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-05-08 14:26:39 -05:00\u0027 --until=\u00272026-08-06 14:26:39 -05:00\u0027 --full-history --no-merges -- core_memory/graph/traversal.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":"core_memory/graph/traversal.py"},"region":{"startLine":37}}}],"partialFingerprints":{"codehealthFindingId/v1":"5948bd752b6cc2089da13a8f36102fe96534ba6dc1096614d6f9f8f3b0ee72d5"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: core_memory/schema/agent_authored_updates.py: core_memory/schema/agent_authored_updates.py changed 2 times in last 90 days, max cyclomatic complexity 36 in agent_authored_updates._validate_json_value at line 506. 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-05-08..2026-08-06, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-05-08 14:26:39 -05:00\u0027 --until=\u00272026-08-06 14:26:39 -05:00\u0027 --full-history --no-merges -- core_memory/schema/agent_authored_updates.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":"core_memory/schema/agent_authored_updates.py"},"region":{"startLine":506}}}],"partialFingerprints":{"codehealthFindingId/v1":"025f6a56fad76e60ed759ce33cecdc258a6e670b16ceef4ec5ea9f9ce25ff225"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: core_memory/integrations/mcp/tools/ingest_discord.py: core_memory/integrations/mcp/tools/ingest_discord.py changed 2 times in last 90 days, max cyclomatic complexity 35 in ingest_discord.ingest_discord_handler at line 79. 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-05-08..2026-08-06, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-05-08 14:26:39 -05:00\u0027 --until=\u00272026-08-06 14:26:39 -05:00\u0027 --full-history --no-merges -- core_memory/integrations/mcp/tools/ingest_discord.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":"core_memory/integrations/mcp/tools/ingest_discord.py"},"region":{"startLine":79}}}],"partialFingerprints":{"codehealthFindingId/v1":"5e834bcdfbcec443fe7263a774d8d89f457848c2f0874294540e387afc58a20e"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: core_memory/integrations/pydanticai/memory_tools.py: core_memory/integrations/pydanticai/memory_tools.py changed 4 times in last 90 days, max cyclomatic complexity 17 in memory_tools.continuity_prompt 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-05-08..2026-08-06, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-05-08 14:26:39 -05:00\u0027 --until=\u00272026-08-06 14:26:39 -05:00\u0027 --full-history --no-merges -- core_memory/integrations/pydanticai/memory_tools.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":"core_memory/integrations/pydanticai/memory_tools.py"},"region":{"startLine":102}}}],"partialFingerprints":{"codehealthFindingId/v1":"6faed1d64baa3be99fef3e9dea0dcee7255cf5a1feef0b68a6ee0237907247c7"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: core_memory/cli/handlers/store.py: core_memory/cli/handlers/store.py changed 2 times in last 90 days, max cyclomatic complexity 31 in store.handle_store_commands at line 14. 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-05-08..2026-08-06, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-05-08 14:26:39 -05:00\u0027 --until=\u00272026-08-06 14:26:39 -05:00\u0027 --full-history --no-merges -- core_memory/cli/handlers/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":"core_memory/cli/handlers/store.py"},"region":{"startLine":14}}}],"partialFingerprints":{"codehealthFindingId/v1":"066b2af2a65ed1a63655abbe22fc46aef5848465b56fb3791e22f4f4d04152d5"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: core_memory/cli/handlers/setup.py: core_memory/cli/handlers/setup.py changed 4 times in last 90 days, max cyclomatic complexity 15 in setup.config_validate_command at line 811. 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-05-08..2026-08-06, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-05-08 14:26:39 -05:00\u0027 --until=\u00272026-08-06 14:26:39 -05:00\u0027 --full-history --no-merges -- core_memory/cli/handlers/setup.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":"core_memory/cli/handlers/setup.py"},"region":{"startLine":811}}}],"partialFingerprints":{"codehealthFindingId/v1":"91da82d96dc26b4e60124b5c527dd898c31e3dfecdffc02ad2d006b047c9b78c"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: benchmarks/causal_continuity/t3.py: benchmarks/causal_continuity/t3.py changed 2 times in last 90 days, max cyclomatic complexity 30 in t3._materialize_case at line 38. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-05-08..2026-08-06, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-05-08 14:26:39 -05:00\u0027 --until=\u00272026-08-06 14:26:39 -05:00\u0027 --full-history --no-merges -- benchmarks/causal_continuity/t3.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":"benchmarks/causal_continuity/t3.py"},"region":{"startLine":38}}}],"partialFingerprints":{"codehealthFindingId/v1":"b3f06e50b254d3c268fa31a900a850d7dc226668d7f05ecdd33f170b784a4685"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: core_memory/runtime/dreamer/geometry.py: core_memory/runtime/dreamer/geometry.py changed 2 times in last 90 days, max cyclomatic complexity 30 in geometry.build_geometry_manifest at line 68. 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-05-08..2026-08-06, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-05-08 14:26:39 -05:00\u0027 --until=\u00272026-08-06 14:26:39 -05:00\u0027 --full-history --no-merges -- core_memory/runtime/dreamer/geometry.py\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"core_memory/runtime/dreamer/geometry.py"},"region":{"startLine":68}}}],"partialFingerprints":{"codehealthFindingId/v1":"a4fd43fc78be825006e0b6865754252c812864b4a97a916f128bd58f7f27eda5"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: core_memory/graph/storylines.py: core_memory/graph/storylines.py changed 2 times in last 90 days, max cyclomatic complexity 29 in storylines.derive_storylines at line 66. 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-05-08..2026-08-06, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-05-08 14:26:39 -05:00\u0027 --until=\u00272026-08-06 14:26:39 -05:00\u0027 --full-history --no-merges -- core_memory/graph/storylines.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":"core_memory/graph/storylines.py"},"region":{"startLine":66}}}],"partialFingerprints":{"codehealthFindingId/v1":"695d96a4765a72e133bfc41ee11e61e0b91f94e567bccc4508059c245a5ce67a"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: core_memory/runtime/turn/semantic_state.py: core_memory/runtime/turn/semantic_state.py changed 2 times in last 90 days, max cyclomatic complexity 28 in semantic_state.mark_semantic_write_state at line 85. 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-05-08..2026-08-06, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-05-08 14:26:39 -05:00\u0027 --until=\u00272026-08-06 14:26:39 -05:00\u0027 --full-history --no-merges -- core_memory/runtime/turn/semantic_state.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":"core_memory/runtime/turn/semantic_state.py"},"region":{"startLine":85}}}],"partialFingerprints":{"codehealthFindingId/v1":"447bbe89c13ff6aee9d5095e774fdad5d5cc7cb2939d711ecd35aaac14d8db15"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: core_memory/persistence/myelination_rewards.py: core_memory/persistence/myelination_rewards.py changed 2 times in last 90 days, max cyclomatic complexity 28 in myelination_rewards.emit_myelination_reward_event at line 236. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-05-08..2026-08-06, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-05-08 14:26:39 -05:00\u0027 --until=\u00272026-08-06 14:26:39 -05:00\u0027 --full-history --no-merges -- core_memory/persistence/myelination_rewards.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":"core_memory/persistence/myelination_rewards.py"},"region":{"startLine":236}}}],"partialFingerprints":{"codehealthFindingId/v1":"3e5fa8c36022cb20a95de9b619a8c2bf41ddb96c7b1d0ade1982ceefff8c7fe0"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: core_memory/runtime/hygiene/seed_backfill.py: core_memory/runtime/hygiene/seed_backfill.py changed 3 times in last 90 days, max cyclomatic complexity 18 in seed_backfill.run_seed_quality_backfill at line 96. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-05-08..2026-08-06, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-05-08 14:26:39 -05:00\u0027 --until=\u00272026-08-06 14:26:39 -05:00\u0027 --full-history --no-merges -- core_memory/runtime/hygiene/seed_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":"core_memory/runtime/hygiene/seed_backfill.py"},"region":{"startLine":96}}}],"partialFingerprints":{"codehealthFindingId/v1":"d890179fbdd50794baa6cf7118310e592376ffda2322cef35ca847b8c8a6d282"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: core_memory/runtime/dreamer/identity_value_research.py: core_memory/runtime/dreamer/identity_value_research.py changed 2 times in last 90 days, max cyclomatic complexity 27 in identity_value_research.enqueue_identity_value_candidates at line 38. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-05-08..2026-08-06, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-05-08 14:26:39 -05:00\u0027 --until=\u00272026-08-06 14:26:39 -05:00\u0027 --full-history --no-merges -- core_memory/runtime/dreamer/identity_value_research.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":"core_memory/runtime/dreamer/identity_value_research.py"},"region":{"startLine":38}}}],"partialFingerprints":{"codehealthFindingId/v1":"b8e07aead56a16f82b67f73f82492a64114b96823d3a22aebe85f1f49ef7878e"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: core_memory/integrations/openclaw/hosted_capture_bridge.py: core_memory/integrations/openclaw/hosted_capture_bridge.py changed 2 times in last 90 days, max cyclomatic complexity 26 in hosted_capture_bridge.process_hosted_capture_event at line 186. 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-05-08..2026-08-06, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-05-08 14:26:39 -05:00\u0027 --until=\u00272026-08-06 14:26:39 -05:00\u0027 --full-history --no-merges -- core_memory/integrations/openclaw/hosted_capture_bridge.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":"core_memory/integrations/openclaw/hosted_capture_bridge.py"},"region":{"startLine":186}}}],"partialFingerprints":{"codehealthFindingId/v1":"23ea54403e5f9cb4b714faa535af1e7bc6501e85d62ef0048a52ded5a126cc77"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: core_memory/graph/worldlines.py: core_memory/graph/worldlines.py changed 2 times in last 90 days, max cyclomatic complexity 26 in worldlines._goal_worldlines at line 161. 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-05-08..2026-08-06, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-05-08 14:26:39 -05:00\u0027 --until=\u00272026-08-06 14:26:39 -05:00\u0027 --full-history --no-merges -- core_memory/graph/worldlines.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":"core_memory/graph/worldlines.py"},"region":{"startLine":161}}}],"partialFingerprints":{"codehealthFindingId/v1":"d8e5fd6891995a90c2b740f0442a9a0dcc78746c4eebf5479f5cee6edba2dfc2"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: core_memory/runtime/ingest/source_envelope.py: core_memory/runtime/ingest/source_envelope.py changed 3 times in last 90 days, max cyclomatic complexity 17 in source_envelope.normalize_source_ingest_envelope at line 111. 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-05-08..2026-08-06, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-05-08 14:26:39 -05:00\u0027 --until=\u00272026-08-06 14:26:39 -05:00\u0027 --full-history --no-merges -- core_memory/runtime/ingest/source_envelope.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":"core_memory/runtime/ingest/source_envelope.py"},"region":{"startLine":111}}}],"partialFingerprints":{"codehealthFindingId/v1":"6235c772a06aee0210abc57d948f801ef329b0ca9504e15a3ecf82c35b08991a"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: core_memory/persistence/store_failure_ops.py: core_memory/persistence/store_failure_ops.py changed 3 times in last 90 days, max cyclomatic complexity 17 in store_failure_ops.find_failure_signature_matches_for_store at line 16. 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-05-08..2026-08-06, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-05-08 14:26:39 -05:00\u0027 --until=\u00272026-08-06 14:26:39 -05:00\u0027 --full-history --no-merges -- core_memory/persistence/store_failure_ops.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":"core_memory/persistence/store_failure_ops.py"},"region":{"startLine":16}}}],"partialFingerprints":{"codehealthFindingId/v1":"9e8a8683ae4a797797e15587c40a3c79d48998f516026721223830d8028b0b34"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: core_memory/association/slo.py: core_memory/association/slo.py changed 2 times in last 90 days, max cyclomatic complexity 25 in slo.association_slo_report at line 65. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-05-08..2026-08-06, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-05-08 14:26:39 -05:00\u0027 --until=\u00272026-08-06 14:26:39 -05:00\u0027 --full-history --no-merges -- core_memory/association/slo.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":"core_memory/association/slo.py"},"region":{"startLine":65}}}],"partialFingerprints":{"codehealthFindingId/v1":"3b1b3992226e40b909a7c525767184b13343d5534db291dca789384d8799ad91"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: core_memory/association/preview.py: core_memory/association/preview.py changed 3 times in last 90 days, max cyclomatic complexity 16 in preview.compute_preview_association_candidates 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-05-08..2026-08-06, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-05-08 14:26:39 -05:00\u0027 --until=\u00272026-08-06 14:26:39 -05:00\u0027 --full-history --no-merges -- core_memory/association/preview.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":"core_memory/association/preview.py"},"region":{"startLine":138}}}],"partialFingerprints":{"codehealthFindingId/v1":"8a98fb3a00bcc2007738385100710d522dfda22bc7e3b105c13e9f7de2f918a0"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: core_memory/retrieval/rerank.py: core_memory/retrieval/rerank.py changed 2 times in last 90 days, max cyclomatic complexity 24 in rerank._load_structural_adjacency at line 113. 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-05-08..2026-08-06, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-05-08 14:26:39 -05:00\u0027 --until=\u00272026-08-06 14:26:39 -05:00\u0027 --full-history --no-merges -- core_memory/retrieval/rerank.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":"core_memory/retrieval/rerank.py"},"region":{"startLine":113}}}],"partialFingerprints":{"codehealthFindingId/v1":"c2b21f9268bef864bea6134db2311994f4ad91fd5a1a942cfee1d75b52f593df"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: benchmarks/locomo/ingest.py: benchmarks/locomo/ingest.py changed 2 times in last 90 days, max cyclomatic complexity 24 in ingest.ingest_conversation at line 127. 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-05-08..2026-08-06, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-05-08 14:26:39 -05:00\u0027 --until=\u00272026-08-06 14:26:39 -05:00\u0027 --full-history --no-merges -- benchmarks/locomo/ingest.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":"benchmarks/locomo/ingest.py"},"region":{"startLine":127}}}],"partialFingerprints":{"codehealthFindingId/v1":"73023e56e85c3291fe62a08a575b82c5973e23882fd62b2296783e276db2e724"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: core_memory/integrations/remote/semantic_tasks.py: core_memory/integrations/remote/semantic_tasks.py changed 2 times in last 90 days, max cyclomatic complexity 22 in semantic_tasks._result_from_payload at line 137. 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-05-08..2026-08-06, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-05-08 14:26:39 -05:00\u0027 --until=\u00272026-08-06 14:26:39 -05:00\u0027 --full-history --no-merges -- core_memory/integrations/remote/semantic_tasks.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":"core_memory/integrations/remote/semantic_tasks.py"},"region":{"startLine":137}}}],"partialFingerprints":{"codehealthFindingId/v1":"b4b6272ed05d97620336b550d0ad140fd62b08580a9725917abb179c5789a573"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: core_memory/runtime/ingest/chunk_turns.py: core_memory/runtime/ingest/chunk_turns.py changed 2 times in last 90 days, max cyclomatic complexity 21 in chunk_turns.list_chunk_turns 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-05-08..2026-08-06, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-05-08 14:26:39 -05:00\u0027 --until=\u00272026-08-06 14:26:39 -05:00\u0027 --full-history --no-merges -- core_memory/runtime/ingest/chunk_turns.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":"core_memory/runtime/ingest/chunk_turns.py"},"region":{"startLine":263}}}],"partialFingerprints":{"codehealthFindingId/v1":"0152e545bad02a43210c25331336289abf036b65ee222fe1286849291d315e04"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: core_memory/soul/injection.py: core_memory/soul/injection.py changed 2 times in last 90 days, max cyclomatic complexity 20 in injection.soul_injection at line 30. 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-05-08..2026-08-06, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-05-08 14:26:39 -05:00\u0027 --until=\u00272026-08-06 14:26:39 -05:00\u0027 --full-history --no-merges -- core_memory/soul/injection.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":"core_memory/soul/injection.py"},"region":{"startLine":30}}}],"partialFingerprints":{"codehealthFindingId/v1":"3ffe9b4ff852e05c759ecc1d9e52a91454b9c6623fe2474e2551f19b5fa003d9"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: core_memory/retrieval/adapters/pipehouse_adapter.py: core_memory/retrieval/adapters/pipehouse_adapter.py changed 2 times in last 90 days, max cyclomatic complexity 20 in pipehouse_adapter.retrieve at line 30. 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-05-08..2026-08-06, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-05-08 14:26:39 -05:00\u0027 --until=\u00272026-08-06 14:26:39 -05:00\u0027 --full-history --no-merges -- core_memory/retrieval/adapters/pipehouse_adapter.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":"core_memory/retrieval/adapters/pipehouse_adapter.py"},"region":{"startLine":30}}}],"partialFingerprints":{"codehealthFindingId/v1":"3608934df0db1b6b0dddd39dbf867cc848fa7e185e8f5e39a324015b722e88f5"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: core_memory/schema/storyline_overlay.py: core_memory/schema/storyline_overlay.py changed 2 times in last 90 days, max cyclomatic complexity 19 in storyline_overlay.validate_storyline_overlay at line 40. 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-05-08..2026-08-06, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-05-08 14:26:39 -05:00\u0027 --until=\u00272026-08-06 14:26:39 -05:00\u0027 --full-history --no-merges -- core_memory/schema/storyline_overlay.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":"core_memory/schema/storyline_overlay.py"},"region":{"startLine":40}}}],"partialFingerprints":{"codehealthFindingId/v1":"56259a5ffa74f4712f35814aac8465fe6fa4fca542cf21165c74d9a19d5bad43"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: benchmarks/causal_continuity/ablations.py: benchmarks/causal_continuity/ablations.py changed 2 times in last 90 days, max cyclomatic complexity 19 in ablations.build_ablation_matrix at line 76. 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-05-08..2026-08-06, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-05-08 14:26:39 -05:00\u0027 --until=\u00272026-08-06 14:26:39 -05:00\u0027 --full-history --no-merges -- benchmarks/causal_continuity/ablations.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":"benchmarks/causal_continuity/ablations.py"},"region":{"startLine":76}}}],"partialFingerprints":{"codehealthFindingId/v1":"4d164595e1d3e2cd8816bc8f1677440cc97513f9ab48d291b2c78cd11c6ba81e"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: core_memory/integrations/langchain/retriever.py: core_memory/integrations/langchain/retriever.py changed 2 times in last 90 days, max cyclomatic complexity 19 in CoreMemoryRetriever._get_relevant_documents at line 67. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-05-08..2026-08-06, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-05-08 14:26:39 -05:00\u0027 --until=\u00272026-08-06 14:26:39 -05:00\u0027 --full-history --no-merges -- core_memory/integrations/langchain/retriever.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":"core_memory/integrations/langchain/retriever.py"},"region":{"startLine":67}}}],"partialFingerprints":{"codehealthFindingId/v1":"b39838e4b9d9704cbcb8b774ce16e85f67ea130166d23778017f70942d66d758"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: core_memory/integrations/neo4j/mapper.py: core_memory/integrations/neo4j/mapper.py changed 2 times in last 90 days, max cyclomatic complexity 19 in mapper.bead_to_node at line 23. 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-05-08..2026-08-06, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-05-08 14:26:39 -05:00\u0027 --until=\u00272026-08-06 14:26:39 -05:00\u0027 --full-history --no-merges -- core_memory/integrations/neo4j/mapper.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":"core_memory/integrations/neo4j/mapper.py"},"region":{"startLine":23}}}],"partialFingerprints":{"codehealthFindingId/v1":"ba70a7a2bd8e1d6e06a98077f0e0cbd67b5159622846f61b57d9e2d8a0f3cb8a"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: core_memory/integrations/mcp/tools/capture.py: core_memory/integrations/mcp/tools/capture.py changed 2 times in last 90 days, max cyclomatic complexity 18 in capture.capture_handler at line 35. 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-05-08..2026-08-06, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-05-08 14:26:39 -05:00\u0027 --until=\u00272026-08-06 14:26:39 -05:00\u0027 --full-history --no-merges -- core_memory/integrations/mcp/tools/capture.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":"core_memory/integrations/mcp/tools/capture.py"},"region":{"startLine":35}}}],"partialFingerprints":{"codehealthFindingId/v1":"36fde894e2fb14e2664cc4d7f9f92657e884a1a97975da36a0dcee29893204b4"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: core_memory/runtime/turn/turn_quality.py: core_memory/runtime/turn/turn_quality.py changed 2 times in last 90 days, max cyclomatic complexity 18 in turn_quality.emit_agent_turn_quality_metric 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-05-08..2026-08-06, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-05-08 14:26:39 -05:00\u0027 --until=\u00272026-08-06 14:26:39 -05:00\u0027 --full-history --no-merges -- core_memory/runtime/turn/turn_quality.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":"core_memory/runtime/turn/turn_quality.py"},"region":{"startLine":34}}}],"partialFingerprints":{"codehealthFindingId/v1":"d401167e8b1dfa650522550e1ed82080fa9770374e650a1dd4420300c80b7c1c"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: core_memory/write_pipeline/rolling_window.py: core_memory/write_pipeline/rolling_window.py changed 2 times in last 90 days, max cyclomatic complexity 17 in rolling_window._select_beads_for_budget 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-05-08..2026-08-06, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-05-08 14:26:39 -05:00\u0027 --until=\u00272026-08-06 14:26:39 -05:00\u0027 --full-history --no-merges -- core_memory/write_pipeline/rolling_window.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":"core_memory/write_pipeline/rolling_window.py"},"region":{"startLine":188}}}],"partialFingerprints":{"codehealthFindingId/v1":"81447a7e9d442bb5d6c525de3c35b898fe2325f2634a4f82b5a3fd9a454b751c"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: core_memory/persistence/store_query.py: core_memory/persistence/store_query.py changed 2 times in last 90 days, max cyclomatic complexity 17 in store_query.query_for_store at line 8. Frequent change and high complexity in one file compound: schedule the next change to it to include carving out the part being edited, with the area under test before it moves. Counted over 2026-05-08..2026-08-06, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-05-08 14:26:39 -05:00\u0027 --until=\u00272026-08-06 14:26:39 -05:00\u0027 --full-history --no-merges -- core_memory/persistence/store_query.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":"core_memory/persistence/store_query.py"},"region":{"startLine":8}}}],"partialFingerprints":{"codehealthFindingId/v1":"63ab93df2c345fdd86435b00066b018e3e20a63ee8295b9d32474307d5875461"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: core_memory/runtime/dreamer/longitudinal.py: core_memory/runtime/dreamer/longitudinal.py changed 2 times in last 90 days, max cyclomatic complexity 17 in longitudinal.longitudinal_benchmark_v2 at line 178. 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-05-08..2026-08-06, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-05-08 14:26:39 -05:00\u0027 --until=\u00272026-08-06 14:26:39 -05:00\u0027 --full-history --no-merges -- core_memory/runtime/dreamer/longitudinal.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":"core_memory/runtime/dreamer/longitudinal.py"},"region":{"startLine":178}}}],"partialFingerprints":{"codehealthFindingId/v1":"765a31ad9539b1031e6e955d732b2a6ec0b2c327baeae845e2d29796227ba574"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: core_memory/persistence/store_projection_ops.py: core_memory/persistence/store_projection_ops.py changed 2 times in last 90 days, max cyclomatic complexity 16 in store_projection_ops.rebuild_index_projection_from_sessions_for_store at line 11. 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-05-08..2026-08-06, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-05-08 14:26:39 -05:00\u0027 --until=\u00272026-08-06 14:26:39 -05:00\u0027 --full-history --no-merges -- core_memory/persistence/store_projection_ops.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":"core_memory/persistence/store_projection_ops.py"},"region":{"startLine":11}}}],"partialFingerprints":{"codehealthFindingId/v1":"3515803d13a388555c2dbd336e6dbfc672c82968a25d15c81189ed70bbdfa379"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: benchmarks/causal_continuity/runtime_ablations.py: benchmarks/causal_continuity/runtime_ablations.py changed 2 times in last 90 days, max cyclomatic complexity 16 in runtime_ablations.run_runtime_ablation_toggles 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-05-08..2026-08-06, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-05-08 14:26:39 -05:00\u0027 --until=\u00272026-08-06 14:26:39 -05:00\u0027 --full-history --no-merges -- benchmarks/causal_continuity/runtime_ablations.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":"benchmarks/causal_continuity/runtime_ablations.py"},"region":{"startLine":77}}}],"partialFingerprints":{"codehealthFindingId/v1":"57061d7f1da6ff9359b3cb79e29fd2ff4f82463fcd4387670c1e77d95de76fa1"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: core_memory/integrations/mcp/tools/status.py: core_memory/integrations/mcp/tools/status.py changed 2 times in last 90 days, max cyclomatic complexity 16 in status.status_handler at line 40. 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-05-08..2026-08-06, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-05-08 14:26:39 -05:00\u0027 --until=\u00272026-08-06 14:26:39 -05:00\u0027 --full-history --no-merges -- core_memory/integrations/mcp/tools/status.py\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"core_memory/integrations/mcp/tools/status.py"},"region":{"startLine":40}}}],"partialFingerprints":{"codehealthFindingId/v1":"b44588c84cea0aed3cba572a6cc2974c2701a1bfb1a8eb96219ace0a3d9d99aa"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: core_memory/runtime/dreamer/goal_decay.py: core_memory/runtime/dreamer/goal_decay.py changed 2 times in last 90 days, max cyclomatic complexity 16 in goal_decay.detect_goal_decay at line 72. 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-05-08..2026-08-06, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-05-08 14:26:39 -05:00\u0027 --until=\u00272026-08-06 14:26:39 -05:00\u0027 --full-history --no-merges -- core_memory/runtime/dreamer/goal_decay.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":"core_memory/runtime/dreamer/goal_decay.py"},"region":{"startLine":72}}}],"partialFingerprints":{"codehealthFindingId/v1":"5b59ecf30cda4389f64cd3888ccadd77766219d8e9a2e442e24c094e4f4d5513"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: core_memory/cli/handlers/semantic.py: core_memory/cli/handlers/semantic.py changed 2 times in last 90 days, max cyclomatic complexity 16 in semantic.handle_semantic_command at line 46. 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-05-08..2026-08-06, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-05-08 14:26:39 -05:00\u0027 --until=\u00272026-08-06 14:26:39 -05:00\u0027 --full-history --no-merges -- core_memory/cli/handlers/semantic.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":"core_memory/cli/handlers/semantic.py"},"region":{"startLine":46}}}],"partialFingerprints":{"codehealthFindingId/v1":"f04420bc66437ac809cdfe1cca89fb2f9a399e9a85549bccf5c31f4afc044dae"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: core_memory/entity/speaker_resolver.py: core_memory/entity/speaker_resolver.py changed 2 times in last 90 days, max cyclomatic complexity 15 in speaker_resolver.resolve_speaker at line 66. 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-05-08..2026-08-06, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-05-08 14:26:39 -05:00\u0027 --until=\u00272026-08-06 14:26:39 -05:00\u0027 --full-history --no-merges -- core_memory/entity/speaker_resolver.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":"core_memory/entity/speaker_resolver.py"},"region":{"startLine":66}}}],"partialFingerprints":{"codehealthFindingId/v1":"af8c6c9b23162ff2c6074996558e7326ff8b3f7ebf4b437dc8f5e9eb5c671c19"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: core_memory/soul/goals.py: core_memory/soul/goals.py changed 2 times in last 90 days, max cyclomatic complexity 15 in goals.list_goals at line 152. 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-05-08..2026-08-06, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-05-08 14:26:39 -05:00\u0027 --until=\u00272026-08-06 14:26:39 -05:00\u0027 --full-history --no-merges -- core_memory/soul/goals.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":"core_memory/soul/goals.py"},"region":{"startLine":152}}}],"partialFingerprints":{"codehealthFindingId/v1":"5fe4f2e32e6414656b3dc74d61aa32ffae8bba765f63fdae1b3fda47dff38551"}},{"ruleId":"D16","level":"note","message":{"text":"Off-boarding risk: anonymized user #1: If anonymized user #1 becomes unavailable, 152 significant file(s) lose their only recent owner: core_memory/runtime/associations/coverage.py, core_memory/retrieval/pipeline/canonical.py, core_memory/management/__init__.py, core_memory/graph/root_cause.py, core_memory/runtime/dreamer/candidates.py, scripts/check_architecture_guards.py, core_memory/soul/summary.py, core_memory/retrieval/agent.py (\u002B144 more). Pair on, review, or document these before any departure."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"e3ce4887dec351ea41eb0a2b22c904290d7b9aaf4845428576cfa9ffa4fad335"}},{"ruleId":"D16","level":"note","message":{"text":"Off-boarding risk: anonymized user #2: If anonymized user #2 becomes unavailable, 5 significant file(s) lose their only recent owner: core_memory/retrieval/tools/memory_reason.py, eval/paraphrase_eval.py, eval/retrieval_eval.py, eval/memory_execute_eval.py, core_memory/policy/incidents.py. Pair on, review, or document these before any departure."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"f760b9ee879e6302768909a0140430b4f5935d515ee1b88988a6c914c89aa98c"}},{"ruleId":"D19","level":"note","message":{"text":"Documentation: no installation or build instructions: The README lacks installation, build, or setup instructions for the main Core Memory package. Add an install section covering pip requirements and any prerequisites."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"README.md"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"1fa6bfcd5c6ae231d1b8ee99bced50b832d1f61cde9da6cbb533467b879a57db"}},{"ruleId":"D19","level":"note","message":{"text":"Documentation: no usage examples: There are no usage examples in the README describing how to run the server or invoke the demo. Provide a short \u0027How to run it\u0027 example for the main server and the Core Memory demo."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"README.md"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"1355eb4e127a4bc9236772ce1c46f09510aa9286e7a06d1e47f308229df19049"}},{"ruleId":"D19","level":"note","message":{"text":"Documentation: written for insiders: The SpringAI integration docs describe a runtime bridge entrypoint (\u0060core_memory.integrations.springai.get_app()\u0060) but the document is written for an internal audience and contains no context tying this to the broader causal memory thesis. Add a brief rationale or ticket reference that maps the runtime bridge to the project\u0027s main causal-memory layer."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/integrations/springai/README.md"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"1889a2facd2655d1053860b4135159b0adc34ada3b6da260fd2699e28b9747ae"}},{"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":"17af65895bdd4ffe30282e92f30c11eafc1fd2910fb67ed4aa12b2417c478d71"},"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":"fe45b0153b6f09f35ea0d587983aa30bfd002310de3357ac997b7eed1e03c849"},"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":"e5639cdc42bbfb7ad7e82aac09da1f5135b6ba868f718e6077f6357c94d2f43d"},"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":"66ac1d15c4b4661127abb4ec21ad3f1f9af9350d46efa6a3a5e8f89552d71b19"},"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":"30e5d8f15b83539c69e73d888b9c39e9253b1993c60ef240d2b88d63a23409b0"},"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":"97bfcf6e5cf282b06b90b6a1e35f581d5547312f13101af867babb122cbb6437"},"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":"bb6069ab4a5fd83b2e426faac0bc4a2081d501ed71a342845ace28a103b68627"},"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":"024e2a71cfd96c318339e64fd4d14b70cb0dfbf2d7795f2e237af12a2b769f50"},"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":"fef30e6e70c7cf5b52ae744e88f0698c8f21d111d19e926ca11cb1b28fffd6d1"},"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":"80009c88b9eadf6e2020ebc9dc841f4e90a3b4a707550e5ba1ea52a84ecdee18"},"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":"0df7cb73eb7a01acf34e3702b8db4a4a22cab36c2fa1933879a5fedb285b08d8"},"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":"1033e81807e44c384290f622819a4e5492a089144453a0c3b625ad5ab24d5cea"},"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":"b7f4528614a1b9b7293cc2fb63c04face27b8d53f66f0719b7558b64a1b7e207"},"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":"244bef360fb7accec89ef84ded19dfcb5397d9337bcca0e2ac568b4743218784"},"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":"b8a1d8a48bc0e28796bed135659c8ddf78f729bdbd41ef9c3d1ea826b6b2d6d4"},"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":"cea7946a594f0595594b45308d2f60dfef33dc808e7d6dfdcb3f7044956cae7a"},"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":"55a9feee9774121f2f799f78815f48406c361b20f27615a6b6c4aa576c312700"},"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":"85766863295dc45a78da3b85c73b22c3da5b4cff929663a05b1937998a45791b"},"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":"929889218fe2adba5577454da6e2fffb54a21f38de62c057ea511bf22abbc080"},"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":"3901227bc675c28ed5f31ccf57dedfbd4c92df41b4c3da76529ced5e5418ffe8"},"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":"ab8ce016c05617d2bea946f803bbeb3700de85a9611a8808cd4bc113313a14a3"},"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":"8a613d69adb910192edd175ef738a14a05de3ba12fd957830039f228ccb617e8"},"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":"5737efc06c6e8974d9eca5116fd6fad508959b148616caec8005de3fc2426593"},"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":"d8702aaaf57f989714d552fadd673ada65f222b8d3da9237f33fe63353813906"},"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":"53315474bb32001c95429eb87437f2f6d6b5dc02b7dabcb3440cf7a4f84d5346"},"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":"39bb71a6084ff6cd9a10645910516299ff884182010bb520f5feb66e1a2685bf"},"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":"1c4e5a6e3f47d4185c1fd8955b9d5cac51f3937764a172906efaecf94eb2520f"},"taxa":[{"id":"CWE-78","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":"24f20f127a2fd71b707210f0ae7395181c1184e128e8b5965a125a497d8f0ce9"},"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":"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":"0bfe2858917efa1e5eaa20eb4312dd909c906147fe4c900af4b15b179b42f604"},"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":"4ddfce58a3f918bd01d9ef4b26de576f6ec2be3b3cfe1684778c1a342d8cc18d"},"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":"6c4574a4e05aeab9fe6ec1842477bbab6ad236b0968eaadfd5526c95c59f7ee8"},"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":"f760d1e630c24b010421fd9db56b75f5c662416b421704b5573ec041cd9f5c23"},"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":"6d963a5454d468150f63fa8d819be5d210d2c88d4ed87ecefa6145e4ccbbd432"},"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":"38701daa32b5e54eac06b585e2848da19705a2f2b4766e6b53fcef60cd57488b"},"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":"f23f21cf25a8c9538d3ce8ef4fa0370f911319e53901fe950cdb60acb14c7cff"},"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":"a282716b36e2bc7ce4b9eebfec9bc063f69485a956efa9a75d0fb50927b24262"},"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":"ef52f3301a207f32c2651a27e8951ae4b822a9f36d5cd4389815513a875ae71e"},"taxa":[{"id":"CWE-327","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":"cfc7b511376e5c7763218725cdc612751d3edaae624f7dab460c194d7aada123"},"taxa":[{"id":"CWE-939","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"note","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"34654f8d0d4dbcf02bbf2543f18aba2699b2781f7f6b5b3974ed168525365f2e"},"taxa":[{"id":"CWE-939","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"note","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"a30d21a8edb987ae23a444e3d7f9bba1b551e4a7a85c99f9d34ed355787257a3"},"taxa":[{"id":"CWE-939","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"note","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"7b9641d69deda3817ffe697eff7098a166feab78b494d914257a06308e82de66"},"taxa":[{"id":"CWE-939","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"note","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"020d90f58f981ead85a43cb0701ab272f8fe7037ed4d96f2042bc10d21fa3a4e"},"taxa":[{"id":"CWE-939","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"note","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"31059bd76a2797dcbcd98c47ba9162a1c492b2c7c40e2e111d63cf41027e93c0"},"taxa":[{"id":"CWE-939","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"note","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"f199ddb7870e93f35bb59b2d29fa5bf37113e94562be4dc33e06564f5d2409a6"},"taxa":[{"id":"CWE-939","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"note","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"2595a3ec08a45685eb921fb74904ae9cef5ba80c48ab545c5336b99e7d83eb0d"},"taxa":[{"id":"CWE-939","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"note","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"07e6961248d31ba9bf2370e35ff0188302cca57b34e1c454616a8610b4615409"},"taxa":[{"id":"CWE-939","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"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":"83624e2a75b102d656da943ab10c203006d969612030d1669428c03d4067940e"}},{"ruleId":"D34","level":"note","message":{"text":"Orphaned files with no living knowledge: 4 of 273 analysed file(s) have no living knowledge left \u2014 their last meaningful change has decayed away, so if one breaks, no one currently understands it (counted over production source files of roughly 2,400 bytes or more, excluding vendored, generated and example/demo trees and test files identified by path convention, largest first; 273 of the 400 production source files in this repository met that bar). None is large enough to earn a read-through of its own, so this row stands in for the per-file rows rather than raising one each \u2014 most significant first: core_memory/persistence/metrics_ops.py, core_memory/runtime/observability/observability.py, core_memory/config/loader.py, core_memory/persistence/encryption.py. Attach the read to the next change that touches one of them: have a second person review that change, and leave behind a short comment or test recording what the file is for, so the knowledge comes back at the cost of a change you were making anyway."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"ce861fd78f6935114d3a342cb90ad25870f984e1042954fcbbe27c0e23be3658"}},{"ruleId":"D35","level":"warning","message":{"text":"Change coupling: store_add_bead_ops.py \u2194 external_evidence.py: \u0060core_memory/persistence/store_add_bead_ops.py\u0060 and \u0060core_memory/runtime/ingest/external_evidence.py\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) with no explicit dependency \u2014 the edge is real but nothing declares it. Read the pair before acting: if one registers itself into the other through a hook or an initialiser, the missing dependency is DELIBERATE \u2014 the registration is the link, and it is meant not to be an import \u2014 and the thing to add is a comment on each side naming the other, not a merge; if they simply belong together, co-locate them; if neither holds, the coupling is hidden and worth breaking. You can check this without leaving the row: of the 7 shared commits counted here, the most recent 3 are \u0060d31b77b1\u0060 Implement lossless agent-authored bead writes (#404); \u0060438d294b\u0060 Scrub retired Ragie tie-ins (#375); \u0060a5e2460b\u0060 Remove Ragie recall fan-out (#374) \u2014 run \u0060git show\u0060 on any of them."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"core_memory/persistence/store_add_bead_ops.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"ff70e4f70acf57dfb2e95b49f095dd1430ebea3153807a61ef5350237b493fcd"}},{"ruleId":"D35","level":"warning","message":{"text":"Change coupling: server.py \u2194 side_effect_queue.py: \u0060core_memory/integrations/http/server.py\u0060 and \u0060core_memory/runtime/queue/side_effect_queue.py\u0060 change together 50% of the time (10 of the 20 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 \u2014 the edge is real but nothing declares it. Read the pair before acting: if one registers itself into the other through a hook or an initialiser, the missing dependency is DELIBERATE \u2014 the registration is the link, and it is meant not to be an import \u2014 and the thing to add is a comment on each side naming the other, not a merge; if they simply belong together, co-locate them; if neither holds, the coupling is hidden and worth breaking. You can check this without leaving the row: of the 10 shared commits counted here, the most recent 3 are \u0060e9016a24\u0060 feat(retrieval): build durable junction roadmap (#434); \u0060cae4f400\u0060 feat(goals): add reviewed goal progress edges (#433); \u00602aa1f9e2\u0060 Improve agent-judged causal association quality (#417) \u2014 run \u0060git show\u0060 on any of them."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"core_memory/integrations/http/server.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"7e1c93c03e8a31a8ca9b32e9a6144e356e859afa0d12a219931960a73f27787d"}},{"ruleId":"D36","level":"note","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"eb00976a698a5d68999b7ee6d27206fd374e916853e7ff1ead5eed42386f043f"}},{"ruleId":"D36","level":"warning","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"90f83b4fa27db32740afe9540c905f3c0499caed87f61049a8a903ecc95b41c3"}},{"ruleId":"D36","level":"warning","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"0752d0df7434000fcabf1048e2de30a7a1a8b982b3db9a19898c4dec199856b4"}},{"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":"D43","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":"ca77df8ac0ed56a2e42b0923be81cca477f3174e98a1dc599981adac6a376eef"}},{"ruleId":"M2","level":"note","message":{"text":"ADRs not easily discoverable: 1 ADR-shaped document(s) detected by content \u2014 \u0060docs/design/F-W1-write-pipeline.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":"P12","level":"warning","message":{"text":"Coverage collected but not gated: CI collects a coverage report but no step enforces a minimum \u2014 coverage could halve and CI stays green. Add a step that fails the build when coverage drops below a floor (your coverage tool\u0027s minimum-threshold flag, or a coverage-gate action) so the number guards something. What was searched, so you can tell an absence from a miss: this repository\u0027s CI files AND its coverage configuration \u2014 the well-known coverage and test-runner config files, read at the repository root and inside workspace package directories two levels down, so a floor declared beside the tests rather than in the pipeline is credited \u2014 matched against the threshold settings this check knows by name. A floor set in your coverage service\u0027s web UI rather than in a committed file, or under a setting whose name is not one of those, is not seen here."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"7f63c06044cf998d9a0698692df30d8873e29bc9b0c98ee829255017c1193d33"}},{"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 8259 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":"SC1","level":"warning","message":{"text":"JavaScript dependencies are not locked: No package-lock.json / yarn.lock / pnpm-lock.yaml / bun.lock \u2014 JS installs aren\u0027t reproducible (SSDF PW.4.4). Commit your package manager\u0027s lockfile and install from it (\u0060npm ci\u0060, \u0060yarn --immutable\u0060, \u0060pnpm i --frozen-lockfile\u0060 or \u0060bun i --frozen-lockfile\u0060). Advisory \u2014 never scored."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"40a08798dc9f9c819eaa9f7c084938e1cf2517a9281aed2c31563d6f7d5ba90d"}}],"taxonomies":[{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d","organization":"MITRE","informationUri":"https://cwe.mitre.org/","isComprehensive":false,"shortDescription":{"text":"The MITRE Common Weakness Enumeration (CWE)."},"taxa":[{"id":"CWE-1357","guid":"e4d2e772-757e-0a5c-bd7d-77052949d866","name":"Reliance on Insufficiently Trustworthy Component","shortDescription":{"text":"Reliance on Insufficiently Trustworthy Component"},"helpUri":"https://cwe.mitre.org/data/definitions/1357.html"},{"id":"CWE-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-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-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":52,"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."]}]}