{"$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":"D5","name":"Coupling","shortDescription":{"text":"Coupling"},"helpUri":"https://codehealth.canine.dev/dimensions/D5"},{"id":"D6","name":"Cohesion (LCOM4)","shortDescription":{"text":"Cohesion (LCOM4)"},"helpUri":"https://codehealth.canine.dev/dimensions/D6"},{"id":"D7","name":"Architectural Integrity","shortDescription":{"text":"Architectural Integrity"},"helpUri":"https://codehealth.canine.dev/dimensions/D7"},{"id":"D8","name":"Code Coverage","shortDescription":{"text":"Code Coverage"},"helpUri":"https://codehealth.canine.dev/dimensions/D8"},{"id":"D9","name":"Test Distribution","shortDescription":{"text":"Test Distribution"},"helpUri":"https://codehealth.canine.dev/dimensions/D9"},{"id":"D11","name":"Test Reliability","shortDescription":{"text":"Test Reliability"},"helpUri":"https://codehealth.canine.dev/dimensions/D11"},{"id":"D12","name":"Dependency Hygiene","shortDescription":{"text":"Dependency Hygiene"},"helpUri":"https://codehealth.canine.dev/dimensions/D12"},{"id":"D13","name":"Secret Scanning","shortDescription":{"text":"Secret Scanning"},"helpUri":"https://codehealth.canine.dev/dimensions/D13","relationships":[{"target":{"id":"CWE-798","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},"kinds":["relevant"]},{"target":{"id":"CWE-259","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},"kinds":["relevant"]},{"target":{"id":"A07:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}},"kinds":["relevant"]}],"properties":{"cwe":["CWE-798","CWE-259"],"owasp":"A07:2025"}},{"id":"D14","name":"License Compliance","shortDescription":{"text":"License Compliance"},"helpUri":"https://codehealth.canine.dev/dimensions/D14"},{"id":"D15","name":"Churn \u00D7 Complexity Hotspots","shortDescription":{"text":"Churn \u00D7 Complexity Hotspots"},"helpUri":"https://codehealth.canine.dev/dimensions/D15"},{"id":"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":"D25","name":"ADR Conformance","shortDescription":{"text":"ADR Conformance"},"helpUri":"https://codehealth.canine.dev/dimensions/D25"},{"id":"D28","name":"Secrets (history)","shortDescription":{"text":"Secrets (history)"},"helpUri":"https://codehealth.canine.dev/dimensions/D28","relationships":[{"target":{"id":"CWE-798","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},"kinds":["relevant"]},{"target":{"id":"CWE-259","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},"kinds":["relevant"]},{"target":{"id":"A07:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}},"kinds":["relevant"]}],"properties":{"cwe":["CWE-798","CWE-259"],"owasp":"A07:2025"}},{"id":"D29","name":"Static Analysis (SAST)","shortDescription":{"text":"Static Analysis (SAST)"},"helpUri":"https://codehealth.canine.dev/dimensions/D29","relationships":[{"target":{"id":"CWE-79","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},"kinds":["relevant"]},{"target":{"id":"CWE-89","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},"kinds":["relevant"]},{"target":{"id":"CWE-78","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},"kinds":["relevant"]},{"target":{"id":"CWE-94","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},"kinds":["relevant"]},{"target":{"id":"CWE-77","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},"kinds":["relevant"]},{"target":{"id":"A05:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}},"kinds":["relevant"]}],"properties":{"cwe":["CWE-79","CWE-89","CWE-78","CWE-94","CWE-77"],"owasp":"A05:2025"}},{"id":"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"]},{"target":{"id":"A03:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}},"kinds":["relevant"]}],"properties":{"cwe":["CWE-1395","CWE-937"],"owasp":"A03:2025"}},{"id":"D31","name":"IaC \u0026 Container Security","shortDescription":{"text":"IaC \u0026 Container Security"},"helpUri":"https://codehealth.canine.dev/dimensions/D31","relationships":[{"target":{"id":"CWE-1032","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},"kinds":["relevant"]},{"target":{"id":"CWE-732","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},"kinds":["relevant"]},{"target":{"id":"CWE-16","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},"kinds":["relevant"]},{"target":{"id":"A02:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}},"kinds":["relevant"]}],"properties":{"cwe":["CWE-1032","CWE-732","CWE-16"],"owasp":"A02:2025"}},{"id":"D34","name":"Knowledge Freshness","shortDescription":{"text":"Knowledge Freshness"},"helpUri":"https://codehealth.canine.dev/dimensions/D34"},{"id":"D35","name":"Change Coupling","shortDescription":{"text":"Change Coupling"},"helpUri":"https://codehealth.canine.dev/dimensions/D35"},{"id":"D36","name":"Supply-chain Provenance \u0026 Signing","shortDescription":{"text":"Supply-chain Provenance \u0026 Signing"},"helpUri":"https://codehealth.canine.dev/dimensions/D36","relationships":[{"target":{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},"kinds":["relevant"]},{"target":{"id":"CWE-494","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},"kinds":["relevant"]},{"target":{"id":"A03:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}},"kinds":["relevant"]}],"properties":{"cwe":["CWE-1357","CWE-494"],"owasp":"A03:2025"}},{"id":"D37","name":"Vulnerability-disclosure Policy","shortDescription":{"text":"Vulnerability-disclosure Policy"},"helpUri":"https://codehealth.canine.dev/dimensions/D37","relationships":[{"target":{"id":"CWE-1059","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},"kinds":["relevant"]},{"target":{"id":"A02:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}},"kinds":["relevant"]}],"properties":{"cwe":["CWE-1059"],"owasp":"A02:2025"}},{"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"]},{"target":{"id":"A08:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}},"kinds":["relevant"]}],"properties":{"cwe":["CWE-506"],"owasp":"A08:2025"}},{"id":"D44","name":"Platform End-of-Life","shortDescription":{"text":"Platform End-of-Life"},"helpUri":"https://codehealth.canine.dev/dimensions/D44"},{"id":"AC1","name":"Text alternatives","shortDescription":{"text":"Text alternatives"},"helpUri":"https://codehealth.canine.dev/dimensions/AC1"},{"id":"AC2","name":"Forms \u0026 labels","shortDescription":{"text":"Forms \u0026 labels"},"helpUri":"https://codehealth.canine.dev/dimensions/AC2"},{"id":"AC3","name":"Page structure","shortDescription":{"text":"Page structure"},"helpUri":"https://codehealth.canine.dev/dimensions/AC3"},{"id":"AC4","name":"Keyboard semantics","shortDescription":{"text":"Keyboard semantics"},"helpUri":"https://codehealth.canine.dev/dimensions/AC4"},{"id":"AC5","name":"ARIA correctness","shortDescription":{"text":"ARIA correctness"},"helpUri":"https://codehealth.canine.dev/dimensions/AC5"},{"id":"AC6","name":"Visual \u0026 motion safety","shortDescription":{"text":"Visual \u0026 motion safety"},"helpUri":"https://codehealth.canine.dev/dimensions/AC6"},{"id":"AC7","name":"A11y enforcement","shortDescription":{"text":"A11y enforcement"},"helpUri":"https://codehealth.canine.dev/dimensions/AC7"},{"id":"AX10","name":"Code composition","shortDescription":{"text":"Code composition"},"helpUri":"https://codehealth.canine.dev/dimensions/AX10"},{"id":"AX3","name":"Project dependency cycles","shortDescription":{"text":"Project dependency cycles"},"helpUri":"https://codehealth.canine.dev/dimensions/AX3"},{"id":"AX4","name":"Dependency direction","shortDescription":{"text":"Dependency direction"},"helpUri":"https://codehealth.canine.dev/dimensions/AX4"},{"id":"AX8","name":"Test isolation","shortDescription":{"text":"Test isolation"},"helpUri":"https://codehealth.canine.dev/dimensions/AX8"},{"id":"AXB2","name":"Runtime readiness","shortDescription":{"text":"Runtime readiness"},"helpUri":"https://codehealth.canine.dev/dimensions/AXB2"},{"id":"ED5","name":"Idempotency","shortDescription":{"text":"Idempotency"},"helpUri":"https://codehealth.canine.dev/dimensions/ED5"},{"id":"GD1","name":"Unfinished \u0026 placeholder code","shortDescription":{"text":"Unfinished \u0026 placeholder code"},"helpUri":"https://codehealth.canine.dev/dimensions/GD1"},{"id":"IC1","name":"Incompleteness \u0026 stubs","shortDescription":{"text":"Incompleteness \u0026 stubs"},"helpUri":"https://codehealth.canine.dev/dimensions/IC1"},{"id":"M1","name":"Documentation (README)","shortDescription":{"text":"Documentation (README)"},"helpUri":"https://codehealth.canine.dev/dimensions/M1"},{"id":"M2","name":"Architecture documentation","shortDescription":{"text":"Architecture documentation"},"helpUri":"https://codehealth.canine.dev/dimensions/M2"},{"id":"M3","name":"Folder \u0026 project structure","shortDescription":{"text":"Folder \u0026 project structure"},"helpUri":"https://codehealth.canine.dev/dimensions/M3"},{"id":"M4","name":"Documentation accuracy","shortDescription":{"text":"Documentation accuracy"},"helpUri":"https://codehealth.canine.dev/dimensions/M4"},{"id":"P1","name":"CI/CD gates","shortDescription":{"text":"CI/CD gates"},"helpUri":"https://codehealth.canine.dev/dimensions/P1"},{"id":"P10","name":"Library API \u0026 versioning","shortDescription":{"text":"Library API \u0026 versioning"},"helpUri":"https://codehealth.canine.dev/dimensions/P10"},{"id":"P12","name":"CI test-gate honesty","shortDescription":{"text":"CI test-gate honesty"},"helpUri":"https://codehealth.canine.dev/dimensions/P12"},{"id":"P2","name":"Observability","shortDescription":{"text":"Observability"},"helpUri":"https://codehealth.canine.dev/dimensions/P2"},{"id":"P3","name":"Security \u0026 performance tooling","shortDescription":{"text":"Security \u0026 performance tooling"},"helpUri":"https://codehealth.canine.dev/dimensions/P3"},{"id":"P4","name":"Deployment \u0026 Rollback","shortDescription":{"text":"Deployment \u0026 Rollback"},"helpUri":"https://codehealth.canine.dev/dimensions/P4"},{"id":"P5","name":"DR \u0026 Backup","shortDescription":{"text":"DR \u0026 Backup"},"helpUri":"https://codehealth.canine.dev/dimensions/P5"},{"id":"P6","name":"Release Hygiene","shortDescription":{"text":"Release Hygiene"},"helpUri":"https://codehealth.canine.dev/dimensions/P6"},{"id":"PF3","name":"Async \u0026 latency hygiene","shortDescription":{"text":"Async \u0026 latency hygiene"},"helpUri":"https://codehealth.canine.dev/dimensions/PF3"},{"id":"R1","name":"Type Safety","shortDescription":{"text":"Type Safety"},"helpUri":"https://codehealth.canine.dev/dimensions/R1"},{"id":"R10","name":"Code Duplication","shortDescription":{"text":"Code Duplication"},"helpUri":"https://codehealth.canine.dev/dimensions/R10"},{"id":"R2","name":"Cyclomatic Complexity","shortDescription":{"text":"Cyclomatic Complexity"},"helpUri":"https://codehealth.canine.dev/dimensions/R2"},{"id":"R3","name":"Large Files","shortDescription":{"text":"Large Files"},"helpUri":"https://codehealth.canine.dev/dimensions/R3"},{"id":"R6","name":"Tooling","shortDescription":{"text":"Tooling"},"helpUri":"https://codehealth.canine.dev/dimensions/R6"},{"id":"R7","name":"Dead Code","shortDescription":{"text":"Dead Code"},"helpUri":"https://codehealth.canine.dev/dimensions/R7"},{"id":"R8","name":"Dependency Hygiene","shortDescription":{"text":"Dependency Hygiene"},"helpUri":"https://codehealth.canine.dev/dimensions/R8"},{"id":"R9","name":"Circular Imports","shortDescription":{"text":"Circular Imports"},"helpUri":"https://codehealth.canine.dev/dimensions/R9"},{"id":"S1","name":"Cryptographic Hygiene","shortDescription":{"text":"Cryptographic Hygiene"},"helpUri":"https://codehealth.canine.dev/dimensions/S1"},{"id":"SC1","name":"Supply-chain hygiene","shortDescription":{"text":"Supply-chain hygiene"},"helpUri":"https://codehealth.canine.dev/dimensions/SC1"},{"id":"X1","name":"Async correctness","shortDescription":{"text":"Async correctness"},"helpUri":"https://codehealth.canine.dev/dimensions/X1"},{"id":"X10","name":"Duplicated predicate","shortDescription":{"text":"Duplicated predicate"},"helpUri":"https://codehealth.canine.dev/dimensions/X10"},{"id":"X12","name":"Unreachable branch","shortDescription":{"text":"Unreachable branch"},"helpUri":"https://codehealth.canine.dev/dimensions/X12"},{"id":"X13","name":"Undrained process stream","shortDescription":{"text":"Undrained process stream"},"helpUri":"https://codehealth.canine.dev/dimensions/X13"},{"id":"X14","name":"Bypassable address classification","shortDescription":{"text":"Bypassable address classification"},"helpUri":"https://codehealth.canine.dev/dimensions/X14"},{"id":"X15","name":"Unvalidated length from an untrusted reader","shortDescription":{"text":"Unvalidated length from an untrusted reader"},"helpUri":"https://codehealth.canine.dev/dimensions/X15"},{"id":"X16","name":"Unfloored truncation loop","shortDescription":{"text":"Unfloored truncation loop"},"helpUri":"https://codehealth.canine.dev/dimensions/X16"},{"id":"X17","name":"Uncapped recursion over a caller-supplied document","shortDescription":{"text":"Uncapped recursion over a caller-supplied document"},"helpUri":"https://codehealth.canine.dev/dimensions/X17"},{"id":"X18","name":"Disposal-pattern correctness","shortDescription":{"text":"Disposal-pattern correctness"},"helpUri":"https://codehealth.canine.dev/dimensions/X18"},{"id":"X19","name":"Unrestored process-global state","shortDescription":{"text":"Unrestored process-global state"},"helpUri":"https://codehealth.canine.dev/dimensions/X19"},{"id":"X2","name":"Cancellation propagation","shortDescription":{"text":"Cancellation propagation"},"helpUri":"https://codehealth.canine.dev/dimensions/X2"},{"id":"X20","name":"Mistyped argument guard","shortDescription":{"text":"Mistyped argument guard"},"helpUri":"https://codehealth.canine.dev/dimensions/X20"},{"id":"X21","name":"Side-effecting pattern guard","shortDescription":{"text":"Side-effecting pattern guard"},"helpUri":"https://codehealth.canine.dev/dimensions/X21"},{"id":"X22","name":"Contradicted release guard","shortDescription":{"text":"Contradicted release guard"},"helpUri":"https://codehealth.canine.dev/dimensions/X22"},{"id":"X23","name":"Unguarded diagnostic materialisation","shortDescription":{"text":"Unguarded diagnostic materialisation"},"helpUri":"https://codehealth.canine.dev/dimensions/X23"},{"id":"X24","name":"Document value interpolated into markup unescaped","shortDescription":{"text":"Document value interpolated into markup unescaped"},"helpUri":"https://codehealth.canine.dev/dimensions/X24"},{"id":"X25","name":"Inert configuration knob","shortDescription":{"text":"Inert configuration knob"},"helpUri":"https://codehealth.canine.dev/dimensions/X25"},{"id":"X26","name":"Unsynchronised callback handoff","shortDescription":{"text":"Unsynchronised callback handoff"},"helpUri":"https://codehealth.canine.dev/dimensions/X26"},{"id":"X28","name":"Index access outside its own emptiness guard","shortDescription":{"text":"Index access outside its own emptiness guard"},"helpUri":"https://codehealth.canine.dev/dimensions/X28"},{"id":"X29","name":"Per-element action decided by a fixed element","shortDescription":{"text":"Per-element action decided by a fixed element"},"helpUri":"https://codehealth.canine.dev/dimensions/X29"},{"id":"X3","name":"Exception handling","shortDescription":{"text":"Exception handling"},"helpUri":"https://codehealth.canine.dev/dimensions/X3"},{"id":"X30","name":"Support guard that admits what it rejects","shortDescription":{"text":"Support guard that admits what it rejects"},"helpUri":"https://codehealth.canine.dev/dimensions/X30"},{"id":"X32","name":"Type resolved by simple name across every loaded assembly","shortDescription":{"text":"Type resolved by simple name across every loaded assembly"},"helpUri":"https://codehealth.canine.dev/dimensions/X32"},{"id":"X4","name":"Structured logging","shortDescription":{"text":"Structured logging"},"helpUri":"https://codehealth.canine.dev/dimensions/X4"},{"id":"X5","name":"Nullable reference types","shortDescription":{"text":"Nullable reference types"},"helpUri":"https://codehealth.canine.dev/dimensions/X5"},{"id":"X6","name":"Hand-rolled structured-format parsing","shortDescription":{"text":"Hand-rolled structured-format parsing"},"helpUri":"https://codehealth.canine.dev/dimensions/X6"},{"id":"X7","name":"Silent fallback defaults","shortDescription":{"text":"Silent fallback defaults"},"helpUri":"https://codehealth.canine.dev/dimensions/X7"},{"id":"X9","name":"Subsumed condition operand","shortDescription":{"text":"Subsumed condition operand"},"helpUri":"https://codehealth.canine.dev/dimensions/X9"}]}},"results":[{"ruleId":"D1","level":"warning","message":{"text":"generate-docs.main (cyclomatic 74): generate-docs.main has cyclomatic complexity 74 (threshold 15). To reduce it, separate the cases: extract each independent branch into its own 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/generate-docs.py"},"region":{"startLine":458}}}],"partialFingerprints":{"codehealthFindingId/v1":"e783ca3b7777670304f8ca45a79b99afdc22b091a4bd30f748c0e2f4fe0b5f28"}},{"ruleId":"D1","level":"warning","message":{"text":"collect_sessions.parse_claude_session (cyclomatic 55): collect_sessions.parse_claude_session 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":"engineering/skill-doctor/skills/skill-doctor/scripts/collect_sessions.py"},"region":{"startLine":252}}}],"partialFingerprints":{"codehealthFindingId/v1":"c58f50124defabda38f66b6070f8e02d449797e89bf359fb1943b682721ee41b"}},{"ruleId":"D1","level":"warning","message":{"text":"pricing_model_picker.score_models (cyclomatic 50): pricing_model_picker.score_models has cyclomatic complexity 50 (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":"commercial/skills/pricing-strategist/scripts/pricing_model_picker.py"},"region":{"startLine":85}}}],"partialFingerprints":{"codehealthFindingId/v1":"5fed6840d05403548440bd0f26e9ba53bae7804b5ab2200c4000c79f6dc1dc7f"}},{"ruleId":"D1","level":"warning","message":{"text":"term_sheet_analyzer.score (cyclomatic 48): term_sheet_analyzer.score has cyclomatic complexity 48 (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":"c-level-advisor/general-counsel-advisor/skills/general-counsel-advisor/scripts/term_sheet_analyzer.py"},"region":{"startLine":80}}}],"partialFingerprints":{"codehealthFindingId/v1":"24cf8c9b0d89335a4952427cc8a479b64713731536dfa81509f94a762fe97886"}},{"ruleId":"D1","level":"warning","message":{"text":"term_sheet_analyzer.score (cyclomatic 48): term_sheet_analyzer.score has cyclomatic complexity 48 (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":"c-level-advisor/skills/general-counsel-advisor/scripts/term_sheet_analyzer.py"},"region":{"startLine":80}}}],"partialFingerprints":{"codehealthFindingId/v1":"569cffb41d1254f661c549653e2a25969fe4f8b53385b85de6f8abef9b6c73c5"}},{"ruleId":"D1","level":"warning","message":{"text":"tc_update.main (cyclomatic 48): tc_update.main has cyclomatic complexity 48 (threshold 15). To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/tc-tracker/scripts/tc_update.py"},"region":{"startLine":128}}}],"partialFingerprints":{"codehealthFindingId/v1":"6b05322fe7d2d0c507bea5b374521d02c5831844a7d5d3fda65cb4e98b72b476"}},{"ruleId":"D1","level":"warning","message":{"text":"tc_validator.validate_tc_record (cyclomatic 48): tc_validator.validate_tc_record has cyclomatic complexity 48 (threshold 15). To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/tc-tracker/scripts/tc_validator.py"},"region":{"startLine":123}}}],"partialFingerprints":{"codehealthFindingId/v1":"3363269126ea18855ec10a29bee08a830bb852dc1a5c3211c40070efb9bbd92e"}},{"ruleId":"D1","level":"warning","message":{"text":"profile_completeness_auditor.evaluate_check (cyclomatic 47): profile_completeness_auditor.evaluate_check 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":"marketing/linkedin/skills/linkedin-profile/scripts/profile_completeness_auditor.py"},"region":{"startLine":104}}}],"partialFingerprints":{"codehealthFindingId/v1":"3ae3e6f3ab8fcb6544e0ab448b7badf2801f076854092c5bbcf096360cb43f88"}},{"ruleId":"D1","level":"warning","message":{"text":"comp_benchmarker.print_report (cyclomatic 46): comp_benchmarker.print_report 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":"c-level-advisor/skills/chro-advisor/scripts/comp_benchmarker.py"},"region":{"startLine":275}}}],"partialFingerprints":{"codehealthFindingId/v1":"282097338b772c888d04393a04c5fc80b37cfa2137bb96c7f92a3ee60781b614"}},{"ruleId":"D1","level":"warning","message":{"text":"okr_tracker.format_report (cyclomatic 43): okr_tracker.format_report 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":"c-level-advisor/skills/coo-advisor/scripts/okr_tracker.py"},"region":{"startLine":406}}}],"partialFingerprints":{"codehealthFindingId/v1":"40d2bdecfb37c88813791ef8b0d7b360a7616b001dc90930bcc9bcd55c4346b2"}},{"ruleId":"D1","level":"warning","message":{"text":"policy_linter.lint (cyclomatic 42): policy_linter.lint 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":"commercial/skills/commercial-policy/scripts/policy_linter.py"},"region":{"startLine":114}}}],"partialFingerprints":{"codehealthFindingId/v1":"5e89311de61109e6ebc64ad2c63a573e0870006c78c1ce05f977eb47211636bc"}},{"ruleId":"D1","level":"warning","message":{"text":"score.run_scorecard (cyclomatic 42): score.run_scorecard 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":"finance/skills/stock-analysis/scripts/score.py"},"region":{"startLine":637}}}],"partialFingerprints":{"codehealthFindingId/v1":"d4a5c2181baf64f276e62d31a3ee1695c652887f97b401ca8c7bd3583bdee094"}},{"ruleId":"D1","level":"warning","message":{"text":"threat_signal_analyzer.main (cyclomatic 41): threat_signal_analyzer.main 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":"engineering-team/skills/threat-detection/scripts/threat_signal_analyzer.py"},"region":{"startLine":408}}}],"partialFingerprints":{"codehealthFindingId/v1":"fe199818129bb76d4b2f49affbb65d523af7648d9b604f6839c92d38a5d1b034"}},{"ruleId":"D1","level":"warning","message":{"text":"score.render_segmented_text (cyclomatic 40): score.render_segmented_text 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":"finance/skills/stock-analysis/scripts/score.py"},"region":{"startLine":1396}}}],"partialFingerprints":{"codehealthFindingId/v1":"e0ac2bd9043e9a45f99c80e89ced472675726ac7c5aee539e87999e6e567759f"}},{"ruleId":"D1","level":"warning","message":{"text":"codebase_analyzer.analyze_project (cyclomatic 40): codebase_analyzer.analyze_project 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":"product-team/code-to-prd/skills/code-to-prd/scripts/codebase_analyzer.py"},"region":{"startLine":463}}}],"partialFingerprints":{"codehealthFindingId/v1":"d5c39f310a90604c7725c6d337ce3b0d3f8ac26b97489165c190d173d5c48a9d"}},{"ruleId":"D1","level":"warning","message":{"text":"mechanism_matcher.match (cyclomatic 40): mechanism_matcher.match 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":"research/grants/skills/grants/scripts/mechanism_matcher.py"},"region":{"startLine":54}}}],"partialFingerprints":{"codehealthFindingId/v1":"d8c84566c3f1b7fca78ede498fb8127edca097cdef16284e07dd895adcdbbc20"}},{"ruleId":"D1","level":"warning","message":{"text":"utils.extract_single_file (cyclomatic 39): utils.extract_single_file 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":"engineering/book-to-skill/skills/book-to-skill/scripts/book_to_skill/utils.py"},"region":{"startLine":400}}}],"partialFingerprints":{"codehealthFindingId/v1":"ab7f7286c8ea49e2ec53aa772288d16d60100e0fc170281f0c0bad7cb8dc0160"}},{"ruleId":"D1","level":"warning","message":{"text":"model_arithmetic.step (cyclomatic 38): model_arithmetic.step 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":"engineering/deep-learning-book/skills/deep-learning-book/scripts/model_arithmetic.py"},"region":{"startLine":98}}}],"partialFingerprints":{"codehealthFindingId/v1":"aba10d2aff92f35c288d84cffbaee232d253d2bd4a3c14eb2d42a7ecff0df54f"}},{"ruleId":"D1","level":"warning","message":{"text":"score.render_text (cyclomatic 38): score.render_text 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":"finance/skills/stock-analysis/scripts/score.py"},"region":{"startLine":1263}}}],"partialFingerprints":{"codehealthFindingId/v1":"76b0a20f2dbf36dcb89ded7562447c9f954135d1070868a7c82cd838e5b3438d"}},{"ruleId":"D1","level":"warning","message":{"text":"primitives_validator.validate (cyclomatic 37): primitives_validator.validate has cyclomatic complexity 37 (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":"agent-launcher/skills/interview/scripts/primitives_validator.py"},"region":{"startLine":31}}}],"partialFingerprints":{"codehealthFindingId/v1":"26f89d536bafeae27276ffaa94ab032c537d23102270cd26d00a8cfd4b51fe2f"}},{"ruleId":"D1","level":"warning","message":{"text":"ai_threat_scanner.main (cyclomatic 37): ai_threat_scanner.main 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":"engineering-team/skills/ai-security/scripts/ai_threat_scanner.py"},"region":{"startLine":322}}}],"partialFingerprints":{"codehealthFindingId/v1":"5c5c7af93ca0ddf1efd41fd03db23e27b62dfaeb878b2ebe0611fd803805fc93"}},{"ruleId":"D1","level":"warning","message":{"text":"payload_validator.validate (cyclomatic 36): payload_validator.validate 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":"agent-launcher/skills/stage-launch/scripts/payload_validator.py"},"region":{"startLine":38}}}],"partialFingerprints":{"codehealthFindingId/v1":"66fd08b9a875f065fcafc5eb8489de3317f5b049cbaca14eee26b0b0857ff530"}},{"ruleId":"D1","level":"warning","message":{"text":"compose_validator.validate_compose (cyclomatic 36): compose_validator.validate_compose 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":"engineering/docker-development/skills/docker-development/scripts/compose_validator.py"},"region":{"startLine":156}}}],"partialFingerprints":{"codehealthFindingId/v1":"7fee59a4bcfa94e3d999365dee17bbf82f9b01cdc53fa9f753cc0d632be7a7cc"}},{"ruleId":"D1","level":"warning","message":{"text":"collect_sessions.parse_codex_session (cyclomatic 36): collect_sessions.parse_codex_session 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":"engineering/skill-doctor/skills/skill-doctor/scripts/collect_sessions.py"},"region":{"startLine":391}}}],"partialFingerprints":{"codehealthFindingId/v1":"5e2fefb46af24cbb9d23cf97b1a56b189bd95c6468820ea599cb46b6b6760f91"}},{"ruleId":"D1","level":"warning","message":{"text":"PaymentProcessor.process_payment (cyclomatic 36): PaymentProcessor.process_payment 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":"engineering/skills/tech-debt-tracker/assets/sample_codebase/src/payment_processor.py"},"region":{"startLine":27}}}],"partialFingerprints":{"codehealthFindingId/v1":"298135408076550dfa0018f3a58a57fdf6386d6e4c6784f56b30a0059237495d"}},{"ruleId":"D1","level":"warning","message":{"text":"seo_checker.analyze_html (cyclomatic 36): seo_checker.analyze_html has cyclomatic complexity 36 (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":"marketing-skill/skills/seo-audit/scripts/seo_checker.py"},"region":{"startLine":120}}}],"partialFingerprints":{"codehealthFindingId/v1":"f62c9c2e3aaabdff5ea7da7c08785e87656a7af1a444bce6c5ae19bc24c5b64a"}},{"ruleId":"D1","level":"warning","message":{"text":"html_validator.validate (cyclomatic 36): html_validator.validate has cyclomatic complexity 36 (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":"marketing/landing/skills/landing/scripts/html_validator.py"},"region":{"startLine":113}}}],"partialFingerprints":{"codehealthFindingId/v1":"00cf436a1f11614798a3ed802397afaabf54672406f7e3ef20d2afced6ba28d5"}},{"ruleId":"D1","level":"warning","message":{"text":"result_ranker.main (cyclomatic 35): result_ranker.main 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":"engineering/agenthub/skills/agenthub/scripts/result_ranker.py"},"region":{"startLine":187}}}],"partialFingerprints":{"codehealthFindingId/v1":"6f646f9619a70acd6556fd84f22a3030547940a19b74c983dfb91981675c27c7"}},{"ruleId":"D1","level":"warning","message":{"text":"feedback_parser.parse (cyclomatic 35): feedback_parser.parse 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":"engineering/human-gate/skills/human-gate/scripts/feedback_parser.py"},"region":{"startLine":173}}}],"partialFingerprints":{"codehealthFindingId/v1":"a7a33b08083d628d3a87fd9f30c6615597aa203849c791f2ebb564b16d03624e"}},{"ruleId":"D1","level":"warning","message":{"text":"collect_sessions.main (cyclomatic 35): collect_sessions.main 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":"engineering/skill-doctor/skills/skill-doctor/scripts/collect_sessions.py"},"region":{"startLine":627}}}],"partialFingerprints":{"codehealthFindingId/v1":"10242281551435473d1c9efd4e4433522747d7f1e26d14f5bef2b42403d46767"}},{"ruleId":"D1","level":"warning","message":{"text":"schema_validator.score_schema (cyclomatic 35): schema_validator.score_schema 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":"marketing-skill/skills/schema-markup/scripts/schema_validator.py"},"region":{"startLine":126}}}],"partialFingerprints":{"codehealthFindingId/v1":"96e347841560cf4549b3de18d72f5104d5ff105c416f6bb1f555bc1a171e441a"}},{"ruleId":"D1","level":"warning","message":{"text":"campaign_roi_calculator.calculate_campaign_metrics (cyclomatic 34): campaign_roi_calculator.calculate_campaign_metrics has cyclomatic complexity 34 (threshold 15). To reduce it, split the body: these branches sit side by side rather than nested inside one another, so extracting each one on its own would leave a function per branch. Group the statements between the checks into named steps and move each step into its own function, so the body reads as a short sequence of named stages."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"marketing-skill/skills/campaign-analytics/scripts/campaign_roi_calculator.py"},"region":{"startLine":117}}}],"partialFingerprints":{"codehealthFindingId/v1":"4d54d6d5eb6bdbebbcee9e475f3252d114b16eb08647445e8a019c1e7c503d42"}},{"ruleId":"D1","level":"warning","message":{"text":"post_linter.lint (cyclomatic 34): post_linter.lint has cyclomatic complexity 34 (threshold 15). To reduce it, split the body: these branches sit side by side rather than nested inside one another, so extracting each one on its own would leave a function per branch. Group the statements between the checks into named steps and move each step into its own function, so the body reads as a short sequence of named stages."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"marketing/linkedin/skills/linkedin-content/scripts/post_linter.py"},"region":{"startLine":117}}}],"partialFingerprints":{"codehealthFindingId/v1":"3fcf9385bc3a1fe31258d07edca346cb13fdcfa0a2eede2e032a195a3b6d3cc1"}},{"ruleId":"D1","level":"warning","message":{"text":"compose_validator.parse_yaml_simple (cyclomatic 33): compose_validator.parse_yaml_simple 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":"engineering/docker-development/skills/docker-development/scripts/compose_validator.py"},"region":{"startLine":59}}}],"partialFingerprints":{"codehealthFindingId/v1":"098eb7619cf655f2dcb5fd425769d95b50b0900b57ac0ee667cf762bb9f25f17"}},{"ruleId":"D1","level":"warning","message":{"text":"score_aggregator.validate (cyclomatic 33): score_aggregator.validate 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":"engineering/skill-doctor/skills/skill-doctor/scripts/score_aggregator.py"},"region":{"startLine":114}}}],"partialFingerprints":{"codehealthFindingId/v1":"f99468703f1e204c60defdb55165f6852384d8db43df5d8af124aaeec4ed513b"}},{"ruleId":"D1","level":"warning","message":{"text":"positioning_brief.validate (cyclomatic 33): positioning_brief.validate 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":"marketing/linkedin/skills/linkedin-strategy/scripts/positioning_brief.py"},"region":{"startLine":117}}}],"partialFingerprints":{"codehealthFindingId/v1":"93615b2386716c5edd184d9c8f666c6984462ffada3bed77da6ae5a3b715cc9c"}},{"ruleId":"D1","level":"warning","message":{"text":"cloud_posture_check.check_s3_policy (cyclomatic 32): cloud_posture_check.check_s3_policy 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":"engineering-team/skills/cloud-security/scripts/cloud_posture_check.py"},"region":{"startLine":518}}}],"partialFingerprints":{"codehealthFindingId/v1":"f5db03286716381370abe6721528f87179656058ff4bb5708f3111135c6e1662"}},{"ruleId":"D1","level":"warning","message":{"text":"validate_examples.main (cyclomatic 32): validate_examples.main 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":"engineering/agent-memory/skills/agent-memory/scripts/validate_examples.py"},"region":{"startLine":195}}}],"partialFingerprints":{"codehealthFindingId/v1":"d9dba6a6c444de67823d973fa3c1cef630fdf0fe04ba78288c0c411b6bf6fc28"}},{"ruleId":"D1","level":"warning","message":{"text":"score.run_segmented_scorecard (cyclomatic 32): score.run_segmented_scorecard 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":"finance/skills/stock-analysis/scripts/score.py"},"region":{"startLine":1110}}}],"partialFingerprints":{"codehealthFindingId/v1":"7a8ccd6bcf9e916cfd2278eb849f9eab660116cbe7b543463db44a01ce63b74c"}},{"ruleId":"D1","level":"warning","message":{"text":"ship_gate_scanner.detect_stack (cyclomatic 31): ship_gate_scanner.detect_stack 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":"engineering/skills/ship-gate/scripts/ship_gate_scanner.py"},"region":{"startLine":227}}}],"partialFingerprints":{"codehealthFindingId/v1":"c4e2fb111a92ad39f0fe2f666dfe3bfbc4932f39970fa81fb26fc3dcc3c4699c"}},{"ruleId":"D1","level":"warning","message":{"text":"dataset_pipeline_builder.main (cyclomatic 30): dataset_pipeline_builder.main 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":"engineering-team/skills/senior-computer-vision/scripts/dataset_pipeline_builder.py"},"region":{"startLine":1506}}}],"partialFingerprints":{"codehealthFindingId/v1":"1002ce04c3ea8cf080d2531db71108dcdb7e33185c5e1006a907009a4ab5916d"}},{"ruleId":"D1","level":"warning","message":{"text":"threat_signal_analyzer.anomaly_mode (cyclomatic 30): threat_signal_analyzer.anomaly_mode 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":"engineering-team/skills/threat-detection/scripts/threat_signal_analyzer.py"},"region":{"startLine":262}}}],"partialFingerprints":{"codehealthFindingId/v1":"7c631ac1a234ca5f6b4e9595ee67e5c2b9493692ed0b145946e76dba291459c3"}},{"ruleId":"D1","level":"warning","message":{"text":"chart_analyzer.check_security (cyclomatic 30): chart_analyzer.check_security 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":"engineering/helm-chart-builder/skills/helm-chart-builder/scripts/chart_analyzer.py"},"region":{"startLine":331}}}],"partialFingerprints":{"codehealthFindingId/v1":"98d06491b73e6f20b2cb5fcb81549c6cb8a62c0c4259b152d9c7c70d249a943e"}},{"ruleId":"D1","level":"warning","message":{"text":"valuation.render_text (cyclomatic 30): valuation.render_text 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":"finance/skills/stock-analysis/scripts/valuation.py"},"region":{"startLine":648}}}],"partialFingerprints":{"codehealthFindingId/v1":"6cad8c9c7a00bca0bfd59d23cf8fb21b5ebdf678ad0f157d70e1aa7fbde8b7fd"}},{"ruleId":"D1","level":"warning","message":{"text":"health_scorer.print_dashboard (cyclomatic 28): health_scorer.print_dashboard 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":"c-level-advisor/skills/org-health-diagnostic/scripts/health_scorer.py"},"region":{"startLine":337}}}],"partialFingerprints":{"codehealthFindingId/v1":"381d093ff886bcf400e9584952c5a8e10e4fadaffdaababee14f6e556945ea35"}},{"ruleId":"D1","level":"warning","message":{"text":"cloud_posture_check.main (cyclomatic 28): cloud_posture_check.main 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":"engineering-team/skills/cloud-security/scripts/cloud_posture_check.py"},"region":{"startLine":967}}}],"partialFingerprints":{"codehealthFindingId/v1":"c12f07ae8f1517d6b2384472fa7b7220aa64423553cd22c13db44ed167feef5e"}},{"ruleId":"D1","level":"warning","message":{"text":"version_bumper.main (cyclomatic 28): version_bumper.main 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":"engineering/skills/changelog-generator/scripts/version_bumper.py"},"region":{"startLine":467}}}],"partialFingerprints":{"codehealthFindingId/v1":"0c39ff663cc7751fb900b61c9e3afcf06dda9c684bbf14ead6f7dd43fe5e7130"}},{"ruleId":"D1","level":"warning","message":{"text":"repurpose_splitter.main (cyclomatic 28): repurpose_splitter.main 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":"marketing/linkedin/skills/linkedin-content/scripts/repurpose_splitter.py"},"region":{"startLine":196}}}],"partialFingerprints":{"codehealthFindingId/v1":"b37c43885d6a322d334883fb046fc2713de247513beb5c9fcc5347e20e663f50"}},{"ruleId":"D1","level":"warning","message":{"text":"time_block_planner.plan (cyclomatic 28): time_block_planner.plan 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":"productivity/deep-work/skills/deep-work/scripts/time_block_planner.py"},"region":{"startLine":86}}}],"partialFingerprints":{"codehealthFindingId/v1":"df252b586f290f45f65d2ec6495b3206d17f2c4a7c2e3a757953ed9b9b5cad4e"}},{"ruleId":"D1","level":"warning","message":{"text":"ops_efficiency_analyzer.format_report (cyclomatic 27): ops_efficiency_analyzer.format_report 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":"c-level-advisor/skills/coo-advisor/scripts/ops_efficiency_analyzer.py"},"region":{"startLine":607}}}],"partialFingerprints":{"codehealthFindingId/v1":"9f8e739e028a09bb59b656e3224f14995d0edd8d6512c43b878c8f04f91ce26a"}},{"ruleId":"D1","level":"warning","message":{"text":"churn_analyzer.print_full_report (cyclomatic 27): churn_analyzer.print_full_report 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":"c-level-advisor/skills/cro-advisor/scripts/churn_analyzer.py"},"region":{"startLine":441}}}],"partialFingerprints":{"codehealthFindingId/v1":"e85812021ed92e0414d1e05d67828defcfce32bb24412d129e7075af47dcaea6"}},{"ruleId":"D1","level":"warning","message":{"text":"revenue_forecast_model.print_report (cyclomatic 27): revenue_forecast_model.print_report 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":"c-level-advisor/skills/cro-advisor/scripts/revenue_forecast_model.py"},"region":{"startLine":295}}}],"partialFingerprints":{"codehealthFindingId/v1":"a9273d4c1adad269cd54c3e917f24d7acb79d7aa902c56901c72e3e9fa8f0e5c"}},{"ruleId":"D1","level":"warning","message":{"text":"contrast_checker.main (cyclomatic 27): contrast_checker.main 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":"engineering-team/a11y-audit/skills/a11y-audit/scripts/contrast_checker.py"},"region":{"startLine":364}}}],"partialFingerprints":{"codehealthFindingId/v1":"246e1356f234e20b88247ca0a976ebf4157b119fe7f49985f7a02f0d84b1e798"}},{"ruleId":"D1","level":"warning","message":{"text":"auth_setup_guide.main (cyclomatic 27): auth_setup_guide.main 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":"engineering-team/google-workspace-cli/skills/google-workspace-cli/scripts/auth_setup_guide.py"},"region":{"startLine":281}}}],"partialFingerprints":{"codehealthFindingId/v1":"6503d2526307fc204d06f8a77fb0d3a20a7c19c52f3797dd8cc86ac9b8365e20"}},{"ruleId":"D1","level":"warning","message":{"text":"SchemaValidator._validate_column (cyclomatic 27): SchemaValidator._validate_column 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":"engineering-team/skills/senior-data-engineer/scripts/data_quality_validator.py"},"region":{"startLine":279}}}],"partialFingerprints":{"codehealthFindingId/v1":"b0b3b67cf08b538c6b989adb34be09f5718d36a208d6131b3eed8bcd7cfda183"}},{"ruleId":"D1","level":"warning","message":{"text":"citation_tracker.main (cyclomatic 27): citation_tracker.main 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":"research/pulse/skills/pulse/scripts/citation_tracker.py"},"region":{"startLine":471}}}],"partialFingerprints":{"codehealthFindingId/v1":"8ec38af3edaff8e8d42014528b98fea62899defa1a6b5e5c4600ab564851e671"}},{"ruleId":"D1","level":"warning","message":{"text":"revshare_modeler.model (cyclomatic 26): revshare_modeler.model 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":"commercial/skills/partnerships-architect/scripts/revshare_modeler.py"},"region":{"startLine":139}}}],"partialFingerprints":{"codehealthFindingId/v1":"11d8da315be1ca3a40654965023f8fc5b08ed0e58e7011b73cb437be85f6b362"}},{"ruleId":"D1","level":"warning","message":{"text":"tc_status.render_single (cyclomatic 26): tc_status.render_single 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":"engineering/skills/tc-tracker/scripts/tc_status.py"},"region":{"startLine":39}}}],"partialFingerprints":{"codehealthFindingId/v1":"0414e76e223e9ab6dbd0ad0e2af6832d035616daf4a7cce2cc3b5491e2d5c0eb"}},{"ruleId":"D1","level":"warning","message":{"text":"UserService.create_user (cyclomatic 26): UserService.create_user 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":"engineering/skills/tech-debt-tracker/assets/sample_codebase/src/user_service.py"},"region":{"startLine":24}}}],"partialFingerprints":{"codehealthFindingId/v1":"52164be656fb3728e76cfea284e0cd2d08f5210da71bd9ba0edb5b7de784e365"}},{"ruleId":"D1","level":"warning","message":{"text":"Period._derive (cyclomatic 26): Period._derive has cyclomatic complexity 26 (threshold 15). To reduce it, split the body: these branches sit side by side rather than nested inside one another, so extracting each one on its own would leave a function per branch. Group the statements between the checks into named steps and move each step into its own function, so the body reads as a short sequence of named stages."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"finance/skills/stock-analysis/scripts/ratios.py"},"region":{"startLine":507}}}],"partialFingerprints":{"codehealthFindingId/v1":"21757cc49f47293c52816676ce732630e92d21d8221aa6bc36543da8e5c37d2d"}},{"ruleId":"D1","level":"warning","message":{"text":"score.main (cyclomatic 26): score.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":"finance/skills/stock-analysis/scripts/score.py"},"region":{"startLine":1983}}}],"partialFingerprints":{"codehealthFindingId/v1":"4a536620d7caa769e3549539414a66f835ededa4476ff485dccc903c52caea73"}},{"ruleId":"D1","level":"warning","message":{"text":"sitemap_analyzer.print_report (cyclomatic 26): sitemap_analyzer.print_report 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":"marketing-skill/skills/site-architecture/scripts/sitemap_analyzer.py"},"region":{"startLine":236}}}],"partialFingerprints":{"codehealthFindingId/v1":"b9656fc68691652247635febc73e6875468dec978ff75943e29639dd5f82845c"}},{"ruleId":"D1","level":"warning","message":{"text":"headline_scorer.score_headline (cyclomatic 26): headline_scorer.score_headline has cyclomatic complexity 26 (threshold 15). To reduce it, split the body: these branches sit side by side rather than nested inside one another, so extracting each one on its own would leave a function per branch. Group the statements between the checks into named steps and move each step into its own function, so the body reads as a short sequence of named stages."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"marketing/linkedin/skills/linkedin-profile/scripts/headline_scorer.py"},"region":{"startLine":103}}}],"partialFingerprints":{"codehealthFindingId/v1":"bed67349640b146e310ac78c45fcb8cb3021605ccb0756d447a2667321ed35ab"}},{"ruleId":"D1","level":"warning","message":{"text":"kb_validator.validate (cyclomatic 26): kb_validator.validate has cyclomatic complexity 26 (threshold 15). To reduce it, split the body: these branches sit side by side rather than nested inside one another, so extracting each one on its own would leave a function per branch. Group the statements between the checks into named steps and move each step into its own function, so the body reads as a short sequence of named stages."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"productivity/email/skills/inbox-setup/scripts/kb_validator.py"},"region":{"startLine":114}}}],"partialFingerprints":{"codehealthFindingId/v1":"1ec1d2ae523a8e7cb058111a4893db893454b371866f3ca1d5e89a89b9b77257"}},{"ruleId":"D1","level":"warning","message":{"text":"sync-gemini-skills.find_skills (cyclomatic 26): sync-gemini-skills.find_skills 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/sync-gemini-skills.py"},"region":{"startLine":44}}}],"partialFingerprints":{"codehealthFindingId/v1":"0723e4d3555a8b0885f7702ab6577fc578097152521bcf7e5f4da3919a3758a7"}},{"ruleId":"D1","level":"warning","message":{"text":"decision_tracker.parse_decisions (cyclomatic 25): decision_tracker.parse_decisions 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":"c-level-advisor/skills/decision-logger/scripts/decision_tracker.py"},"region":{"startLine":141}}}],"partialFingerprints":{"codehealthFindingId/v1":"6a5da5c418bd9e6ec2ad01082c056898644f1c9c53b0721b5d604849e6d7e7b3"}},{"ruleId":"D1","level":"warning","message":{"text":"bookings_forecaster.compute_forecast (cyclomatic 25): bookings_forecaster.compute_forecast 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":"commercial/skills/commercial-forecaster/scripts/bookings_forecaster.py"},"region":{"startLine":197}}}],"partialFingerprints":{"codehealthFindingId/v1":"66e603017343e913aadcba6a3875e8debbcae086c096a0dc43f9991e2ebb84f9"}},{"ruleId":"D1","level":"warning","message":{"text":"AgentEvaluator.calculate_performance_metrics (cyclomatic 25): AgentEvaluator.calculate_performance_metrics 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":"engineering/skills/agent-designer/agent_evaluator.py"},"region":{"startLine":259}}}],"partialFingerprints":{"codehealthFindingId/v1":"acdec38cb0512fab9aaec609d6264e35c2600de31edcb9e885369d5908f5eb5f"}},{"ruleId":"D1","level":"warning","message":{"text":"ship_gate_scanner.print_report (cyclomatic 25): ship_gate_scanner.print_report 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":"engineering/skills/ship-gate/scripts/ship_gate_scanner.py"},"region":{"startLine":1031}}}],"partialFingerprints":{"codehealthFindingId/v1":"96485cfff76b83637a0ca95a5fc7d149343322b1ea8fec5f343bbea6575583fe"}},{"ruleId":"D1","level":"warning","message":{"text":"html_renderer._render_block (cyclomatic 25): html_renderer._render_block 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":"markdown-html/skills/md-document/scripts/html_renderer.py"},"region":{"startLine":404}}}],"partialFingerprints":{"codehealthFindingId/v1":"f5648e035665b02c12cbe7a7c7eb327a6d2d3f61d6efce026e9ee4a1843c7880"}},{"ruleId":"D1","level":"warning","message":{"text":"deck_html_renderer._render_block (cyclomatic 25): deck_html_renderer._render_block 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":"markdown-html/skills/md-slides/scripts/deck_html_renderer.py"},"region":{"startLine":94}}}],"partialFingerprints":{"codehealthFindingId/v1":"ec385feb56fd9841c7fa6e3039a4b6e5fb1cc1f4ae2abe046762102c99ce884e"}},{"ruleId":"D1","level":"warning","message":{"text":"handoff_self_check.check (cyclomatic 25): handoff_self_check.check 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":"productivity/handoff/skills/handoff/scripts/handoff_self_check.py"},"region":{"startLine":165}}}],"partialFingerprints":{"codehealthFindingId/v1":"3541dcea88e3f83c8ea3d819840cc0cf952199b46caebc242ea1596416961114"}},{"ruleId":"D1","level":"warning","message":{"text":"source_tier_classifier.classify (cyclomatic 25): source_tier_classifier.classify 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":"research/dossier/skills/dossier/scripts/source_tier_classifier.py"},"region":{"startLine":125}}}],"partialFingerprints":{"codehealthFindingId/v1":"1b22871ac0ef1c9f9318b70583febf9c78111f3c309bb6136c66c206f7a7046b"}},{"ruleId":"D1","level":"warning","message":{"text":"adr_scanner.scan_directory (cyclomatic 24): adr_scanner.scan_directory 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":"engineering/grill-with-docs/skills/grill-with-docs/scripts/adr_scanner.py"},"region":{"startLine":87}}}],"partialFingerprints":{"codehealthFindingId/v1":"ce4e57b5caf29b2524e4ee22392580700a08e1be29269095a2a05aa01a78e5a8"}},{"ruleId":"D1","level":"warning","message":{"text":"lint_wiki.scan (cyclomatic 24): lint_wiki.scan 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":"engineering/llm-wiki/skills/llm-wiki/scripts/lint_wiki.py"},"region":{"startLine":44}}}],"partialFingerprints":{"codehealthFindingId/v1":"d8fb516643056cc06051c095dcf031a5830296b273ba86f0b24443c6167b3f88"}},{"ruleId":"D1","level":"warning","message":{"text":"valuation.scenario_value (cyclomatic 24): valuation.scenario_value 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":"finance/skills/stock-analysis/scripts/valuation.py"},"region":{"startLine":491}}}],"partialFingerprints":{"codehealthFindingId/v1":"9c6e6a262c2e7ccc3472f919a07591465e6c2d1b85543b01e30d6f26004f35db"}},{"ruleId":"D1","level":"warning","message":{"text":"form_field_analyzer.analyze_form (cyclomatic 24): form_field_analyzer.analyze_form 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":"marketing-skill/skills/form-cro/scripts/form_field_analyzer.py"},"region":{"startLine":108}}}],"partialFingerprints":{"codehealthFindingId/v1":"2f15a9e7557d1017e66064addb79824ca83590b608a085672edf11675d7b769a"}},{"ruleId":"D1","level":"warning","message":{"text":"seo_health_scorer.score_checks (cyclomatic 24): seo_health_scorer.score_checks 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":"marketing-skill/skills/seo-audit/scripts/seo_health_scorer.py"},"region":{"startLine":109}}}],"partialFingerprints":{"codehealthFindingId/v1":"30b7d36d1681b04d97c10d0038e0f4ac78a2695c8885e9fba97c5cacf53f0d82"}},{"ruleId":"D1","level":"warning","message":{"text":"gtm_efficiency_calculator.rate_metric (cyclomatic 23): gtm_efficiency_calculator.rate_metric 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":"business-growth/skills/revenue-operations/scripts/gtm_efficiency_calculator.py"},"region":{"startLine":75}}}],"partialFingerprints":{"codehealthFindingId/v1":"10c4941d1eb21e828a4f724616fcc67e8c9fd70e9ba59414625afa678b7fbfec"}},{"ruleId":"D1","level":"warning","message":{"text":"comms_calendar_builder.build_calendar (cyclomatic 23): comms_calendar_builder.build_calendar 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":"business-operations/skills/internal-comms/scripts/comms_calendar_builder.py"},"region":{"startLine":78}}}],"partialFingerprints":{"codehealthFindingId/v1":"5c7325d9bbe16df94dbb6a0a96af1713a6e10325cd7a40f6136ae67f62ccee2b"}},{"ruleId":"D1","level":"warning","message":{"text":"vendor_risk_classifier.classify_regulatory_exposure (cyclomatic 23): vendor_risk_classifier.classify_regulatory_exposure 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":"business-operations/skills/vendor-management/scripts/vendor_risk_classifier.py"},"region":{"startLine":127}}}],"partialFingerprints":{"codehealthFindingId/v1":"c186fd8a11064f3ed059c04c5672a2c7799d55ab1b375192a454554b7ae15c4b"}},{"ruleId":"D1","level":"warning","message":{"text":"cloud_posture_check.check_security_group (cyclomatic 23): cloud_posture_check.check_security_group 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":"engineering-team/skills/cloud-security/scripts/cloud_posture_check.py"},"region":{"startLine":724}}}],"partialFingerprints":{"codehealthFindingId/v1":"1830643aff999192fae7b4575fea65ddb890d0e5b47894299355f58cab2c6f49"}},{"ruleId":"D1","level":"warning","message":{"text":"book_skill_validator.check_frontmatter (cyclomatic 23): book_skill_validator.check_frontmatter 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":"engineering/book-to-skill/skills/book-to-skill/scripts/book_skill_validator.py"},"region":{"startLine":288}}}],"partialFingerprints":{"codehealthFindingId/v1":"cb0d4c300e951e5b7ced7a82ba4dc8d018e41d303c252dadf69442d8631250e3"}},{"ruleId":"D1","level":"warning","message":{"text":"dependencies.run_dependency_check (cyclomatic 23): dependencies.run_dependency_check 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":"engineering/book-to-skill/skills/book-to-skill/scripts/book_to_skill/dependencies.py"},"region":{"startLine":236}}}],"partialFingerprints":{"codehealthFindingId/v1":"247a66a08c3ec7d53724d6c9b0d5aa67294ec10b14010229649826f209c80bf4"}},{"ruleId":"D1","level":"warning","message":{"text":"values_validator.parse_values (cyclomatic 23): values_validator.parse_values 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":"engineering/helm-chart-builder/skills/helm-chart-builder/scripts/values_validator.py"},"region":{"startLine":78}}}],"partialFingerprints":{"codehealthFindingId/v1":"ac80926eed4830cd7cbc28ab29329d9cf79b7a093c79d35eafb34ee73b392eb8"}},{"ruleId":"D1","level":"warning","message":{"text":"score_aggregator.main (cyclomatic 23): score_aggregator.main 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":"engineering/skill-doctor/skills/skill-doctor/scripts/score_aggregator.py"},"region":{"startLine":289}}}],"partialFingerprints":{"codehealthFindingId/v1":"cb29375919bc472ad68718bf1799611e8b14dbce0fdde0d2ae184f0914890e23"}},{"ruleId":"D1","level":"warning","message":{"text":"ship_gate_scanner.main (cyclomatic 23): ship_gate_scanner.main 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":"engineering/skills/ship-gate/scripts/ship_gate_scanner.py"},"region":{"startLine":1147}}}],"partialFingerprints":{"codehealthFindingId/v1":"eb04c3ece09738d136629a2ab3e8a026937dff5c34aa7fea6a380e4de5b9ba12"}},{"ruleId":"D1","level":"warning","message":{"text":"review_html_renderer.render (cyclomatic 23): review_html_renderer.render 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":"markdown-html/skills/md-review/scripts/review_html_renderer.py"},"region":{"startLine":395}}}],"partialFingerprints":{"codehealthFindingId/v1":"564924378dae70d60480d31c7c0f86595f46c1e7ecd5bef146329a68eef9d320"}},{"ruleId":"D1","level":"warning","message":{"text":"outreach_message_builder.validate (cyclomatic 23): outreach_message_builder.validate 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":"marketing/linkedin/skills/linkedin-engagement/scripts/outreach_message_builder.py"},"region":{"startLine":92}}}],"partialFingerprints":{"codehealthFindingId/v1":"d8bc68412b8ddbc03aed8be83a9914833a345baad59f0faceb248aed07f906a6"}},{"ruleId":"D1","level":"warning","message":{"text":"codebase_analyzer.format_markdown (cyclomatic 23): codebase_analyzer.format_markdown 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":"product-team/code-to-prd/skills/code-to-prd/scripts/codebase_analyzer.py"},"region":{"startLine":622}}}],"partialFingerprints":{"codehealthFindingId/v1":"478662d0aefe7d4b9c0f607cbe9904c66fcf42957f1e749c8f1cb5b3c7b62aa9"}},{"ruleId":"D1","level":"warning","message":{"text":"sync-codex-skills.main (cyclomatic 23): sync-codex-skills.main 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":"scripts/sync-codex-skills.py"},"region":{"startLine":357}}}],"partialFingerprints":{"codehealthFindingId/v1":"8addc320a901569a349a3bf5a5a3fc5027dc492a8bd30d52ee68bbadbb7ba876"}},{"ruleId":"D1","level":"warning","message":{"text":"UserInterface.renderUserDashboard (cyclomatic 23): UserInterface.renderUserDashboard has cyclomatic complexity 23 (threshold 15). Of this number, 18 points are the body\u0027s own statements and 5 belong to one function literal inside it that branches. To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/tech-debt-tracker/assets/sample_codebase/src/frontend.js"},"region":{"startLine":59}}}],"partialFingerprints":{"codehealthFindingId/v1":"44b9dc880521cca22b69098174175410a37f751a790fafc854b9eee537ffb198"}},{"ruleId":"D1","level":"warning","message":{"text":"renderUserDashboard (cyclomatic 23): renderUserDashboard has cyclomatic complexity 23 (threshold 15). Of this number, 18 points are the body\u0027s own statements and 5 belong to one function literal inside it that branches. To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":".codex/skills/tech-debt-tracker/assets/sample_codebase/src/frontend.js"},"region":{"startLine":59}}}],"partialFingerprints":{"codehealthFindingId/v1":"0398c7cbef101d1ab46ce1dc20d8d310604546fc6ef560a9944595d337708478"}},{"ruleId":"D1","level":"warning","message":{"text":"renderUserDashboard (cyclomatic 23): renderUserDashboard has cyclomatic complexity 23 (threshold 15). Of this number, 18 points are the body\u0027s own statements and 5 belong to one function literal inside it that branches. To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":".vibe/skills/claude-skills/engineering/tech-debt-tracker/assets/sample_codebase/src/frontend.js"},"region":{"startLine":59}}}],"partialFingerprints":{"codehealthFindingId/v1":"a1c5b9182bc00b01c14a5e5fc604bfcfb06063da1dd370941f3630e0a30fc464"}},{"ruleId":"D1","level":"warning","message":{"text":"renderUserDashboard (cyclomatic 23): renderUserDashboard has cyclomatic complexity 23 (threshold 15). Of this number, 18 points are the body\u0027s own statements and 5 belong to one function literal inside it that branches. To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":".hermes/skills/claude-skills/engineering/tech-debt-tracker/assets/sample_codebase/src/frontend.js"},"region":{"startLine":59}}}],"partialFingerprints":{"codehealthFindingId/v1":"827f7217bfb5f635ba75e88ef5f5a98f7bce4e7f653bca0976c0c277f9e94ab4"}},{"ruleId":"D1","level":"warning","message":{"text":"deployment_builder.main (cyclomatic 22): deployment_builder.main 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":"agent-launcher/skills/run-without-you/scripts/deployment_builder.py"},"region":{"startLine":58}}}],"partialFingerprints":{"codehealthFindingId/v1":"0d56efffae83d807c5d62164f20784b5f5ef2f6fda9ff9cc36e0cb2275117a44"}},{"ruleId":"D1","level":"warning","message":{"text":"okf_linter.lint (cyclomatic 22): okf_linter.lint 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":"c-level-advisor/arquiteto-de-empresa/skills/arquiteto-de-empresa/scripts/okf_linter.py"},"region":{"startLine":55}}}],"partialFingerprints":{"codehealthFindingId/v1":"8bdaadc39e5eb8ade856ee5345943899ef203a51cf431b0a435679a41ba8623d"}},{"ruleId":"D1","level":"warning","message":{"text":"okf_linter.lint (cyclomatic 22): okf_linter.lint 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":"c-level-advisor/skills/arquiteto-de-empresa/scripts/okf_linter.py"},"region":{"startLine":55}}}],"partialFingerprints":{"codehealthFindingId/v1":"d838478cae9564d55ba761bfa8cc18a6943400adf38cc8440c6289993ea32b60"}},{"ruleId":"D1","level":"warning","message":{"text":"incident_triage.main (cyclomatic 22): incident_triage.main has cyclomatic complexity 22 (threshold 15). To reduce it, split the body: these branches sit side by side rather than nested inside one another, so extracting each one on its own would leave a function per branch. Group the statements between the checks into named steps and move each step into its own function, so the body reads as a short sequence of named stages."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/skills/incident-response/scripts/incident_triage.py"},"region":{"startLine":600}}}],"partialFingerprints":{"codehealthFindingId/v1":"c1ba72db720bf11d6ac7ef41a4abd39fb41315ad5811a747d066217d62071014"}},{"ruleId":"D1","level":"warning","message":{"text":"engagement_planner.build_engagement_plan (cyclomatic 22): engagement_planner.build_engagement_plan 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":"engineering-team/skills/red-team/scripts/engagement_planner.py"},"region":{"startLine":137}}}],"partialFingerprints":{"codehealthFindingId/v1":"5c29b50bfa928566e11f00173b21625880c9fc47aa372396a576ed8aa6b73e98"}},{"ruleId":"D1","level":"warning","message":{"text":"backend_decision_engine.render_markdown (cyclomatic 22): backend_decision_engine.render_markdown has cyclomatic complexity 22 (threshold 15). To reduce it, break up the iteration: give each loop body a named function, and split a multi-phase loop into one function per phase so no single body carries the whole pipeline."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/skills/senior-backend/scripts/backend_decision_engine.py"},"region":{"startLine":191}}}],"partialFingerprints":{"codehealthFindingId/v1":"f876cec3d7a9549ac9fb73359d7df22c1ccd71311eb4fcac088f7054c865dc5f"}},{"ruleId":"D1","level":"warning","message":{"text":"code_quality_analyzer.analyze_project (cyclomatic 22): code_quality_analyzer.analyze_project 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":"engineering-team/skills/senior-fullstack/scripts/code_quality_analyzer.py"},"region":{"startLine":334}}}],"partialFingerprints":{"codehealthFindingId/v1":"45840fcfa8d6ff6662e0d4a331b453312036f200213a55152263c2106aa8e295"}},{"ruleId":"D1","level":"warning","message":{"text":"rag_evaluator.evaluate_rag_system (cyclomatic 22): rag_evaluator.evaluate_rag_system 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":"engineering-team/skills/senior-prompt-engineer/scripts/rag_evaluator.py"},"region":{"startLine":343}}}],"partialFingerprints":{"codehealthFindingId/v1":"99351c2309bfe73c9c3b10664400fe69530ccbf53c46838bade6e12afb21b6af"}},{"ruleId":"D1","level":"warning","message":{"text":"memory_inspect.main (cyclomatic 22): memory_inspect.main 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":"engineering/agent-memory/skills/agent-memory/scripts/memory_inspect.py"},"region":{"startLine":170}}}],"partialFingerprints":{"codehealthFindingId/v1":"df781b53b7437b42bcc03a33f5cc6df43d2d3319453adb302e9e35f08d22705a"}},{"ruleId":"D1","level":"warning","message":{"text":"log_results.main (cyclomatic 22): log_results.main 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":"engineering/autoresearch-agent/skills/autoresearch-agent/scripts/log_results.py"},"region":{"startLine":316}}}],"partialFingerprints":{"codehealthFindingId/v1":"5ada0de761371438798e72a9b99be470c66886f0c97361f1c3c4f50ea56f1e7a"}},{"ruleId":"D1","level":"warning","message":{"text":"data_profiler.print_report (cyclomatic 22): data_profiler.print_report has cyclomatic complexity 22 (threshold 15). To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/data-quality-auditor/skills/data-quality-auditor/scripts/data_profiler.py"},"region":{"startLine":151}}}],"partialFingerprints":{"codehealthFindingId/v1":"e74965a7cd608529eb24871a41f07fbc41aed1cee637b52e85cd46b681f7d2fb"}},{"ruleId":"D1","level":"warning","message":{"text":"openapi_to_mcp.extract_tools (cyclomatic 22): openapi_to_mcp.extract_tools 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":"engineering/skills/mcp-server-builder/scripts/openapi_to_mcp.py"},"region":{"startLine":103}}}],"partialFingerprints":{"codehealthFindingId/v1":"088f73589ba45c5f5aebc184bddfeae0169459bf6a186535c42313a63207843b"}},{"ruleId":"D1","level":"warning","message":{"text":"audit_log_analyzer.analyze (cyclomatic 22): audit_log_analyzer.analyze 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":"engineering/skills/secrets-vault-manager/scripts/audit_log_analyzer.py"},"region":{"startLine":101}}}],"partialFingerprints":{"codehealthFindingId/v1":"2887f5f479cce492730168729ed6d8bee8034cfe2d07d3682dfe7840a8ee23e3"}},{"ruleId":"D1","level":"warning","message":{"text":"tc_create.main (cyclomatic 22): tc_create.main 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":"engineering/skills/tc-tracker/scripts/tc_create.py"},"region":{"startLine":146}}}],"partialFingerprints":{"codehealthFindingId/v1":"358d1b2d9d0330517a89f086a11484d5ed547536fc8d19da6f84531756f42155"}},{"ruleId":"D1","level":"warning","message":{"text":"metrics_calculator.calculate (cyclomatic 22): metrics_calculator.calculate 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":"finance/skills/saas-metrics-coach/scripts/metrics_calculator.py"},"region":{"startLine":19}}}],"partialFingerprints":{"codehealthFindingId/v1":"eb2f8d4ed293962b80de253dede91c7f29fb75868eae0443d59828b79c8957b7"}},{"ruleId":"D1","level":"warning","message":{"text":"lint_report.check_blank_cells (cyclomatic 22): lint_report.check_blank_cells 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":"finance/skills/stock-analysis/scripts/lint_report.py"},"region":{"startLine":629}}}],"partialFingerprints":{"codehealthFindingId/v1":"99994a772a9ae15118c7612eea2ea320c5896c7bb08620c2b6e32ac77b963025"}},{"ruleId":"D1","level":"warning","message":{"text":"score.apply_gates (cyclomatic 22): score.apply_gates 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":"finance/skills/stock-analysis/scripts/score.py"},"region":{"startLine":556}}}],"partialFingerprints":{"codehealthFindingId/v1":"46f9512dcf72dfafa7396cac3ba5a52ca76697a2c5ebf5fb7176ed963025fb71"}},{"ruleId":"D1","level":"warning","message":{"text":"campaign_roi_calculator.format_text (cyclomatic 22): campaign_roi_calculator.format_text 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":"marketing-skill/skills/campaign-analytics/scripts/campaign_roi_calculator.py"},"region":{"startLine":299}}}],"partialFingerprints":{"codehealthFindingId/v1":"9a85031157205f906aa1148823ab7a169b84cebeb00ce6ab7b9ce27d5231aa04"}},{"ruleId":"D1","level":"warning","message":{"text":"jql_query_builder.build_jql_from_description (cyclomatic 22): jql_query_builder.build_jql_from_description 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":"project-management/skills/jira-expert/scripts/jql_query_builder.py"},"region":{"startLine":209}}}],"partialFingerprints":{"codehealthFindingId/v1":"739a487be78c6f2f7f52c3649bb61568d1408de83873f8fceb3472df7c7ec3f7"}},{"ruleId":"D1","level":"warning","message":{"text":"resource_capacity_planner.optimize_resource_allocation (cyclomatic 22): resource_capacity_planner.optimize_resource_allocation 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":"project-management/skills/senior-pm/scripts/resource_capacity_planner.py"},"region":{"startLine":370}}}],"partialFingerprints":{"codehealthFindingId/v1":"b8210c5a6eef6f6a93b7706f0671a7792a1ba15e26047406337c726c53b780aa"}},{"ruleId":"D1","level":"warning","message":{"text":"qsr_compliance_checker.search_documentation (cyclomatic 22): qsr_compliance_checker.search_documentation 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":"ra-qm-team/skills/fda-consultant-specialist/scripts/qsr_compliance_checker.py"},"region":{"startLine":348}}}],"partialFingerprints":{"codehealthFindingId/v1":"f5505c4073a4c98436844dea1b61970c33c2bd62e08b0ec1277c87b50537a04b"}},{"ruleId":"D1","level":"warning","message":{"text":"ai_training_data_audit._decide (cyclomatic 21): ai_training_data_audit._decide 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":"c-level-advisor/chief-data-officer-advisor/skills/chief-data-officer-advisor/scripts/ai_training_data_audit.py"},"region":{"startLine":123}}}],"partialFingerprints":{"codehealthFindingId/v1":"5c2e0c9bc82fb3ebab563c17ecc9310a8e4160d1278833d3ee811baacf4500a1"}},{"ruleId":"D1","level":"warning","message":{"text":"ai_training_data_audit._decide (cyclomatic 21): ai_training_data_audit._decide 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":"c-level-advisor/skills/chief-data-officer-advisor/scripts/ai_training_data_audit.py"},"region":{"startLine":123}}}],"partialFingerprints":{"codehealthFindingId/v1":"f2aaec0cd9fbcf2b24502f90821f18095314e510f714f1d7201f476e45f4c6ca"}},{"ruleId":"D1","level":"warning","message":{"text":"framework_selector.select_frameworks (cyclomatic 21): framework_selector.select_frameworks has cyclomatic complexity 21 (threshold 15). To reduce it, split the body: these branches sit side by side rather than nested inside one another, so extracting each one on its own would leave a function per branch. Group the statements between the checks into named steps and move each step into its own function, so the body reads as a short sequence of named stages."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"compliance-os/skills/compliance-os/scripts/framework_selector.py"},"region":{"startLine":105}}}],"partialFingerprints":{"codehealthFindingId/v1":"e2e671bf3deb22cf9422359618df6f9a70d2975f968e1af4b63945af4d4a8918"}},{"ruleId":"D1","level":"warning","message":{"text":"output_analyzer.main (cyclomatic 21): output_analyzer.main has cyclomatic complexity 21 (threshold 15). To reduce it, split the body: these branches sit side by side rather than nested inside one another, so extracting each one on its own would leave a function per branch. Group the statements between the checks into named steps and move each step into its own function, so the body reads as a short sequence of named stages."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/google-workspace-cli/skills/google-workspace-cli/scripts/output_analyzer.py"},"region":{"startLine":228}}}],"partialFingerprints":{"codehealthFindingId/v1":"95c8cee6afadc55069e10fb65010e97a108da4fbd889c4be526a6a24b4158220"}},{"ruleId":"D1","level":"warning","message":{"text":"cloud_posture_check.analyze_statement (cyclomatic 21): cloud_posture_check.analyze_statement 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":"engineering-team/skills/cloud-security/scripts/cloud_posture_check.py"},"region":{"startLine":288}}}],"partialFingerprints":{"codehealthFindingId/v1":"ee3e20827bc01168d078757607f640ca13cb05241a3ddb6350e970c874697610"}},{"ruleId":"D1","level":"warning","message":{"text":"frontend_decision_engine.render_markdown (cyclomatic 21): frontend_decision_engine.render_markdown has cyclomatic complexity 21 (threshold 15). To reduce it, break up the iteration: give each loop body a named function, and split a multi-phase loop into one function per phase so no single body carries the whole pipeline."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/skills/senior-frontend/scripts/frontend_decision_engine.py"},"region":{"startLine":145}}}],"partialFingerprints":{"codehealthFindingId/v1":"34908fc76512de2c6b4b5fa51a62d91e61e98434eb7fd0fab196553e90cf83e4"}},{"ruleId":"D1","level":"warning","message":{"text":"fullstack_decision_engine.render_markdown (cyclomatic 21): fullstack_decision_engine.render_markdown has cyclomatic complexity 21 (threshold 15). To reduce it, break up the iteration: give each loop body a named function, and split a multi-phase loop into one function per phase so no single body carries the whole pipeline."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/skills/senior-fullstack/scripts/fullstack_decision_engine.py"},"region":{"startLine":187}}}],"partialFingerprints":{"codehealthFindingId/v1":"5bc451e0e48d7034590fd6fd6692c73ef2e343928606f9df6b19d92937273be6"}},{"ruleId":"D1","level":"warning","message":{"text":"CoverageParser._parse_lcov (cyclomatic 21): CoverageParser._parse_lcov 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":"engineering-team/skills/senior-qa/scripts/coverage_analyzer.py"},"region":{"startLine":200}}}],"partialFingerprints":{"codehealthFindingId/v1":"5f016c648930758a8473f9e8d5fa18b2cd96d21b447065cb4a7f13dd0a61c564"}},{"ruleId":"D1","level":"warning","message":{"text":"prompt_rater.rate (cyclomatic 21): prompt_rater.rate has cyclomatic complexity 21 (threshold 15). To reduce it, split the body: these branches sit side by side rather than nested inside one another, so extracting each one on its own would leave a function per branch. Group the statements between the checks into named steps and move each step into its own function, so the body reads as a short sequence of named stages."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/claude-coach/skills/claude-coach/scripts/prompt_rater.py"},"region":{"startLine":57}}}],"partialFingerprints":{"codehealthFindingId/v1":"61d7060cc51754d9d5e115047d4e6f2d0891217d75184e558acd85c97b9a65f4"}},{"ruleId":"D1","level":"warning","message":{"text":"review_page_builder.markdown_blocks (cyclomatic 21): review_page_builder.markdown_blocks has cyclomatic complexity 21 (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":"engineering/human-gate/skills/human-gate/scripts/review_page_builder.py"},"region":{"startLine":164}}}],"partialFingerprints":{"codehealthFindingId/v1":"c94a3487bb541426a5f9ebf6755d45748229cafccd696e4e812e647526826f9f"}},{"ruleId":"D1","level":"warning","message":{"text":"AgentPlanner.select_architecture_pattern (cyclomatic 21): AgentPlanner.select_architecture_pattern 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":"engineering/skills/agent-designer/agent_planner.py"},"region":{"startLine":207}}}],"partialFingerprints":{"codehealthFindingId/v1":"cf703bb8d637cbdf536dc3b62675d12dc106bc04d48f24e4c22f77db374f4192"}},{"ruleId":"D1","level":"warning","message":{"text":"stack_detector.detect (cyclomatic 21): stack_detector.detect has cyclomatic complexity 21 (threshold 15). To reduce it, split the body: these branches sit side by side rather than nested inside one another, so extracting each one on its own would leave a function per branch. Group the statements between the checks into named steps and move each step into its own function, so the body reads as a short sequence of named stages."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/ci-cd-pipeline-builder/scripts/stack_detector.py"},"region":{"startLine":75}}}],"partialFingerprints":{"codehealthFindingId/v1":"3f759b56c600162b08459f1e8d4881ca91194925fb3c7f408384964914aa78c4"}},{"ruleId":"D1","level":"warning","message":{"text":"skill_security_auditor.scan_dependencies (cyclomatic 21): skill_security_auditor.scan_dependencies 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":"engineering/skills/skill-security-auditor/scripts/skill_security_auditor.py"},"region":{"startLine":682}}}],"partialFingerprints":{"codehealthFindingId/v1":"14e3160a5d0aa0416bd209cb96a2c3904fe881825be96972595fc9344a4349c3"}},{"ruleId":"D1","level":"warning","message":{"text":"verify_data.render_text (cyclomatic 21): verify_data.render_text 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":"finance/skills/stock-analysis/scripts/verify_data.py"},"region":{"startLine":1452}}}],"partialFingerprints":{"codehealthFindingId/v1":"b9c9b5001f574af26c1945eafbc71f0c9750209f1326490d00a8796fc4697552"}},{"ruleId":"D1","level":"warning","message":{"text":"codebase_analyzer.detect_framework (cyclomatic 21): codebase_analyzer.detect_framework 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":"product-team/code-to-prd/skills/code-to-prd/scripts/codebase_analyzer.py"},"region":{"startLine":163}}}],"partialFingerprints":{"codehealthFindingId/v1":"3300c82e915a7f0e8f77ebac8e96b50de33a1a1b7df41a67bf900f749e794bb2"}},{"ruleId":"D1","level":"warning","message":{"text":"jira_snapshot_bridge.flow_report (cyclomatic 21): jira_snapshot_bridge.flow_report has cyclomatic complexity 21 (threshold 15). To reduce it, split the body: these branches sit side by side rather than nested inside one another, so extracting each one on its own would leave a function per branch. Group the statements between the checks into named steps and move each step into its own function, so the body reads as a short sequence of named stages."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"project-management/skills/pm-skills/scripts/jira_snapshot_bridge.py"},"region":{"startLine":116}}}],"partialFingerprints":{"codehealthFindingId/v1":"64dc26c9b4947f3e943d9780336a36e8a21463e4a6224d41362b0f278fc3c7e9"}},{"ruleId":"D1","level":"warning","message":{"text":"interview_planner.plan (cyclomatic 20): interview_planner.plan 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":"agent-launcher/skills/interview/scripts/interview_planner.py"},"region":{"startLine":38}}}],"partialFingerprints":{"codehealthFindingId/v1":"871292a4cca7016e0c4412ceb79a49fef159d2f575e22202bbcc994b7e3efc37"}},{"ruleId":"D1","level":"warning","message":{"text":"stakeholder_mapper.print_report (cyclomatic 20): stakeholder_mapper.print_report has cyclomatic complexity 20 (threshold 15). To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"c-level-advisor/executive-mentor/skills/executive-mentor/scripts/stakeholder_mapper.py"},"region":{"startLine":232}}}],"partialFingerprints":{"codehealthFindingId/v1":"1ee4826155d7a2affaf339111bfac85f8a95ccb41e686075fa3d8b3f0f47153a"}},{"ruleId":"D1","level":"warning","message":{"text":"packaging_designer.detect_anti_patterns (cyclomatic 20): packaging_designer.detect_anti_patterns 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":"commercial/skills/pricing-strategist/scripts/packaging_designer.py"},"region":{"startLine":107}}}],"partialFingerprints":{"codehealthFindingId/v1":"5c12ae52f03fecc4d2e60eaeffc6803de052319f61b31a905f009b1faa4c1ba0"}},{"ruleId":"D1","level":"warning","message":{"text":"engagement_planner.main (cyclomatic 20): engagement_planner.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":"engineering-team/skills/red-team/scripts/engagement_planner.py"},"region":{"startLine":283}}}],"partialFingerprints":{"codehealthFindingId/v1":"5846c7ad101eb10b352c2c0e4c970e840624b7e5650112a4cf8d08be1de577b4"}},{"ruleId":"D1","level":"warning","message":{"text":"epub.extract_with_zipfile (cyclomatic 20): epub.extract_with_zipfile 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":"engineering/book-to-skill/skills/book-to-skill/scripts/book_to_skill/parsers/epub.py"},"region":{"startLine":67}}}],"partialFingerprints":{"codehealthFindingId/v1":"47ae93af3c086875eeea87ff6b93a502e9cb111f83c0ad92eebadf97a4c1d7fc"}},{"ruleId":"D1","level":"warning","message":{"text":"context_md_linter.lint (cyclomatic 20): context_md_linter.lint 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":"engineering/grill-with-docs/skills/grill-with-docs/scripts/context_md_linter.py"},"region":{"startLine":110}}}],"partialFingerprints":{"codehealthFindingId/v1":"4a6ca7c46c9a7bf0de38e847afb8e4dc82d7c0da91b8f9bd12f81e74eb983237"}},{"ruleId":"D1","level":"warning","message":{"text":"IndexOptimizer.analyze_missing_indexes (cyclomatic 20): IndexOptimizer.analyze_missing_indexes 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":"engineering/skills/database-designer/index_optimizer.py"},"region":{"startLine":227}}}],"partialFingerprints":{"codehealthFindingId/v1":"b6a6079cd896aa5f70292397f2d5171fe83c4e3e244907336cd78c85bf17ac8c"}},{"ruleId":"D1","level":"warning","message":{"text":"ReportFormatter.format_human_readable (cyclomatic 20): ReportFormatter.format_human_readable 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":"engineering/skills/skill-tester/scripts/skill_validator.py"},"region":{"startLine":578}}}],"partialFingerprints":{"codehealthFindingId/v1":"1f3ba62612acb167e25346b49a1b5dce5a71e90ed3cce71b9d4fdf0d81c8106c"}},{"ruleId":"D1","level":"warning","message":{"text":"Analysis.build_ev_bridge (cyclomatic 20): Analysis.build_ev_bridge 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":"finance/skills/stock-analysis/scripts/ratios.py"},"region":{"startLine":1673}}}],"partialFingerprints":{"codehealthFindingId/v1":"826573ed146cd220992107064c5bc6e68fd867604908745c9d65724171ae5788"}},{"ruleId":"D1","level":"warning","message":{"text":"score.score_metric (cyclomatic 20): score.score_metric 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":"finance/skills/stock-analysis/scripts/score.py"},"region":{"startLine":364}}}],"partialFingerprints":{"codehealthFindingId/v1":"617a1084ab5e965150a74b3d6c18e6f684c47492cfb4e0135dbcf2b766777973"}},{"ruleId":"D1","level":"warning","message":{"text":"slide_splitter.split_slides (cyclomatic 20): slide_splitter.split_slides 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":"markdown-html/skills/md-slides/scripts/slide_splitter.py"},"region":{"startLine":76}}}],"partialFingerprints":{"codehealthFindingId/v1":"042404b30f05f354678dc56ed3df9f392ff0459bac1182a0e736bd9834ec6816"}},{"ruleId":"D1","level":"warning","message":{"text":"prompt_versioner.main (cyclomatic 20): prompt_versioner.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":"marketing-skill/skills/prompt-engineer-toolkit/scripts/prompt_versioner.py"},"region":{"startLine":126}}}],"partialFingerprints":{"codehealthFindingId/v1":"4bc024573b61f3d12a24d3dd80e6fb592162d8cef19697bf44307eabc235f537"}},{"ruleId":"D1","level":"warning","message":{"text":"OKRGenerator.generate_okr_dashboard (cyclomatic 20): OKRGenerator.generate_okr_dashboard has cyclomatic complexity 20 (threshold 15). To reduce it, break up the iteration: give each loop body a named function, and split a multi-phase loop into one function per phase so no single body carries the whole pipeline."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"product-team/skills/product-strategist/scripts/okr_cascade_generator.py"},"region":{"startLine":247}}}],"partialFingerprints":{"codehealthFindingId/v1":"f2119b3d3e77f47f2575ba7bad07ada2eeb99e0448cbc728b98f80ee0f482342"}},{"ruleId":"D1","level":"warning","message":{"text":"section_progress_tracker.main (cyclomatic 20): section_progress_tracker.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":"productivity/email/skills/inbox-setup/scripts/section_progress_tracker.py"},"region":{"startLine":199}}}],"partialFingerprints":{"codehealthFindingId/v1":"0a9b3d3818af92046c034cef11fb381252256ba68c5841fdc756d3d5ac407c76"}},{"ruleId":"D1","level":"warning","message":{"text":"directional_recommendation_validator.validate (cyclomatic 20): directional_recommendation_validator.validate 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":"productivity/reflect/skills/reflect/scripts/directional_recommendation_validator.py"},"region":{"startLine":91}}}],"partialFingerprints":{"codehealthFindingId/v1":"7a030b226dd4c88b1b6cf60d71e49f212c43244d97faae7b8d6048656daceffb"}},{"ruleId":"D1","level":"warning","message":{"text":"verdict_synthesizer.synthesize (cyclomatic 20): verdict_synthesizer.synthesize 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":"productivity/roast/skills/roast/scripts/verdict_synthesizer.py"},"region":{"startLine":60}}}],"partialFingerprints":{"codehealthFindingId/v1":"dbd41dd5cfd608bd2f4a68ec8339367d8533f8140248c4c268e12a153961f841"}},{"ruleId":"D1","level":"warning","message":{"text":"pipeline_analyzer.assess_pipeline_risk (cyclomatic 19): pipeline_analyzer.assess_pipeline_risk 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":"business-growth/skills/revenue-operations/scripts/pipeline_analyzer.py"},"region":{"startLine":203}}}],"partialFingerprints":{"codehealthFindingId/v1":"17d9a381d3c46dbfbd4aec798a7056ddbe793b13be7cb4b5a435a03821fa2994"}},{"ruleId":"D1","level":"warning","message":{"text":"portfolio_analyzer._product_findings (cyclomatic 19): portfolio_analyzer._product_findings 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":"c-level-advisor/skills/cpo-advisor/scripts/portfolio_analyzer.py"},"region":{"startLine":222}}}],"partialFingerprints":{"codehealthFindingId/v1":"82745736e1e71b8242a8c5601837f6e3f04d78bf8352d0157888c7f89a9d2c64"}},{"ruleId":"D1","level":"warning","message":{"text":"TimelineReconstructor._calculate_metrics (cyclomatic 19): TimelineReconstructor._calculate_metrics 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":"engineering-team/skills/incident-commander/scripts/timeline_reconstructor.py"},"region":{"startLine":423}}}],"partialFingerprints":{"codehealthFindingId/v1":"440d3ce76254eaeb15a9b6481ac7ed8fdc85a9562b0eb7f98b8288538b6a9442"}},{"ruleId":"D1","level":"warning","message":{"text":"MigrationGenerator._compare_tables (cyclomatic 19): MigrationGenerator._compare_tables 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":"engineering-team/skills/senior-backend/scripts/database_migration_tool.py"},"region":{"startLine":503}}}],"partialFingerprints":{"codehealthFindingId/v1":"bc8effb678763170d4810cc329266e2e0773761e5cd82cc8326d80e1ea1ce778"}},{"ruleId":"D1","level":"warning","message":{"text":"DataContractValidator.validate_contract (cyclomatic 19): DataContractValidator.validate_contract 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":"engineering-team/skills/senior-data-engineer/scripts/data_quality_validator.py"},"region":{"startLine":990}}}],"partialFingerprints":{"codehealthFindingId/v1":"4730541de07c857c8e2ca78beae4df7ec0e146c079ed5a96c092edad73799443"}},{"ruleId":"D1","level":"warning","message":{"text":"training_diagnostics.diagnose (cyclomatic 19): training_diagnostics.diagnose 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":"engineering/deep-learning-book/skills/deep-learning-book/scripts/training_diagnostics.py"},"region":{"startLine":70}}}],"partialFingerprints":{"codehealthFindingId/v1":"c7676fd9688b1ec9052d2f3068a7909b18146180ed8ad285aae649b06bbacd3a"}},{"ruleId":"D1","level":"warning","message":{"text":"ToolSchemaGenerator._generate_example_value (cyclomatic 19): ToolSchemaGenerator._generate_example_value 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":"engineering/skills/agent-designer/tool_schema_generator.py"},"region":{"startLine":699}}}],"partialFingerprints":{"codehealthFindingId/v1":"64c72d121019dca4869d26c52c5110b869e3a429d610e535d8b4c1da8edcfe0d"}},{"ruleId":"D1","level":"warning","message":{"text":"SelectivityEstimator.estimate_selectivity (cyclomatic 19): SelectivityEstimator.estimate_selectivity 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":"engineering/skills/database-designer/index_optimizer.py"},"region":{"startLine":113}}}],"partialFingerprints":{"codehealthFindingId/v1":"e4566f2d88b7c28df73b29e56cda9ce134fe8a7dc9d01d4a5f2dffaca3b6400d"}},{"ruleId":"D1","level":"warning","message":{"text":"hiring_calibrator.format_human_readable (cyclomatic 19): hiring_calibrator.format_human_readable 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":"engineering/skills/interview-system-designer/hiring_calibrator.py"},"region":{"startLine":1112}}}],"partialFingerprints":{"codehealthFindingId/v1":"29de2c215b0529a6decc80dfcdbae83273aca9bae2009c1d5aac4bd598faf51b"}},{"ruleId":"D1","level":"warning","message":{"text":"SchemaCompatibilityChecker._build_compatibility_report (cyclomatic 19): SchemaCompatibilityChecker._build_compatibility_report 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":"engineering/skills/migration-architect/scripts/compatibility_checker.py"},"region":{"startLine":667}}}],"partialFingerprints":{"codehealthFindingId/v1":"350e8214f33d6fac7e04a90720dc87a909648ac19ffbefe25e41a75c2b565246"}},{"ruleId":"D1","level":"warning","message":{"text":"RollbackGenerator.generate_human_readable_runbook (cyclomatic 19): RollbackGenerator.generate_human_readable_runbook has cyclomatic complexity 19 (threshold 15). To reduce it, break up the iteration: give each loop body a named function, and split a multi-phase loop into one function per phase so no single body carries the whole pipeline."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/migration-architect/scripts/rollback_generator.py"},"region":{"startLine":940}}}],"partialFingerprints":{"codehealthFindingId/v1":"3064fdc13978b877a1793a24c00830c377454a1f44f0bce8ee560a0ebf15820b"}},{"ruleId":"D1","level":"warning","message":{"text":"ratios.render_text (cyclomatic 19): ratios.render_text 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":"finance/skills/stock-analysis/scripts/ratios.py"},"region":{"startLine":2368}}}],"partialFingerprints":{"codehealthFindingId/v1":"1d232a92e229bde5a701818ec42beb1f6a8ee3e183a249a4adbbc8a255039016"}},{"ruleId":"D1","level":"warning","message":{"text":"score.aggregate (cyclomatic 19): score.aggregate 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":"finance/skills/stock-analysis/scripts/score.py"},"region":{"startLine":479}}}],"partialFingerprints":{"codehealthFindingId/v1":"abd7c71ab4299759cbf5c7b632f573caa224d97fd8f092026bac4ac464f52b6e"}},{"ruleId":"D1","level":"warning","message":{"text":"score.explain (cyclomatic 19): score.explain 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":"finance/skills/stock-analysis/scripts/score.py"},"region":{"startLine":1632}}}],"partialFingerprints":{"codehealthFindingId/v1":"02912fb5dd9504cb42577d06df9bd4374cd4ce3ea943d6fa623c98436a859253"}},{"ruleId":"D1","level":"warning","message":{"text":"verify_data._check_magnitude (cyclomatic 19): verify_data._check_magnitude 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":"finance/skills/stock-analysis/scripts/verify_data.py"},"region":{"startLine":1043}}}],"partialFingerprints":{"codehealthFindingId/v1":"6f43c54234d84f5bd44333792d2b3dee3cd48c40313a3ddc1a665335bfc94875"}},{"ruleId":"D1","level":"warning","message":{"text":"humanizer_scorer.print_report (cyclomatic 19): humanizer_scorer.print_report 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":"marketing-skill/skills/content-humanizer/scripts/humanizer_scorer.py"},"region":{"startLine":360}}}],"partialFingerprints":{"codehealthFindingId/v1":"9daeec8611660dc0780119a761f719a06a8d760d072e8cebb856dc8c4f963c7a"}},{"ruleId":"D1","level":"warning","message":{"text":"CROParser.handle_starttag (cyclomatic 19): CROParser.handle_starttag 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":"marketing-skill/skills/page-cro/scripts/conversion_audit.py"},"region":{"startLine":62}}}],"partialFingerprints":{"codehealthFindingId/v1":"e96205df2d6d90df46468238d731bbc5a36a3caad8841864dea1b0f3476af78a"}},{"ruleId":"D1","level":"warning","message":{"text":"pattern_miner.mine (cyclomatic 19): pattern_miner.mine 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":"marketing/linkedin/skills/linkedin-analytics/scripts/pattern_miner.py"},"region":{"startLine":146}}}],"partialFingerprints":{"codehealthFindingId/v1":"873ff4fb44972199b6406fa6ffd8a452953e8968f84caa088764bbb2a61bc05f"}},{"ruleId":"D1","level":"warning","message":{"text":"comment_target_planner.build (cyclomatic 19): comment_target_planner.build has cyclomatic complexity 19 (threshold 15). To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"marketing/linkedin/skills/linkedin-engagement/scripts/comment_target_planner.py"},"region":{"startLine":89}}}],"partialFingerprints":{"codehealthFindingId/v1":"8055c116539d3c581d9a4c1210cdc605a75677e1ba0036656f72bac38b2ab026"}},{"ruleId":"D1","level":"warning","message":{"text":"OKRGenerator.calculate_alignment_score (cyclomatic 19): OKRGenerator.calculate_alignment_score 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":"product-team/skills/product-strategist/scripts/okr_cascade_generator.py"},"region":{"startLine":304}}}],"partialFingerprints":{"codehealthFindingId/v1":"00518f0397625f06eaa5fac087cf66fefdca1b2db9c72170e9e7385270475cb0"}},{"ruleId":"D1","level":"warning","message":{"text":"retrospective_analyzer.analyze_action_item_completion (cyclomatic 19): retrospective_analyzer.analyze_action_item_completion 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":"project-management/skills/scrum-master/scripts/retrospective_analyzer.py"},"region":{"startLine":236}}}],"partialFingerprints":{"codehealthFindingId/v1":"222e06e7ae99b53ddc944e6d9f55954ad7912bd18938e36400fef2ea987c384b"}},{"ruleId":"D1","level":"warning","message":{"text":"project_health_dashboard.format_text_output (cyclomatic 19): project_health_dashboard.format_text_output 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":"project-management/skills/senior-pm/scripts/project_health_dashboard.py"},"region":{"startLine":635}}}],"partialFingerprints":{"codehealthFindingId/v1":"0f253df491794d74329f410721691e7de8d5ae02c4038825a6b72a8e7aed4803"}},{"ruleId":"D1","level":"warning","message":{"text":"resource_capacity_planner.format_text_output (cyclomatic 19): resource_capacity_planner.format_text_output has cyclomatic complexity 19 (threshold 15). To reduce it, break up the iteration: give each loop body a named function, and split a multi-phase loop into one function per phase so no single body carries the whole pipeline."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"project-management/skills/senior-pm/scripts/resource_capacity_planner.py"},"region":{"startLine":646}}}],"partialFingerprints":{"codehealthFindingId/v1":"f79a77c8935487aead1c891603a2503d7192a3061f7d040c263f0e21b7cbf139"}},{"ruleId":"D1","level":"warning","message":{"text":"CAPATracker.calculate_metrics (cyclomatic 19): CAPATracker.calculate_metrics 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":"ra-qm-team/skills/capa-officer/scripts/capa_tracker.py"},"region":{"startLine":114}}}],"partialFingerprints":{"codehealthFindingId/v1":"3e66eb03b77f0c5079bb609f21d1e1f70e7305589e402203a32afb645432dd74"}},{"ruleId":"D1","level":"warning","message":{"text":"gdpr_compliance_checker.analyze_project (cyclomatic 19): gdpr_compliance_checker.analyze_project 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":"ra-qm-team/skills/gdpr-dsgvo-expert/scripts/gdpr_compliance_checker.py"},"region":{"startLine":201}}}],"partialFingerprints":{"codehealthFindingId/v1":"191c977041076414ebee94824bed32daf3057fe015e2438941537e1cd7c76842"}},{"ruleId":"D1","level":"warning","message":{"text":"citation_tracker.main (cyclomatic 19): citation_tracker.main has cyclomatic complexity 19 (threshold 15). To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"research/litreview/skills/litreview/scripts/citation_tracker.py"},"region":{"startLine":200}}}],"partialFingerprints":{"codehealthFindingId/v1":"3539cfd12c42db0e63ed4eb7f1b398c36a25946a388b2295ffb0aaf9463e110e"}},{"ruleId":"D1","level":"warning","message":{"text":"check_frontmatter.check_file (cyclomatic 19): check_frontmatter.check_file 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":"scripts/check_frontmatter.py"},"region":{"startLine":109}}}],"partialFingerprints":{"codehealthFindingId/v1":"386d19cbe4d17df0ae122f2e62162965c0f452e469b82f97a64d774e92c95ba8"}},{"ruleId":"D1","level":"warning","message":{"text":"sync-hermes-skills.discover_skills (cyclomatic 19): sync-hermes-skills.discover_skills 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":"scripts/sync-hermes-skills.py"},"region":{"startLine":58}}}],"partialFingerprints":{"codehealthFindingId/v1":"47a7ec2cd3fd6b51b2c2ebe4b043756b0b050c6627b5e637916ee35904cbe0ed"}},{"ruleId":"D1","level":"warning","message":{"text":"sync-vibe-skills.discover_skills (cyclomatic 19): sync-vibe-skills.discover_skills 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":"scripts/sync-vibe-skills.py"},"region":{"startLine":71}}}],"partialFingerprints":{"codehealthFindingId/v1":"a58bd7693a5ae12e6c66bc857030f14893690a6d78fbb996921d9f85272dc26a"}},{"ruleId":"D1","level":"warning","message":{"text":"decision_tracker.report_conflicts (cyclomatic 18): decision_tracker.report_conflicts 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":"c-level-advisor/skills/decision-logger/scripts/decision_tracker.py"},"region":{"startLine":394}}}],"partialFingerprints":{"codehealthFindingId/v1":"cf7c45500a4e222b1ec208e402eaaefa329fbc06cebbd95f24d21049f8136ce8"}},{"ruleId":"D1","level":"warning","message":{"text":"IncidentClassifier._classify_severity (cyclomatic 18): IncidentClassifier._classify_severity 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":"engineering-team/skills/incident-commander/scripts/incident_classifier.py"},"region":{"startLine":420}}}],"partialFingerprints":{"codehealthFindingId/v1":"50d1a369b8da7823238a2157694dfbff1ccb9e557cdf7cc2e6866126b06a277e"}},{"ruleId":"D1","level":"warning","message":{"text":"SQLParser._parse_table_body (cyclomatic 18): SQLParser._parse_table_body 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":"engineering-team/skills/senior-backend/scripts/database_migration_tool.py"},"region":{"startLine":127}}}],"partialFingerprints":{"codehealthFindingId/v1":"ca52c5a6e183cc0b7f9d3d5254ec7aa51c44c5d9fd633e4d4a37fc95ea976a96"}},{"ruleId":"D1","level":"warning","message":{"text":"DataContractValidator._parse_simple_yaml (cyclomatic 18): DataContractValidator._parse_simple_yaml 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":"engineering-team/skills/senior-data-engineer/scripts/data_quality_validator.py"},"region":{"startLine":937}}}],"partialFingerprints":{"codehealthFindingId/v1":"fa9821b03f98a442df9fbe879d56bd15ad73dd1c4e21bb5f364e3c2e8e56040e"}},{"ruleId":"D1","level":"warning","message":{"text":"ReportGenerator.generate_text_report (cyclomatic 18): ReportGenerator.generate_text_report 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":"engineering-team/skills/senior-data-engineer/scripts/data_quality_validator.py"},"region":{"startLine":1111}}}],"partialFingerprints":{"codehealthFindingId/v1":"cf5f00f77d13b72f8c91423e5c948bb838a6371df14b04eeb5ade91d68671793"}},{"ruleId":"D1","level":"warning","message":{"text":"pipeline_orchestrator.main (cyclomatic 18): pipeline_orchestrator.main has cyclomatic complexity 18 (threshold 15). To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/skills/senior-data-engineer/scripts/pipeline_orchestrator.py"},"region":{"startLine":717}}}],"partialFingerprints":{"codehealthFindingId/v1":"1771ba30c6e9a07284da28e0b09156a4166e1f3d08cfd3afc98983ef2369fbca"}},{"ruleId":"D1","level":"warning","message":{"text":"EcosystemAnalyzer._score_npm_health (cyclomatic 18): EcosystemAnalyzer._score_npm_health 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":"engineering-team/skills/tech-stack-evaluator/scripts/ecosystem_analyzer.py"},"region":{"startLine":122}}}],"partialFingerprints":{"codehealthFindingId/v1":"59ba8e6ecb35882b1d0a1725e0192a998eed056116aac992e9981754b1c7202c"}},{"ruleId":"D1","level":"warning","message":{"text":"skill_plugin_emitter.emit (cyclomatic 18): skill_plugin_emitter.emit 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":"engineering/book-to-skill/skills/book-to-skill/scripts/skill_plugin_emitter.py"},"region":{"startLine":375}}}],"partialFingerprints":{"codehealthFindingId/v1":"9908cb94c222286de1cca94de851fd81b85be67f9f7e5913e61f64c28b95b460"}},{"ruleId":"D1","level":"warning","message":{"text":"reading_path_planner.main (cyclomatic 18): reading_path_planner.main 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":"engineering/deep-learning-book/skills/deep-learning-book/scripts/reading_path_planner.py"},"region":{"startLine":373}}}],"partialFingerprints":{"codehealthFindingId/v1":"f2da84f3cf4690a5b542927d111ea946032518dcb997dc94904037672cdb1744"}},{"ruleId":"D1","level":"warning","message":{"text":"memory_cost_profiler.profile (cyclomatic 18): memory_cost_profiler.profile 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":"engineering/memory-engineering/skills/memory-engineering/scripts/memory_cost_profiler.py"},"region":{"startLine":99}}}],"partialFingerprints":{"codehealthFindingId/v1":"db4884053e927f61b9b73f8ce8eca54d3750c92c87e8fc607cdd0b2c6c2b7e19"}},{"ruleId":"D1","level":"warning","message":{"text":"AgentEvaluator.analyze_errors (cyclomatic 18): AgentEvaluator.analyze_errors 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":"engineering/skills/agent-designer/agent_evaluator.py"},"region":{"startLine":355}}}],"partialFingerprints":{"codehealthFindingId/v1":"a97c7644ab69ce34c5bee6965d4e1ff71f9c4e7e58fbd813e5d74a3b74c726c3"}},{"ruleId":"D1","level":"warning","message":{"text":"loop_designer.main (cyclomatic 18): loop_designer.main has cyclomatic complexity 18 (threshold 15). To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/interview-system-designer/loop_designer.py"},"region":{"startLine":826}}}],"partialFingerprints":{"codehealthFindingId/v1":"cb32e279024dc64222a781eaa984da3feec2268d6b6be4b9ff9c9cebc2f89f42"}},{"ruleId":"D1","level":"warning","message":{"text":"question_bank_generator.main (cyclomatic 18): question_bank_generator.main has cyclomatic complexity 18 (threshold 15). To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/interview-system-designer/question_bank_generator.py"},"region":{"startLine":970}}}],"partialFingerprints":{"codehealthFindingId/v1":"a998617f2dc8f45ed463b1111d88a404deddac0ce4295eeea6ade857daf50533"}},{"ruleId":"D1","level":"warning","message":{"text":"ship_gate_scanner.run_manual_checks (cyclomatic 18): ship_gate_scanner.run_manual_checks 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":"engineering/skills/ship-gate/scripts/ship_gate_scanner.py"},"region":{"startLine":977}}}],"partialFingerprints":{"codehealthFindingId/v1":"147c7c5bff27e1ee3ac3f0318e3b55453ba1e2ef661f874723cfc7e70f63c041"}},{"ruleId":"D1","level":"warning","message":{"text":"tc_init.main (cyclomatic 18): tc_init.main has cyclomatic complexity 18 (threshold 15). To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/tc-tracker/scripts/tc_init.py"},"region":{"startLine":106}}}],"partialFingerprints":{"codehealthFindingId/v1":"379677be53503aa0c95378f9e18887964cd9fa16bd7aa376ce3755d8dd595151"}},{"ruleId":"D1","level":"warning","message":{"text":"validate_workflow._strip_comments (cyclomatic 18): validate_workflow._strip_comments 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":"engineering/workflow-builder/skills/workflow-builder/scripts/validate_workflow.py"},"region":{"startLine":22}}}],"partialFingerprints":{"codehealthFindingId/v1":"47678312fe7c78bf7f00d9ba26c20b156778d0361514ac65b84b992e5bdb206b"}},{"ruleId":"D1","level":"warning","message":{"text":"verify_data.check_period_alignment (cyclomatic 18): verify_data.check_period_alignment 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":"finance/skills/stock-analysis/scripts/verify_data.py"},"region":{"startLine":1108}}}],"partialFingerprints":{"codehealthFindingId/v1":"9352b0ab526316d363093ceca547c69d8bfcb3150e667817d70acc9432f6396b"}},{"ruleId":"D1","level":"warning","message":{"text":"context_validator.validate_context (cyclomatic 18): context_validator.validate_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":"marketing-skill/skills/marketing-context/scripts/context_validator.py"},"region":{"startLine":27}}}],"partialFingerprints":{"codehealthFindingId/v1":"b0be4a5798c2a6305be84cf6ed18c00d73ddfe5a43d73bba9ff75df0419abc45"}},{"ruleId":"D1","level":"warning","message":{"text":"campaign_tracker.analyze_campaign (cyclomatic 18): campaign_tracker.analyze_campaign 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":"marketing-skill/skills/marketing-ops/scripts/campaign_tracker.py"},"region":{"startLine":29}}}],"partialFingerprints":{"codehealthFindingId/v1":"f33366932940aaebf9b4e3a83caeb9bc1d23c76b9a946c574cb64d2f1d5322ed"}},{"ruleId":"D1","level":"warning","message":{"text":"ad_health_scorer.score_platform (cyclomatic 18): ad_health_scorer.score_platform 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":"marketing-skill/skills/paid-ads/scripts/ad_health_scorer.py"},"region":{"startLine":99}}}],"partialFingerprints":{"codehealthFindingId/v1":"3a98d523df189b54084a86d9e38985e6392b1a731c5265aafc517edc63376fb8"}},{"ruleId":"D1","level":"warning","message":{"text":"roas_calculator.calculate (cyclomatic 18): roas_calculator.calculate 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":"marketing-skill/skills/paid-ads/scripts/roas_calculator.py"},"region":{"startLine":20}}}],"partialFingerprints":{"codehealthFindingId/v1":"eff4101c3efddee89de17149180aee262196a77c85ce37c037de5d18624f469c"}},{"ruleId":"D1","level":"warning","message":{"text":"tweet_composer.main (cyclomatic 18): tweet_composer.main has cyclomatic complexity 18 (threshold 15). To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"marketing-skill/skills/x-twitter-growth/scripts/tweet_composer.py"},"region":{"startLine":222}}}],"partialFingerprints":{"codehealthFindingId/v1":"069e6b004d9d2e286ba3bd910e1308092e1c91496dd0c1f7e70d9ea3cfb1a188"}},{"ruleId":"D1","level":"warning","message":{"text":"anti_todo_card.main (cyclomatic 18): anti_todo_card.main has cyclomatic complexity 18 (threshold 15). To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"productivity/andreessen/skills/andreessen/scripts/anti_todo_card.py"},"region":{"startLine":146}}}],"partialFingerprints":{"codehealthFindingId/v1":"cc9e58b026f7d29314df5b97c624905cd237fdb758a253b13b2fa7e8d9f2720d"}},{"ruleId":"D1","level":"warning","message":{"text":"setup.run_setup (cyclomatic 18): setup.run_setup 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":"productivity/handoff/skills/handoff/scripts/setup.py"},"region":{"startLine":152}}}],"partialFingerprints":{"codehealthFindingId/v1":"90ba6ecaa58c05b00de2fa7f954418a13a02c219dbe9523b9cd09e3dfa6a07e0"}},{"ruleId":"D1","level":"warning","message":{"text":"dpia_generator.generate_dpia_report (cyclomatic 18): dpia_generator.generate_dpia_report has cyclomatic complexity 18 (threshold 15). To reduce it, break up the iteration: give each loop body a named function, and split a multi-phase loop into one function per phase so no single body carries the whole pipeline."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"ra-qm-team/skills/gdpr-dsgvo-expert/scripts/dpia_generator.py"},"region":{"startLine":390}}}],"partialFingerprints":{"codehealthFindingId/v1":"9cbe0af43224197dff64c940dfc3cf0f3b95d565f907c700093ba49cd9897ac6"}},{"ruleId":"D1","level":"warning","message":{"text":"document_version_control.main (cyclomatic 18): document_version_control.main has cyclomatic complexity 18 (threshold 15). To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"ra-qm-team/skills/quality-documentation-manager/scripts/document_version_control.py"},"region":{"startLine":375}}}],"partialFingerprints":{"codehealthFindingId/v1":"c9196cb93239f2d99f4699bcbafd71372dba89debb8e95b790cad1a4f2fc62b6"}},{"ruleId":"D1","level":"warning","message":{"text":"phase_gate_scorer.score_plan (cyclomatic 18): phase_gate_scorer.score_plan 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":"research-ops/skills/clinical-research/scripts/phase_gate_scorer.py"},"region":{"startLine":88}}}],"partialFingerprints":{"codehealthFindingId/v1":"90c889938253a91a08a4e8f00c22d73366806d44c50dee281fbf1f33f7e8b4ca"}},{"ruleId":"D1","level":"warning","message":{"text":"framework_recommender.recommend (cyclomatic 18): framework_recommender.recommend 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":"research/litreview/skills/litreview/scripts/framework_recommender.py"},"region":{"startLine":70}}}],"partialFingerprints":{"codehealthFindingId/v1":"3bba8ea8315518d557bb1572033b7d4ce19d1115ca539d5b7ae27925defa022b"}},{"ruleId":"D1","level":"warning","message":{"text":"routing_transparency_logger.main (cyclomatic 18): routing_transparency_logger.main has cyclomatic complexity 18 (threshold 15). To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"research/research/skills/research/scripts/routing_transparency_logger.py"},"region":{"startLine":127}}}],"partialFingerprints":{"codehealthFindingId/v1":"e2fcb457eed30efee2609a4248e51603f472837c8154b24b2bf508d73abf2497"}},{"ruleId":"D1","level":"warning","message":{"text":"derive_counters.run_check (cyclomatic 18): derive_counters.run_check 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":"scripts/derive_counters.py"},"region":{"startLine":273}}}],"partialFingerprints":{"codehealthFindingId/v1":"4db57f1c394a180b6d5c9653dcb485dfb06094b0b3fa5bd3716e218761f2b4e5"}},{"ruleId":"D1","level":"warning","message":{"text":"smoke_json_output.main (cyclomatic 18): smoke_json_output.main has cyclomatic complexity 18 (threshold 15). To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"scripts/smoke_json_output.py"},"region":{"startLine":148}}}],"partialFingerprints":{"codehealthFindingId/v1":"cfe1cbe03d99509911a91bad62761d203d596ee3103e9e65fda8410b67e53d66"}},{"ruleId":"D1","level":"warning","message":{"text":"full-page-screenshot.captureFullPage (cyclomatic 18): full-page-screenshot.captureFullPage 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":"engineering/skills/full-page-screenshot/scripts/full-page-screenshot.mjs"},"region":{"startLine":221}}}],"partialFingerprints":{"codehealthFindingId/v1":"c903176ea201035cf490ebab3ac10016616b89660ab1494d7f088642ea21d8e4"}},{"ruleId":"D1","level":"warning","message":{"text":"marketing_budget_modeler.print_recommendations (cyclomatic 17): marketing_budget_modeler.print_recommendations 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":"c-level-advisor/skills/cmo-advisor/scripts/marketing_budget_modeler.py"},"region":{"startLine":355}}}],"partialFingerprints":{"codehealthFindingId/v1":"60d40fdde740e131cd5118055fc421defd7776f00d0d4bde7364df19e515ca10"}},{"ruleId":"D1","level":"warning","message":{"text":"decision_tracker.main (cyclomatic 17): decision_tracker.main has cyclomatic complexity 17 (threshold 15). To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"c-level-advisor/skills/decision-logger/scripts/decision_tracker.py"},"region":{"startLine":546}}}],"partialFingerprints":{"codehealthFindingId/v1":"8af2e1f9d7734b17373d8b082bb58963ee9f23bba024df8a7db082d0bc8155df"}},{"ruleId":"D1","level":"warning","message":{"text":"scenario_modeler.print_report (cyclomatic 17): scenario_modeler.print_report 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":"c-level-advisor/skills/scenario-war-room/scripts/scenario_modeler.py"},"region":{"startLine":212}}}],"partialFingerprints":{"codehealthFindingId/v1":"acd65292b7e29105c63c9c741f2f19a21d03de47cfd4616f14d3d6d147b74582"}},{"ruleId":"D1","level":"warning","message":{"text":"code_quality_checker.check_c_specific_smells (cyclomatic 17): code_quality_checker.check_c_specific_smells 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":"engineering-team/skills/code-reviewer/scripts/code_quality_checker.py"},"region":{"startLine":610}}}],"partialFingerprints":{"codehealthFindingId/v1":"a95e8edeeaeb21613b45335b1be7dd2a6384328bcd8ae71479273f7b6c6c3d55"}},{"ruleId":"D1","level":"warning","message":{"text":"inspect-assets.analyse_image (cyclomatic 17): inspect-assets.analyse_image 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":"engineering-team/skills/epic-design/scripts/inspect-assets.py"},"region":{"startLine":24}}}],"partialFingerprints":{"codehealthFindingId/v1":"f4c8fec0d1875c9c7ac173b52fac723e6f68c6902651c14651d0be1346a41b3c"}},{"ruleId":"D1","level":"warning","message":{"text":"PIRGenerator._identify_category_factors (cyclomatic 17): PIRGenerator._identify_category_factors 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":"engineering-team/skills/incident-commander/scripts/pir_generator.py"},"region":{"startLine":664}}}],"partialFingerprints":{"codehealthFindingId/v1":"ee49e4b8a1397e6cb5bea61edef03522d9e707900d2fca4e5ca5640f036d3139"}},{"ruleId":"D1","level":"warning","message":{"text":"api_scaffolder.load_yaml_as_json (cyclomatic 17): api_scaffolder.load_yaml_as_json 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":"engineering-team/skills/senior-backend/scripts/api_scaffolder.py"},"region":{"startLine":24}}}],"partialFingerprints":{"codehealthFindingId/v1":"3068500556fd83d201b3235e142ebd7d54bd5688d2c18373632b10acaf50836b"}},{"ruleId":"D1","level":"warning","message":{"text":"bundle_analyzer.print_report (cyclomatic 17): bundle_analyzer.print_report 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":"engineering-team/skills/senior-frontend/scripts/bundle_analyzer.py"},"region":{"startLine":293}}}],"partialFingerprints":{"codehealthFindingId/v1":"1bdbd5fdcad1799fef9c610eff923e2fbb242c08abdf1a13be522c9be2b4fc1a"}},{"ruleId":"D1","level":"warning","message":{"text":"FrameworkAdapter.detect_framework (cyclomatic 17): FrameworkAdapter.detect_framework 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":"engineering-team/skills/tdd-guide/scripts/framework_adapter.py"},"region":{"startLine":390}}}],"partialFingerprints":{"codehealthFindingId/v1":"360280b3962969de66e26aa169453b1b2673a729eaefd89d93060e936d1174d5"}},{"ruleId":"D1","level":"warning","message":{"text":"threat_signal_analyzer.ioc_mode (cyclomatic 17): threat_signal_analyzer.ioc_mode 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":"engineering-team/skills/threat-detection/scripts/threat_signal_analyzer.py"},"region":{"startLine":161}}}],"partialFingerprints":{"codehealthFindingId/v1":"7b612918481610f46679eb69d34f5ee79d88718259478f185e2c1a7a28f822dc"}},{"ruleId":"D1","level":"warning","message":{"text":"setup_experiment.main (cyclomatic 17): setup_experiment.main has cyclomatic complexity 17 (threshold 15). To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/autoresearch-agent/skills/autoresearch-agent/scripts/setup_experiment.py"},"region":{"startLine":251}}}],"partialFingerprints":{"codehealthFindingId/v1":"1a9da6d71a98bebcdce1cfad502db57995884606db4a0fc80ee742bfb042e810"}},{"ruleId":"D1","level":"warning","message":{"text":"chart_analyzer.check_templates (cyclomatic 17): chart_analyzer.check_templates 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":"engineering/helm-chart-builder/skills/helm-chart-builder/scripts/chart_analyzer.py"},"region":{"startLine":257}}}],"partialFingerprints":{"codehealthFindingId/v1":"471a9c03348b96e7b4b6042da73122c9680e2ecc7d9b6aec4e2bfef8107fe809"}},{"ruleId":"D1","level":"warning","message":{"text":"diff_surgeon.main (cyclomatic 17): diff_surgeon.main has cyclomatic complexity 17 (threshold 15). To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/karpathy-coder/skills/karpathy-coder/scripts/diff_surgeon.py"},"region":{"startLine":141}}}],"partialFingerprints":{"codehealthFindingId/v1":"d1fd372d3f2a546f1b293469e55aa04189be87b1fc6ada06cd03651421c55b17"}},{"ruleId":"D1","level":"warning","message":{"text":"memory_density_auditor.audit (cyclomatic 17): memory_density_auditor.audit 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":"engineering/memory-engineering/skills/memory-engineering/scripts/memory_density_auditor.py"},"region":{"startLine":365}}}],"partialFingerprints":{"codehealthFindingId/v1":"6d692e89272aa94d4c4fce7879c69dcc22934ccadddb3c08ca3ca637983b3e1a"}},{"ruleId":"D1","level":"warning","message":{"text":"APIScoringEngine._check_parameter_consistency (cyclomatic 17): APIScoringEngine._check_parameter_consistency 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":"engineering/skills/api-design-reviewer/scripts/api_scorecard.py"},"region":{"startLine":353}}}],"partialFingerprints":{"codehealthFindingId/v1":"8982e880f2560be6eefb7b30e3aaf38407670931001b94cb199301e743927611"}},{"ruleId":"D1","level":"warning","message":{"text":"BreakingChangeDetector.generate_text_report (cyclomatic 17): BreakingChangeDetector.generate_text_report 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":"engineering/skills/api-design-reviewer/scripts/breaking_change_detector.py"},"region":{"startLine":875}}}],"partialFingerprints":{"codehealthFindingId/v1":"a5bc4ba66301f62681c9bc440a835d02aeaa43e4661942c0697d19ca26bb5780"}},{"ruleId":"D1","level":"warning","message":{"text":"HiringCalibrator._analyze_trends_over_time (cyclomatic 17): HiringCalibrator._analyze_trends_over_time 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":"engineering/skills/interview-system-designer/hiring_calibrator.py"},"region":{"startLine":604}}}],"partialFingerprints":{"codehealthFindingId/v1":"defafa2852c2b894f187038475ecb5ed9ccf1a14e8cbf864a6bd53614b0ed37a"}},{"ruleId":"D1","level":"warning","message":{"text":"SemanticChunker._chunk_section (cyclomatic 17): SemanticChunker._chunk_section 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":"engineering/skills/rag-architect/chunking_optimizer.py"},"region":{"startLine":364}}}],"partialFingerprints":{"codehealthFindingId/v1":"aa4482dda17135e851084e5a7a2faf58b1b23e09d90b1d683fc62b9e3a823996"}},{"ruleId":"D1","level":"warning","message":{"text":"ship_gate_scanner.grep_files (cyclomatic 17): ship_gate_scanner.grep_files 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":"engineering/skills/ship-gate/scripts/ship_gate_scanner.py"},"region":{"startLine":150}}}],"partialFingerprints":{"codehealthFindingId/v1":"c19ec637f56c819fd916b49bcbd29a217681126da4f7914c78a24c9281875ede"}},{"ruleId":"D1","level":"warning","message":{"text":"skill_security_auditor.scan_filesystem (cyclomatic 17): skill_security_auditor.scan_filesystem 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":"engineering/skills/skill-security-auditor/scripts/skill_security_auditor.py"},"region":{"startLine":776}}}],"partialFingerprints":{"codehealthFindingId/v1":"04c1f40248546120efa52bd4088cae837310f4bf8c5624e43944aeb52ef27f36"}},{"ruleId":"D1","level":"warning","message":{"text":"score.resolve_sector (cyclomatic 17): score.resolve_sector 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":"finance/skills/stock-analysis/scripts/score.py"},"region":{"startLine":157}}}],"partialFingerprints":{"codehealthFindingId/v1":"4a322aebad5e4d2e921e9feba126ac1a3fb19c39ec50cd893da4a421de3018d1"}},{"ruleId":"D1","level":"warning","message":{"text":"email_sequence_analyzer.analyze_body (cyclomatic 17): email_sequence_analyzer.analyze_body 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":"marketing-skill/skills/cold-email/scripts/email_sequence_analyzer.py"},"region":{"startLine":224}}}],"partialFingerprints":{"codehealthFindingId/v1":"56cd3190d24dad598388a51947ce4261ea5ae98c0eb41f99186d69ab07ddccca"}},{"ruleId":"D1","level":"warning","message":{"text":"comparison_matrix_builder.build_matrix (cyclomatic 17): comparison_matrix_builder.build_matrix 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":"marketing-skill/skills/competitor-alternatives/scripts/comparison_matrix_builder.py"},"region":{"startLine":77}}}],"partialFingerprints":{"codehealthFindingId/v1":"ea9085cbb8282ba152d9c4c7da2f004865dd612ef148029e31b60caf47c2963e"}},{"ruleId":"D1","level":"warning","message":{"text":"content_scorer.score_structure (cyclomatic 17): content_scorer.score_structure 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":"marketing-skill/skills/content-production/scripts/content_scorer.py"},"region":{"startLine":199}}}],"partialFingerprints":{"codehealthFindingId/v1":"70e5c4b356acd095640ea31cd57b96bed8810902c6ad609ac633d8daab856b37"}},{"ruleId":"D1","level":"warning","message":{"text":"sitemap_analyzer.parse_sitemap (cyclomatic 17): sitemap_analyzer.parse_sitemap 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":"marketing-skill/skills/site-architecture/scripts/sitemap_analyzer.py"},"region":{"startLine":147}}}],"partialFingerprints":{"codehealthFindingId/v1":"21061110e51eba8dcf0cdd8dc243064c65f3bbb7ea6bc69838711afa8940e5c9"}},{"ruleId":"D1","level":"warning","message":{"text":"ost_linter.lint (cyclomatic 17): ost_linter.lint 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":"product-team/skills/product-skills/scripts/ost_linter.py"},"region":{"startLine":75}}}],"partialFingerprints":{"codehealthFindingId/v1":"9cc00eab5578c0d7ea951286a3c8b89d99f596e2b00d55cac611bc5189aeb9a2"}},{"ruleId":"D1","level":"warning","message":{"text":"kb_reader.read_kb (cyclomatic 17): kb_reader.read_kb 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":"productivity/email/skills/inbox-triage/scripts/kb_reader.py"},"region":{"startLine":179}}}],"partialFingerprints":{"codehealthFindingId/v1":"6e61db6383a5e2e59b3ed6f83cbe12abe74c326f9196a9afb0bb9356d30e709b"}},{"ruleId":"D1","level":"warning","message":{"text":"sprint_health_scorer._generate_detailed_metrics (cyclomatic 17): sprint_health_scorer._generate_detailed_metrics has cyclomatic complexity 17 (threshold 15). To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"project-management/skills/scrum-master/scripts/sprint_health_scorer.py"},"region":{"startLine":518}}}],"partialFingerprints":{"codehealthFindingId/v1":"14f21233b724cf2a369690c64da9a8d8ed8337fb3f04a64a9139edebad77f534"}},{"ruleId":"D1","level":"warning","message":{"text":"fda_submission_tracker.print_text_report (cyclomatic 17): fda_submission_tracker.print_text_report 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":"ra-qm-team/skills/fda-consultant-specialist/scripts/fda_submission_tracker.py"},"region":{"startLine":305}}}],"partialFingerprints":{"codehealthFindingId/v1":"78a0484498c424dff6ac9e9d1df2d76294eb70bafec9d2a43692e76e146e0a04"}},{"ruleId":"D1","level":"warning","message":{"text":"data_subject_rights_tracker.main (cyclomatic 17): data_subject_rights_tracker.main has cyclomatic complexity 17 (threshold 15). To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"ra-qm-team/skills/gdpr-dsgvo-expert/scripts/data_subject_rights_tracker.py"},"region":{"startLine":449}}}],"partialFingerprints":{"codehealthFindingId/v1":"7d0eec897bce0c4f8c89471b67186efdd28a1d565b25b38b12e23424a2430bc6"}},{"ruleId":"D1","level":"warning","message":{"text":"check_frontmatter.main (cyclomatic 17): check_frontmatter.main has cyclomatic complexity 17 (threshold 15). To reduce it, break up the iteration: give each loop body a named function, and split a multi-phase loop into one function per phase so no single body carries the whole pipeline."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"scripts/check_frontmatter.py"},"region":{"startLine":174}}}],"partialFingerprints":{"codehealthFindingId/v1":"27c1356e6aa7e5f087e82f4db38a45b5c8e57c015f6164eaa0f6b081f90e7680"}},{"ruleId":"D1","level":"warning","message":{"text":"sync-codex-skills.find_skills (cyclomatic 17): sync-codex-skills.find_skills 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":"scripts/sync-codex-skills.py"},"region":{"startLine":98}}}],"partialFingerprints":{"codehealthFindingId/v1":"921e8a80d0772946053f504ceaaa02e0f622106a1de2b65cb7d15cee2b07736e"}},{"ruleId":"D1","level":"warning","message":{"text":"sync-vibe-skills.main (cyclomatic 17): sync-vibe-skills.main 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":"scripts/sync-vibe-skills.py"},"region":{"startLine":246}}}],"partialFingerprints":{"codehealthFindingId/v1":"72918c0aab1135f825be77e6b2ae1efea5b64655ebf5e74de5b93c54015b787a"}},{"ruleId":"D1","level":"warning","message":{"text":"full-page-screenshot.modeUrl (cyclomatic 17): full-page-screenshot.modeUrl 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":"engineering/skills/full-page-screenshot/scripts/full-page-screenshot.mjs"},"region":{"startLine":524}}}],"partialFingerprints":{"codehealthFindingId/v1":"66e3e0b9e3c00f7aff581125c704e39379ff5a4a674dd1cac8efe6ac2ad8f538"}},{"ruleId":"D1","level":"warning","message":{"text":"cron_validator._valid_field (cyclomatic 16): cron_validator._valid_field 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":"agent-launcher/skills/run-without-you/scripts/cron_validator.py"},"region":{"startLine":25}}}],"partialFingerprints":{"codehealthFindingId/v1":"f1fa71ee2bc4b45525106046104bbe22e1570c3029d4a121d02cbb95cf3e2467"}},{"ruleId":"D1","level":"warning","message":{"text":"poc_planner.format_text (cyclomatic 16): poc_planner.format_text has cyclomatic complexity 16 (threshold 15). To reduce it, break up the iteration: give each loop body a named function, and split a multi-phase loop into one function per phase so no single body carries the whole pipeline."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"business-growth/skills/sales-engineer/scripts/poc_planner.py"},"region":{"startLine":581}}}],"partialFingerprints":{"codehealthFindingId/v1":"75490b6602311c376d1dd1c27674fc0093624f6a9379fb9aa98f4e8398ffc670"}},{"ruleId":"D1","level":"warning","message":{"text":"rfp_response_analyzer.determine_bid_recommendation (cyclomatic 16): rfp_response_analyzer.determine_bid_recommendation 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":"business-growth/skills/sales-engineer/scripts/rfp_response_analyzer.py"},"region":{"startLine":207}}}],"partialFingerprints":{"codehealthFindingId/v1":"13678bc8446438caf13461a57e87a5b76cc0c3808774c5fea5af9d02f3e3b219"}},{"ruleId":"D1","level":"warning","message":{"text":"capacity_modeler.model_capacity (cyclomatic 16): capacity_modeler.model_capacity 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":"business-operations/skills/capacity-planner/scripts/capacity_modeler.py"},"region":{"startLine":159}}}],"partialFingerprints":{"codehealthFindingId/v1":"689f9cfafc8db2d4d03563bfa7ae8c3d14e5a47a2fc564fba2a51d1b0baf2294"}},{"ruleId":"D1","level":"warning","message":{"text":"utilization_analyzer.assess_team (cyclomatic 16): utilization_analyzer.assess_team 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":"business-operations/skills/capacity-planner/scripts/utilization_analyzer.py"},"region":{"startLine":110}}}],"partialFingerprints":{"codehealthFindingId/v1":"d3a00d1701177e4ea2be1d0ac0b9c9d54c9a6816a8eb398b11eddbd7b56b5413"}},{"ruleId":"D1","level":"warning","message":{"text":"kb_ingester.generate_report (cyclomatic 16): kb_ingester.generate_report 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":"business-operations/skills/knowledge-ops/scripts/kb_ingester.py"},"region":{"startLine":264}}}],"partialFingerprints":{"codehealthFindingId/v1":"5e9dfa42dd1e62ebf21d3d6e8d9644190ff335b7ed7ea77eb30043203d616c39"}},{"ruleId":"D1","level":"warning","message":{"text":"cycle_time_analyzer.analyze (cyclomatic 16): cycle_time_analyzer.analyze 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":"business-operations/skills/process-mapper/scripts/cycle_time_analyzer.py"},"region":{"startLine":51}}}],"partialFingerprints":{"codehealthFindingId/v1":"e8fab3f7bc3cdc5f5afff3dbe988b6a7882af3d8be0161a1ff1b398b89940ac5"}},{"ruleId":"D1","level":"warning","message":{"text":"supplier_consolidation.render_markdown (cyclomatic 16): supplier_consolidation.render_markdown has cyclomatic complexity 16 (threshold 15). To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"business-operations/skills/procurement-optimizer/scripts/supplier_consolidation.py"},"region":{"startLine":223}}}],"partialFingerprints":{"codehealthFindingId/v1":"9f18eae3da891093fea2b9090efd3f26a97f8301ec5dcfd9b6fbc826d294d8b1"}},{"ruleId":"D1","level":"warning","message":{"text":"decision_matrix_scorer.print_report (cyclomatic 16): decision_matrix_scorer.print_report 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":"c-level-advisor/executive-mentor/skills/executive-mentor/scripts/decision_matrix_scorer.py"},"region":{"startLine":164}}}],"partialFingerprints":{"codehealthFindingId/v1":"738c849cd658d0f02b098822ff83451fb98429e7425ea796e8fac072bf3430cd"}},{"ruleId":"D1","level":"warning","message":{"text":"unit_economics_analyzer.analyze_cohort (cyclomatic 16): unit_economics_analyzer.analyze_cohort 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":"c-level-advisor/skills/cfo-advisor/scripts/unit_economics_analyzer.py"},"region":{"startLine":98}}}],"partialFingerprints":{"codehealthFindingId/v1":"72e497222d668b60424f08dd16c06e1ce0d411b69cb6a37851910346755471ce"}},{"ruleId":"D1","level":"warning","message":{"text":"hiring_plan_modeler.assess_risks (cyclomatic 16): hiring_plan_modeler.assess_risks 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":"c-level-advisor/skills/chro-advisor/scripts/hiring_plan_modeler.py"},"region":{"startLine":175}}}],"partialFingerprints":{"codehealthFindingId/v1":"9f264cefbd39e5a47854fdba7d84e972392ac273ee3c7c8db3f96d2fb11d1557"}},{"ruleId":"D1","level":"warning","message":{"text":"portfolio_analyzer.investment_posture (cyclomatic 16): portfolio_analyzer.investment_posture 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":"c-level-advisor/skills/cpo-advisor/scripts/portfolio_analyzer.py"},"region":{"startLine":132}}}],"partialFingerprints":{"codehealthFindingId/v1":"907198d9f39b4a761039e2e09f328457282cfbf2f4cada2776a0855deaefbbf9"}},{"ruleId":"D1","level":"warning","message":{"text":"alignment_checker.print_report (cyclomatic 16): alignment_checker.print_report 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":"c-level-advisor/skills/strategic-alignment/scripts/alignment_checker.py"},"region":{"startLine":317}}}],"partialFingerprints":{"codehealthFindingId/v1":"b5db10c266e04589a07988833fc9472564be0bc4ecb3fd09aa1e2eaf935ad344"}},{"ruleId":"D1","level":"warning","message":{"text":"channel_mix_optimizer.render_markdown (cyclomatic 16): channel_mix_optimizer.render_markdown has cyclomatic complexity 16 (threshold 15). To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"commercial/skills/channel-economics/scripts/channel_mix_optimizer.py"},"region":{"startLine":185}}}],"partialFingerprints":{"codehealthFindingId/v1":"ad10cb2b2c69eb8c619d9ef9a2104d563f7412bb5a088b6c1690258d68426290"}},{"ruleId":"D1","level":"warning","message":{"text":"a11y_scanner.check_media_captions_block (cyclomatic 16): a11y_scanner.check_media_captions_block 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":"engineering-team/a11y-audit/skills/a11y-audit/scripts/a11y_scanner.py"},"region":{"startLine":407}}}],"partialFingerprints":{"codehealthFindingId/v1":"ff255dd04287dbef1f348de27ba57befd0c04816152abf3b6f56a61b0059bdf8"}},{"ruleId":"D1","level":"warning","message":{"text":"review_report_generator.format_markdown_report (cyclomatic 16): review_report_generator.format_markdown_report 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":"engineering-team/skills/code-reviewer/scripts/review_report_generator.py"},"region":{"startLine":224}}}],"partialFingerprints":{"codehealthFindingId/v1":"39fa020c6b712400933c1ab503e1e3193602a47aca2b6ecb921ae38beeceaceb"}},{"ruleId":"D1","level":"warning","message":{"text":"pir_generator.main (cyclomatic 16): pir_generator.main 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":"engineering-team/skills/incident-commander/scripts/pir_generator.py"},"region":{"startLine":1501}}}],"partialFingerprints":{"codehealthFindingId/v1":"67c047910cd1279e239d567a36b9d297af46e904caab0786473343714bd9492b"}},{"ruleId":"D1","level":"warning","message":{"text":"DatasetAnalyzer._detect_format (cyclomatic 16): DatasetAnalyzer._detect_format 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":"engineering-team/skills/senior-computer-vision/scripts/dataset_pipeline_builder.py"},"region":{"startLine":204}}}],"partialFingerprints":{"codehealthFindingId/v1":"b27be10921efe49bae721768913a93eb2237e5f49e1e257cb914617866b7813a"}},{"ruleId":"D1","level":"warning","message":{"text":"GreatExpectationsGenerator._generate_column_expectations (cyclomatic 16): GreatExpectationsGenerator._generate_column_expectations 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":"engineering-team/skills/senior-data-engineer/scripts/data_quality_validator.py"},"region":{"startLine":753}}}],"partialFingerprints":{"codehealthFindingId/v1":"8709a9e93be1e5d4a7c5576743cdb5a99974fc20f80832d86454f7db341416ac"}},{"ruleId":"D1","level":"warning","message":{"text":"loop_controller.cmd_verify (cyclomatic 16): loop_controller.cmd_verify 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":"engineering/agent-harness/skills/agent-harness/scripts/loop_controller.py"},"region":{"startLine":204}}}],"partialFingerprints":{"codehealthFindingId/v1":"2c52a23e3c60141b2152fcfac00e7627694b8724ae8fd02551beff8a5d4ed45f"}},{"ruleId":"D1","level":"warning","message":{"text":"book_skill_validator._collect_skill_files (cyclomatic 16): book_skill_validator._collect_skill_files 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":"engineering/book-to-skill/skills/book-to-skill/scripts/book_skill_validator.py"},"region":{"startLine":166}}}],"partialFingerprints":{"codehealthFindingId/v1":"5113f5e7ba249e591cb40c2edb5b82fee3309bdda5f8f0f418366f5570e9c742"}},{"ruleId":"D1","level":"warning","message":{"text":"rtf._strip_destination_groups (cyclomatic 16): rtf._strip_destination_groups 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":"engineering/book-to-skill/skills/book-to-skill/scripts/book_to_skill/parsers/rtf.py"},"region":{"startLine":44}}}],"partialFingerprints":{"codehealthFindingId/v1":"e064531512921ca829587c62e9434b175baee09ae586025d601058ba6ce21073"}},{"ruleId":"D1","level":"warning","message":{"text":"chart_analyzer.analyze_chart (cyclomatic 16): chart_analyzer.analyze_chart 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":"engineering/helm-chart-builder/skills/helm-chart-builder/scripts/chart_analyzer.py"},"region":{"startLine":400}}}],"partialFingerprints":{"codehealthFindingId/v1":"c21a401c20bc24626e41293d5df83321a9f945d4a288540e713abff23cd3b5a4"}},{"ruleId":"D1","level":"warning","message":{"text":"forgetting_policy_linter.lint (cyclomatic 16): forgetting_policy_linter.lint 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":"engineering/memory-engineering/skills/memory-engineering/scripts/forgetting_policy_linter.py"},"region":{"startLine":221}}}],"partialFingerprints":{"codehealthFindingId/v1":"0cff2499dcdf7eda9fb8942114fedd3cec1834ce9e3544efb1c4d7223661da7a"}},{"ruleId":"D1","level":"warning","message":{"text":"AgentPlanner.design_communication_topology (cyclomatic 16): AgentPlanner.design_communication_topology 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":"engineering/skills/agent-designer/agent_planner.py"},"region":{"startLine":544}}}],"partialFingerprints":{"codehealthFindingId/v1":"fb353b54cf63b7ff75e3725ef08cba4aa4d27924368457aef6d527e5c01ccd8a"}},{"ruleId":"D1","level":"warning","message":{"text":"APILinter._validate_path_structure (cyclomatic 16): APILinter._validate_path_structure 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":"engineering/skills/api-design-reviewer/scripts/api_linter.py"},"region":{"startLine":279}}}],"partialFingerprints":{"codehealthFindingId/v1":"dab2547735f72bb23554f9f0e0910e5a6da233f3be16a654a6ed87cefcfaf3b7"}},{"ruleId":"D1","level":"warning","message":{"text":"APIScoringEngine._check_url_structure_consistency (cyclomatic 16): APIScoringEngine._check_url_structure_consistency 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":"engineering/skills/api-design-reviewer/scripts/api_scorecard.py"},"region":{"startLine":401}}}],"partialFingerprints":{"codehealthFindingId/v1":"5f5d0674fe1e6d6aa7f04eddccffedc86a218e4cc6483c2953bc1eca23b1b117"}},{"ruleId":"D1","level":"warning","message":{"text":"question_bank_generator.format_human_readable (cyclomatic 16): question_bank_generator.format_human_readable 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":"engineering/skills/interview-system-designer/question_bank_generator.py"},"region":{"startLine":880}}}],"partialFingerprints":{"codehealthFindingId/v1":"244bc3e23f72ead8a5403e72951b98b74cc7746631846fed493354068e445cb5"}},{"ruleId":"D1","level":"warning","message":{"text":"ScriptTester._test_argparse_implementation (cyclomatic 16): ScriptTester._test_argparse_implementation 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":"engineering/skills/skill-tester/scripts/script_tester.py"},"region":{"startLine":316}}}],"partialFingerprints":{"codehealthFindingId/v1":"55ba33b6d0699f2e93c4ed03b26cebd805e971bff920195fb294ddc33ebe2be0"}},{"ruleId":"D1","level":"warning","message":{"text":"DebtDashboard._generate_executive_summary (cyclomatic 16): DebtDashboard._generate_executive_summary 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":"engineering/skills/tech-debt-tracker/scripts/debt_dashboard.py"},"region":{"startLine":606}}}],"partialFingerprints":{"codehealthFindingId/v1":"507e164bb51f171332dbfca49e08186dd30729c8e7083ce14c5d51ce20de62e3"}},{"ruleId":"D1","level":"warning","message":{"text":"Analysis._warn_tax_rate_anomalies (cyclomatic 16): Analysis._warn_tax_rate_anomalies 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":"finance/skills/stock-analysis/scripts/ratios.py"},"region":{"startLine":2158}}}],"partialFingerprints":{"codehealthFindingId/v1":"6147ac8643de83f8e65a11fb0c1d5e788c731fcc78360dfe4c061d7e3e9a4c79"}},{"ruleId":"D1","level":"warning","message":{"text":"verify_data.classify_period (cyclomatic 16): verify_data.classify_period 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":"finance/skills/stock-analysis/scripts/verify_data.py"},"region":{"startLine":530}}}],"partialFingerprints":{"codehealthFindingId/v1":"8843fe0e8e9e19f911ee96f2c6841aa79caa09a1ae7cbb8f9ef53e7c3853a460"}},{"ruleId":"D1","level":"warning","message":{"text":"verify_data.check_cross_source (cyclomatic 16): verify_data.check_cross_source 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":"finance/skills/stock-analysis/scripts/verify_data.py"},"region":{"startLine":858}}}],"partialFingerprints":{"codehealthFindingId/v1":"dbbec0b069c4220d0b19a505da76fc946808f6dbc792365d722a8591e2bc04b3"}},{"ruleId":"D1","level":"warning","message":{"text":"verify_data.check_recency (cyclomatic 16): verify_data.check_recency 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":"finance/skills/stock-analysis/scripts/verify_data.py"},"region":{"startLine":1173}}}],"partialFingerprints":{"codehealthFindingId/v1":"791fe3cbd4e93bd8d35ac0e7ae7b1128c6fdda0dd692c1925d0b08bfa05a7fa3"}},{"ruleId":"D1","level":"warning","message":{"text":"onboard.main (cyclomatic 16): onboard.main has cyclomatic complexity 16 (threshold 15). To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"markdown-html/skills/design-system/scripts/onboard.py"},"region":{"startLine":173}}}],"partialFingerprints":{"codehealthFindingId/v1":"d43a8919b2942fc8f0cd84a565fcad8cde4e937c6ce11f9fa05ab3035e7cb90f"}},{"ruleId":"D1","level":"warning","message":{"text":"tracking_plan_generator.generate_tracking_plan (cyclomatic 16): tracking_plan_generator.generate_tracking_plan 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":"marketing-skill/skills/analytics-tracking/scripts/tracking_plan_generator.py"},"region":{"startLine":192}}}],"partialFingerprints":{"codehealthFindingId/v1":"d08938f8334716ecba43f4d6413d156fac21e992de4054d0e4609e9810d9360d"}},{"ruleId":"D1","level":"warning","message":{"text":"email_sequence_analyzer.analyze_subject_line (cyclomatic 16): email_sequence_analyzer.analyze_subject_line 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":"marketing-skill/skills/cold-email/scripts/email_sequence_analyzer.py"},"region":{"startLine":170}}}],"partialFingerprints":{"codehealthFindingId/v1":"38fe1266e6e24098229d79636a71725efa93237ff2a0b236ea571db0dbe2816d"}},{"ruleId":"D1","level":"warning","message":{"text":"FormAnalyzer.handle_starttag (cyclomatic 16): FormAnalyzer.handle_starttag 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":"marketing-skill/skills/form-cro/scripts/form_field_analyzer.py"},"region":{"startLine":31}}}],"partialFingerprints":{"codehealthFindingId/v1":"b47510d94d2bf806d92f499bd2da97863427a50040175afc2504ebc0c1f86c91"}},{"ruleId":"D1","level":"warning","message":{"text":"nap_checker.compare_nap (cyclomatic 16): nap_checker.compare_nap 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":"marketing-skill/skills/local-seo-manager/scripts/nap_checker.py"},"region":{"startLine":107}}}],"partialFingerprints":{"codehealthFindingId/v1":"12c0ff424e8085400f203ff91e6b8a59d533c4a3ea64e5d16af2297f4c58165f"}},{"ruleId":"D1","level":"warning","message":{"text":"roas_calculator._recommendations (cyclomatic 16): roas_calculator._recommendations 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":"marketing-skill/skills/paid-ads/scripts/roas_calculator.py"},"region":{"startLine":147}}}],"partialFingerprints":{"codehealthFindingId/v1":"9aa24d20c08a842dfbfc0755302285b2d0d10509d2fd37f0eca273f9dfe501d3"}},{"ruleId":"D1","level":"warning","message":{"text":"competitor_analyzer.analyze_competitors (cyclomatic 16): competitor_analyzer.analyze_competitors 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":"marketing-skill/skills/x-twitter-growth/scripts/competitor_analyzer.py"},"region":{"startLine":53}}}],"partialFingerprints":{"codehealthFindingId/v1":"18c3010bec1551c8014d451e50bbde5feba0892f3356c3001eef822bead43f33"}},{"ruleId":"D1","level":"warning","message":{"text":"brand_palette_validator.validate (cyclomatic 16): brand_palette_validator.validate 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":"marketing/landing/skills/landing/scripts/brand_palette_validator.py"},"region":{"startLine":127}}}],"partialFingerprints":{"codehealthFindingId/v1":"d1b3520b67121101313dcd88880a0273c9e5678796fab296b8fd63fa4c197fd2"}},{"ruleId":"D1","level":"warning","message":{"text":"post_performance_analyzer.analyse (cyclomatic 16): post_performance_analyzer.analyse 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":"marketing/linkedin/skills/linkedin-analytics/scripts/post_performance_analyzer.py"},"region":{"startLine":111}}}],"partialFingerprints":{"codehealthFindingId/v1":"67c9e05db415190a36a73e5fe31e9d3cf3067e0ab5e5c6d4bf6a6dcc9163be46"}},{"ruleId":"D1","level":"warning","message":{"text":"codebase_analyzer.extract_backend_routes (cyclomatic 16): codebase_analyzer.extract_backend_routes 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":"product-team/code-to-prd/skills/code-to-prd/scripts/codebase_analyzer.py"},"region":{"startLine":367}}}],"partialFingerprints":{"codehealthFindingId/v1":"9d90eb1ccb45ed437eec7825311eeeb83e72f37b87e74affc2b3f658e989cd71"}},{"ruleId":"D1","level":"warning","message":{"text":"discovery_cadence_tracker.analyze (cyclomatic 16): discovery_cadence_tracker.analyze 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":"product-team/skills/product-skills/scripts/discovery_cadence_tracker.py"},"region":{"startLine":64}}}],"partialFingerprints":{"codehealthFindingId/v1":"2aa82ab8cd074bf0e760b1f58d13fdd79286730c94a699f7805f35ad141520d4"}},{"ruleId":"D1","level":"warning","message":{"text":"weekly_review_gate.evaluate (cyclomatic 16): weekly_review_gate.evaluate 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":"productivity/weekly-review/skills/weekly-review/scripts/weekly_review_gate.py"},"region":{"startLine":86}}}],"partialFingerprints":{"codehealthFindingId/v1":"1967a327ed000dc00fb4561e1616cb2cde9aeff98f4fa01537fe3e20d2496978"}},{"ruleId":"D1","level":"warning","message":{"text":"delivery_loop_gate.check_plan (cyclomatic 16): delivery_loop_gate.check_plan 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":"project-management/skills/pm-skills/scripts/delivery_loop_gate.py"},"region":{"startLine":57}}}],"partialFingerprints":{"codehealthFindingId/v1":"523ebb9ad25143980cc14ee12d24f43ecc5fb1eb3648c1d1b55e22fb9c7ff212"}},{"ruleId":"D1","level":"warning","message":{"text":"jira_snapshot_bridge.sprint_export (cyclomatic 16): jira_snapshot_bridge.sprint_export 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":"project-management/skills/pm-skills/scripts/jira_snapshot_bridge.py"},"region":{"startLine":186}}}],"partialFingerprints":{"codehealthFindingId/v1":"a22408557e47bf685e7860f6f88a2186907e6e3e8c0a465e9df1303c4b652de6"}},{"ruleId":"D1","level":"warning","message":{"text":"regulatory_pathway_analyzer.format_analysis_text (cyclomatic 16): regulatory_pathway_analyzer.format_analysis_text has cyclomatic complexity 16 (threshold 15). To reduce it, break up the iteration: give each loop body a named function, and split a multi-phase loop into one function per phase so no single body carries the whole pipeline."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"ra-qm-team/skills/regulatory-affairs-head/scripts/regulatory_pathway_analyzer.py"},"region":{"startLine":385}}}],"partialFingerprints":{"codehealthFindingId/v1":"7d738b910d42283c534517e114abb754658694f2c7bf30c6acb229320dae6831"}},{"ruleId":"D1","level":"warning","message":{"text":"FMEAAnalyzer.analyze_entries (cyclomatic 16): FMEAAnalyzer.analyze_entries 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":"ra-qm-team/skills/risk-management-specialist/scripts/fmea_analyzer.py"},"region":{"startLine":130}}}],"partialFingerprints":{"codehealthFindingId/v1":"d6181afdd9d2651e1347f769bfdd8e74e6f676530a7b4abbfc19dde936098811"}},{"ruleId":"D1","level":"warning","message":{"text":"check_model_freshness.main (cyclomatic 16): check_model_freshness.main has cyclomatic complexity 16 (threshold 15). To reduce it, separate the cases: extract each independent branch into its own named function, and where the body has guards that only reject input, fold those into early returns at the top."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"scripts/check_model_freshness.py"},"region":{"startLine":171}}}],"partialFingerprints":{"codehealthFindingId/v1":"314c648dbfda455aed9c09aaf405ffa5051f0314a2d71ec09586f950b943a706"}},{"ruleId":"D1","level":"warning","message":{"text":"derive_counters.derive (cyclomatic 16): derive_counters.derive 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/derive_counters.py"},"region":{"startLine":79}}}],"partialFingerprints":{"codehealthFindingId/v1":"3051e98ca5d8db3b4e896d2acfdf05ce6ff39e80e8c15585d0300865c5cbe7ea"}},{"ruleId":"D1","level":"warning","message":{"text":"generate_reading_list.buildAuditLogSection (cyclomatic 16): generate_reading_list.buildAuditLogSection 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":"research/syllabus/skills/syllabus/scripts/generate_reading_list.js"},"region":{"startLine":263}}}],"partialFingerprints":{"codehealthFindingId/v1":"f0e29c89b1fdbb5c4720c1edf1e4f654be87cff8c3540f81834622b6ab65e588"}},{"ruleId":"D2","level":"warning","message":{"text":"generate-docs.main (cognitive 176): generate-docs.main has cognitive complexity 176 (threshold 15). Drivers by points: if/else 44 (121 pts), loops 22 (42 pts), boolean chains 10, ternaries 1 (3 pts) (nesting depth added 99). To reduce it, split the body into named stages: move each independent step or branch into 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/generate-docs.py"},"region":{"startLine":458}}}],"partialFingerprints":{"codehealthFindingId/v1":"99db25076bb3e1aab94efd6800d48474a1da0e7cc0848e82456ae0881760ef22"}},{"ruleId":"D2","level":"warning","message":{"text":"collect_sessions.parse_claude_session (cognitive 101): collect_sessions.parse_claude_session has cognitive complexity 101 (threshold 15). Drivers by points: if/else 20 (60 pts), boolean chains 17, ternaries 5 (14 pts), loops 3 (7 pts), error handling 2 (3 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":"engineering/skill-doctor/skills/skill-doctor/scripts/collect_sessions.py"},"region":{"startLine":252}}}],"partialFingerprints":{"codehealthFindingId/v1":"5ee045246a4d0dea9f1420ce567e60cc8bda61ed7eed1ad23539f8258e01a02a"}},{"ruleId":"D2","level":"warning","message":{"text":"threat_signal_analyzer.main (cognitive 93): threat_signal_analyzer.main has cognitive complexity 93 (threshold 15). Drivers by points: if/else 27 (62 pts), ternaries 4 (13 pts), loops 3 (11 pts), boolean chains 7 (nesting depth added 52). To reduce it, flatten the nesting: this score is depth rather than breadth \u2014 most of its points come from checks stacked inside one another, so the work sits several levels in. Invert each enclosing check into an early exit (a return, or the language\u0027s equivalent) so the happy path stays at one level, and where a level cannot be exited early, lift the block it encloses into its own named function."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/skills/threat-detection/scripts/threat_signal_analyzer.py"},"region":{"startLine":408}}}],"partialFingerprints":{"codehealthFindingId/v1":"b259fb8258642e14a3f187c1812cae59af82413594f300033c8f037136645bc0"}},{"ruleId":"D2","level":"warning","message":{"text":"okr_tracker.format_report (cognitive 90): okr_tracker.format_report has cognitive complexity 90 (threshold 15). Drivers by points: if/else 22 (44 pts), loops 15 (32 pts), ternaries 4 (14 pts) (nesting depth added 49). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"c-level-advisor/skills/coo-advisor/scripts/okr_tracker.py"},"region":{"startLine":406}}}],"partialFingerprints":{"codehealthFindingId/v1":"67a6b8be838fee48b21d296692eb95b89e908af57ea51d1dffe16375bb6024d8"}},{"ruleId":"D2","level":"warning","message":{"text":"compose_validator.parse_yaml_simple (cognitive 89): compose_validator.parse_yaml_simple has cognitive complexity 89 (threshold 15). Drivers by points: if/else 22 (74 pts), boolean chains 10, ternaries 1 (4 pts), loops 1 (nesting depth added 55). 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":"engineering/docker-development/skills/docker-development/scripts/compose_validator.py"},"region":{"startLine":59}}}],"partialFingerprints":{"codehealthFindingId/v1":"a3c70de045539a8a5b7a34a0118aeff5492c020642d93c9ba6d4e82cc1607b08"}},{"ruleId":"D2","level":"warning","message":{"text":"tc_validator.validate_tc_record (cognitive 83): tc_validator.validate_tc_record has cognitive complexity 83 (threshold 15). Drivers by points: if/else 37 (76 pts), loops 4 (7 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":"engineering/skills/tc-tracker/scripts/tc_validator.py"},"region":{"startLine":123}}}],"partialFingerprints":{"codehealthFindingId/v1":"35911b8c2d8d6c1f52dc1ef7e78570ccd8130f8c49f6037bb1162ae4a8ebd06a"}},{"ruleId":"D2","level":"warning","message":{"text":"dataset_pipeline_builder.main (cognitive 82): dataset_pipeline_builder.main has cognitive complexity 82 (threshold 15). Drivers by points: if/else 19 (49 pts), loops 6 (27 pts), ternaries 2 (5 pts), error handling 1 (nesting depth added 54). To reduce it, flatten the nesting: this score is depth rather than breadth \u2014 most of its points come from checks stacked inside one another, so the work sits several levels in. Invert each enclosing check into an early exit (a return, or the language\u0027s equivalent) so the happy path stays at one level, and where a level cannot be exited early, lift the block it encloses into its own named function."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/skills/senior-computer-vision/scripts/dataset_pipeline_builder.py"},"region":{"startLine":1506}}}],"partialFingerprints":{"codehealthFindingId/v1":"1ecf7a0fc37f4f915fc88c8bb7952828dc28f573568aef340002f96c74ee8ae3"}},{"ruleId":"D2","level":"warning","message":{"text":"openapi_to_mcp.extract_tools (cognitive 80): openapi_to_mcp.extract_tools has cognitive complexity 80 (threshold 15). Drivers by points: if/else 15 (63 pts), loops 4 (14 pts), boolean chains 3 (nesting depth added 58). To reduce it, flatten the nesting: this score is depth rather than breadth \u2014 most of its points come from checks stacked inside one another, so the work sits several levels in. Invert each enclosing check into an early exit (a return, or the language\u0027s equivalent) so the happy path stays at one level, and where a level cannot be exited early, lift the block it encloses into its own named function."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/mcp-server-builder/scripts/openapi_to_mcp.py"},"region":{"startLine":103}}}],"partialFingerprints":{"codehealthFindingId/v1":"df4f56abc4a8b99b3fec3498be159dc2c1ee804da28e896d7d01a4ccee04930d"}},{"ruleId":"D2","level":"warning","message":{"text":"comp_benchmarker.print_report (cognitive 75): comp_benchmarker.print_report has cognitive complexity 75 (threshold 15). Drivers by points: if/else 22 (35 pts), ternaries 8 (18 pts), loops 9 (16 pts), boolean chains 6 (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":"c-level-advisor/skills/chro-advisor/scripts/comp_benchmarker.py"},"region":{"startLine":275}}}],"partialFingerprints":{"codehealthFindingId/v1":"f585124f8377fa92daf61206f0b9fbdaa8294958b41d108217f1c608793aba80"}},{"ruleId":"D2","level":"warning","message":{"text":"compose_validator.validate_compose (cognitive 75): compose_validator.validate_compose has cognitive complexity 75 (threshold 15). Drivers by points: if/else 19 (51 pts), loops 6 (14 pts), boolean chains 7, ternaries 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":"engineering/docker-development/skills/docker-development/scripts/compose_validator.py"},"region":{"startLine":156}}}],"partialFingerprints":{"codehealthFindingId/v1":"bc60a5388a813a81e480e9927f7018784cb9e71d97106f78bf2b7f3af8c068ae"}},{"ruleId":"D2","level":"warning","message":{"text":"collect_sessions.main (cognitive 72): collect_sessions.main has cognitive complexity 72 (threshold 15). Drivers by points: if/else 20 (47 pts), loops 5 (12 pts), boolean chains 8, error handling 1 (4 pts), ternaries 1 (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":"engineering/skill-doctor/skills/skill-doctor/scripts/collect_sessions.py"},"region":{"startLine":627}}}],"partialFingerprints":{"codehealthFindingId/v1":"caa83a50885a192d23895e39b9ea54a354e791d0aa027bc0fc4ecedd05713868"}},{"ruleId":"D2","level":"warning","message":{"text":"auth_setup_guide.main (cognitive 70): auth_setup_guide.main has cognitive complexity 70 (threshold 15). Drivers by points: if/else 26 (46 pts), loops 6 (20 pts), ternaries 1 (4 pts) (nesting depth added 37). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/google-workspace-cli/skills/google-workspace-cli/scripts/auth_setup_guide.py"},"region":{"startLine":281}}}],"partialFingerprints":{"codehealthFindingId/v1":"667f15fbfe57870a183e8b041702ea6223b46d40a518257021eb579b1ac62818"}},{"ruleId":"D2","level":"warning","message":{"text":"policy_linter.lint (cognitive 69): policy_linter.lint has cognitive complexity 69 (threshold 15). Drivers by points: if/else 16 (35 pts), loops 14 (16 pts), ternaries 5 (11 pts), boolean chains 7 (nesting depth added 27). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"commercial/skills/commercial-policy/scripts/policy_linter.py"},"region":{"startLine":114}}}],"partialFingerprints":{"codehealthFindingId/v1":"1ced369fa02beca3b77c57e1b44982052c9204df0c12c959f986daf8fc38c538"}},{"ruleId":"D2","level":"warning","message":{"text":"score.render_text (cognitive 69): score.render_text has cognitive complexity 69 (threshold 15). Drivers by points: if/else 24 (46 pts), loops 7 (13 pts), boolean chains 7, ternaries 1 (3 pts) (nesting depth added 30). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"finance/skills/stock-analysis/scripts/score.py"},"region":{"startLine":1263}}}],"partialFingerprints":{"codehealthFindingId/v1":"d8180cb712481ddba6e81842ef6b07d73e4ebd1fe75e0b6a205913b859f433e1"}},{"ruleId":"D2","level":"warning","message":{"text":"feedback_parser.parse (cognitive 68): feedback_parser.parse has cognitive complexity 68 (threshold 15). Drivers by points: if/else 21 (47 pts), boolean chains 7, loops 4 (6 pts), error handling 1 (5 pts), ternaries 1 (3 pts) (nesting depth added 34). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/human-gate/skills/human-gate/scripts/feedback_parser.py"},"region":{"startLine":173}}}],"partialFingerprints":{"codehealthFindingId/v1":"092f08373cbee9c5df529a9dd85da7ab115fc1bb08ac37470249f4b1345524d9"}},{"ruleId":"D2","level":"warning","message":{"text":"profile_completeness_auditor.evaluate_check (cognitive 68): profile_completeness_auditor.evaluate_check has cognitive complexity 68 (threshold 15). Drivers by points: if/else 26 (38 pts), ternaries 10 (20 pts), boolean chains 10 (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":"marketing/linkedin/skills/linkedin-profile/scripts/profile_completeness_auditor.py"},"region":{"startLine":104}}}],"partialFingerprints":{"codehealthFindingId/v1":"d9cec91742fe9c9b5c8bf612ea480fc62cdffc8d7c85d54797cd0cd35f62dc80"}},{"ruleId":"D2","level":"warning","message":{"text":"tc_update.main (cognitive 67): tc_update.main has cognitive complexity 67 (threshold 15). Drivers by points: ternaries 11 (24 pts), if/else 14 (19 pts), boolean chains 13, loops 6, error handling 4 (5 pts) (nesting depth added 19). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/tc-tracker/scripts/tc_update.py"},"region":{"startLine":128}}}],"partialFingerprints":{"codehealthFindingId/v1":"e29ddc9e4cecb6c47d9952fe1e13ac55f77a7f5e8dd88e9b8826d57a10a4e2ed"}},{"ruleId":"D2","level":"warning","message":{"text":"ai_threat_scanner.main (cognitive 64): ai_threat_scanner.main has cognitive complexity 64 (threshold 15). Drivers by points: if/else 20 (37 pts), loops 6 (13 pts), boolean chains 5, ternaries 4 (5 pts), error handling 2 (4 pts) (nesting depth added 27). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/skills/ai-security/scripts/ai_threat_scanner.py"},"region":{"startLine":322}}}],"partialFingerprints":{"codehealthFindingId/v1":"1da21e06652ab000b4fb0be69e42e5f8ef24526141242b60a32f0dbbb1ec2b78"}},{"ruleId":"D2","level":"warning","message":{"text":"payload_validator.validate (cognitive 63): payload_validator.validate has cognitive complexity 63 (threshold 15). Drivers by points: if/else 24 (42 pts), error handling 3 (7 pts), loops 5 (7 pts), ternaries 4, boolean chains 3 (nesting depth added 24). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"agent-launcher/skills/stage-launch/scripts/payload_validator.py"},"region":{"startLine":38}}}],"partialFingerprints":{"codehealthFindingId/v1":"a7336e987de93c1a9241557b22d89cea02f7ab918367c14641730efb5e153d67"}},{"ruleId":"D2","level":"warning","message":{"text":"utils.extract_single_file (cognitive 62): utils.extract_single_file has cognitive complexity 62 (threshold 15). Drivers by points: if/else 27 (49 pts), boolean chains 9, error handling 1 (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":"engineering/book-to-skill/skills/book-to-skill/scripts/book_to_skill/utils.py"},"region":{"startLine":400}}}],"partialFingerprints":{"codehealthFindingId/v1":"2ded090c604c5f1a5730a85c3696eb46ddf576ee6c88034b3a68630d171d6b71"}},{"ruleId":"D2","level":"warning","message":{"text":"model_arithmetic.step (cognitive 62): model_arithmetic.step has cognitive complexity 62 (threshold 15). Drivers by points: if/else 24 (38 pts), ternaries 7 (15 pts), boolean chains 4, error handling 1 (3 pts), loops 1 (2 pts) (nesting depth added 25). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/deep-learning-book/skills/deep-learning-book/scripts/model_arithmetic.py"},"region":{"startLine":98}}}],"partialFingerprints":{"codehealthFindingId/v1":"dc758d2ec05da6261ba8ed0c3007444b4525ae6747f5491fbfbf23c638cfe999"}},{"ruleId":"D2","level":"warning","message":{"text":"score.render_segmented_text (cognitive 62): score.render_segmented_text has cognitive complexity 62 (threshold 15). Drivers by points: if/else 23 (39 pts), loops 8 (12 pts), ternaries 2 (6 pts), boolean chains 5 (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":"finance/skills/stock-analysis/scripts/score.py"},"region":{"startLine":1396}}}],"partialFingerprints":{"codehealthFindingId/v1":"70bde7f15430f0df7ce9483c3f5de10b1d686cb0b86f8a71a0ae251ec203b126"}},{"ruleId":"D2","level":"warning","message":{"text":"resource_capacity_planner.optimize_resource_allocation (cognitive 62): resource_capacity_planner.optimize_resource_allocation has cognitive complexity 62 (threshold 15). Drivers by points: if/else 12 (41 pts), loops 6 (18 pts), boolean chains 3 (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":"project-management/skills/senior-pm/scripts/resource_capacity_planner.py"},"region":{"startLine":370}}}],"partialFingerprints":{"codehealthFindingId/v1":"866f533d76229a780cf495229c36ab14329b40caf8eeea22e14b5368e5fe7145"}},{"ruleId":"D2","level":"warning","message":{"text":"collect_sessions.parse_codex_session (cognitive 61): collect_sessions.parse_codex_session has cognitive complexity 61 (threshold 15). Drivers by points: if/else 15 (46 pts), boolean chains 11, error handling 2 (3 pts), loops 1 (nesting depth added 32). To reduce it, flatten the nesting: this score is depth rather than breadth \u2014 most of its points come from checks stacked inside one another, so the work sits several levels in. Invert each enclosing check into an early exit (a return, or the language\u0027s equivalent) so the happy path stays at one level, and where a level cannot be exited early, lift the block it encloses into its own named function."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skill-doctor/skills/skill-doctor/scripts/collect_sessions.py"},"region":{"startLine":391}}}],"partialFingerprints":{"codehealthFindingId/v1":"baa7eb6942e42ae2686256b7b5612ddf2df931f21284d04c0ca26fec1a65566b"}},{"ruleId":"D2","level":"warning","message":{"text":"schema_validator.score_schema (cognitive 60): schema_validator.score_schema has cognitive complexity 60 (threshold 15). Drivers by points: if/else 21 (41 pts), ternaries 5 (9 pts), boolean chains 7, loops 1 (3 pts) (nesting depth added 26). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"marketing-skill/skills/schema-markup/scripts/schema_validator.py"},"region":{"startLine":126}}}],"partialFingerprints":{"codehealthFindingId/v1":"6d761928980f9095da29a056552c6b114fe194165090b002f9a171a5a0bd1f2b"}},{"ruleId":"D2","level":"warning","message":{"text":"mechanism_matcher.match (cognitive 60): mechanism_matcher.match has cognitive complexity 60 (threshold 15). Drivers by points: if/else 27 (51 pts), boolean chains 8, loops 1 (nesting depth added 24). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"research/grants/skills/grants/scripts/mechanism_matcher.py"},"region":{"startLine":54}}}],"partialFingerprints":{"codehealthFindingId/v1":"39c3d71a662959b3de2cc375375d9b5c2fa4b4f5ebdca4f26bf58a6546bbe391"}},{"ruleId":"D2","level":"warning","message":{"text":"OKRGenerator.generate_okr_dashboard (cognitive 59): OKRGenerator.generate_okr_dashboard has cognitive complexity 59 (threshold 15). Drivers by points: loops 11 (37 pts), if/else 7 (21 pts), boolean chains 1 (nesting depth added 40). 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":"product-team/skills/product-strategist/scripts/okr_cascade_generator.py"},"region":{"startLine":247}}}],"partialFingerprints":{"codehealthFindingId/v1":"aae2617c0d111d101b18a4076409f63a9d02c9266c7409baf3c9687bd061cff1"}},{"ruleId":"D2","level":"warning","message":{"text":"qsr_compliance_checker.search_documentation (cognitive 59): qsr_compliance_checker.search_documentation has cognitive complexity 59 (threshold 15). Drivers by points: if/else 7 (22 pts), loops 8 (20 pts), error handling 3 (11 pts), ternaries 1 (4 pts), boolean chains 2 (nesting depth added 38). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"ra-qm-team/skills/fda-consultant-specialist/scripts/qsr_compliance_checker.py"},"region":{"startLine":348}}}],"partialFingerprints":{"codehealthFindingId/v1":"7c8ecdba66e10d287295cdce347152cee09b7573cd75a662ce41f62b435c7595"}},{"ruleId":"D2","level":"warning","message":{"text":"result_ranker.main (cognitive 58): result_ranker.main has cognitive complexity 58 (threshold 15). Drivers by points: if/else 19 (30 pts), ternaries 5 (14 pts), boolean chains 8, loops 4 (6 pts) (nesting depth added 22). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/agenthub/skills/agenthub/scripts/result_ranker.py"},"region":{"startLine":187}}}],"partialFingerprints":{"codehealthFindingId/v1":"f9dd1bae65514d2d426149a16fbccd73c8aab9e4f132b281053a9ec489fa2690"}},{"ruleId":"D2","level":"warning","message":{"text":"version_bumper.main (cognitive 58): version_bumper.main has cognitive complexity 58 (threshold 15). Drivers by points: if/else 19 (30 pts), loops 6 (18 pts), error handling 4 (5 pts), ternaries 1 (5 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":"engineering/skills/changelog-generator/scripts/version_bumper.py"},"region":{"startLine":467}}}],"partialFingerprints":{"codehealthFindingId/v1":"c43caf14570d2cfc55b9a0db8e55cb4441951ba19b8c7744dc07d21b27f481b9"}},{"ruleId":"D2","level":"warning","message":{"text":"score_aggregator.validate (cognitive 55): score_aggregator.validate has cognitive complexity 55 (threshold 15). Drivers by points: if/else 17 (37 pts), boolean chains 9, loops 6 (9 pts) (nesting depth added 23). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skill-doctor/skills/skill-doctor/scripts/score_aggregator.py"},"region":{"startLine":114}}}],"partialFingerprints":{"codehealthFindingId/v1":"8dba8aeeef644fac6389a9c4e2a70cd16f5a13fb145d7724c5ab8e73d2d5d986"}},{"ruleId":"D2","level":"warning","message":{"text":"contrast_checker.main (cognitive 54): contrast_checker.main has cognitive complexity 54 (threshold 15). Drivers by points: if/else 18 (32 pts), error handling 6 (11 pts), loops 2 (5 pts), boolean chains 3, ternaries 2 (3 pts) (nesting depth added 23). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/a11y-audit/skills/a11y-audit/scripts/contrast_checker.py"},"region":{"startLine":364}}}],"partialFingerprints":{"codehealthFindingId/v1":"6ff94767e6b1c6c966a995aed229036654be1ba342c3fe364aaa3965c013f920"}},{"ruleId":"D2","level":"warning","message":{"text":"ops_efficiency_analyzer.format_report (cognitive 53): ops_efficiency_analyzer.format_report has cognitive complexity 53 (threshold 15). Drivers by points: ternaries 10 (27 pts), if/else 10 (14 pts), loops 7 (12 pts) (nesting depth added 26). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"c-level-advisor/skills/coo-advisor/scripts/ops_efficiency_analyzer.py"},"region":{"startLine":607}}}],"partialFingerprints":{"codehealthFindingId/v1":"f935042a112315784b024b923f24da61dcb417bb14505b02914934ec18a9cb94"}},{"ruleId":"D2","level":"warning","message":{"text":"html_validator.validate (cognitive 53): html_validator.validate has cognitive complexity 53 (threshold 15). Drivers by points: if/else 38 (39 pts), boolean chains 8, ternaries 3 (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, 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":"marketing/landing/skills/landing/scripts/html_validator.py"},"region":{"startLine":113}}}],"partialFingerprints":{"codehealthFindingId/v1":"b73d17519aa060e5061602a4e140b36ac19378443bf11978e9e72d59a8dbcc14"}},{"ruleId":"D2","level":"warning","message":{"text":"validate_examples.main (cognitive 52): validate_examples.main has cognitive complexity 52 (threshold 15). Drivers by points: if/else 13 (26 pts), loops 14 (20 pts), ternaries 3 (5 pts), boolean chains 1 (nesting depth added 21). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/agent-memory/skills/agent-memory/scripts/validate_examples.py"},"region":{"startLine":195}}}],"partialFingerprints":{"codehealthFindingId/v1":"ec704fdf9ba25357e1af2d16756c687be41985b956a35e93b9e29fdb7eb3fc1a"}},{"ruleId":"D2","level":"warning","message":{"text":"score.run_scorecard (cognitive 52): score.run_scorecard has cognitive complexity 52 (threshold 15). Drivers by points: if/else 17 (25 pts), boolean chains 17, loops 5 (6 pts), error handling 1 (2 pts), ternaries 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":"finance/skills/stock-analysis/scripts/score.py"},"region":{"startLine":637}}}],"partialFingerprints":{"codehealthFindingId/v1":"f929b708ef63d9ebbd013db8a53fe3f755e916549f3b353246be0c6417401ddb"}},{"ruleId":"D2","level":"warning","message":{"text":"sync-codex-skills.find_skills (cognitive 52): sync-codex-skills.find_skills has cognitive complexity 52 (threshold 15). Drivers by points: if/else 10 (40 pts), loops 4 (10 pts), boolean chains 2 (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":"scripts/sync-codex-skills.py"},"region":{"startLine":98}}}],"partialFingerprints":{"codehealthFindingId/v1":"2364f5d1315e7f53700e5796180f191de0e157f92cd3d198baef056e67aa1f6f"}},{"ruleId":"D2","level":"warning","message":{"text":"threat_signal_analyzer.anomaly_mode (cognitive 50): threat_signal_analyzer.anomaly_mode has cognitive complexity 50 (threshold 15). Drivers by points: if/else 13 (22 pts), error handling 5 (13 pts), ternaries 4 (8 pts), loops 2 (4 pts), boolean chains 3 (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":"engineering-team/skills/threat-detection/scripts/threat_signal_analyzer.py"},"region":{"startLine":262}}}],"partialFingerprints":{"codehealthFindingId/v1":"8395837f0c10214e2672ad2d5de5affb2e26e463fd61105a6d6ad2a4bb5d6a17"}},{"ruleId":"D2","level":"warning","message":{"text":"primitives_validator.validate (cognitive 49): primitives_validator.validate has cognitive complexity 49 (threshold 15). Drivers by points: if/else 25 (34 pts), boolean chains 7, loops 3 (4 pts), error handling 1 (2 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":"agent-launcher/skills/interview/scripts/primitives_validator.py"},"region":{"startLine":31}}}],"partialFingerprints":{"codehealthFindingId/v1":"f877e1981aa5fb8acdfe392355d5c0b615351ec59bcad1c80b7262d118744f21"}},{"ruleId":"D2","level":"warning","message":{"text":"lint_report.check_blank_cells (cognitive 49): lint_report.check_blank_cells has cognitive complexity 49 (threshold 15). Drivers by points: if/else 9 (28 pts), loops 6 (13 pts), boolean chains 5, ternaries 1 (3 pts) (nesting depth added 28). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"finance/skills/stock-analysis/scripts/lint_report.py"},"region":{"startLine":629}}}],"partialFingerprints":{"codehealthFindingId/v1":"af1423f67e7347f422c160019d1c5397463809dba040d186505a3b87998645fc"}},{"ruleId":"D2","level":"warning","message":{"text":"codebase_analyzer.analyze_project (cognitive 49): codebase_analyzer.analyze_project has cognitive complexity 49 (threshold 15). Drivers by points: if/else 14 (22 pts), loops 9 (12 pts), boolean chains 9, ternaries 5 (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":"product-team/code-to-prd/skills/code-to-prd/scripts/codebase_analyzer.py"},"region":{"startLine":463}}}],"partialFingerprints":{"codehealthFindingId/v1":"bcf6b392f4fe25e4a4c2b212fd816ee038f19f5a1f628b3b1b320be32e8d99b2"}},{"ruleId":"D2","level":"warning","message":{"text":"sync-gemini-skills.find_skills (cognitive 49): sync-gemini-skills.find_skills has cognitive complexity 49 (threshold 15). Drivers by points: if/else 15 (33 pts), loops 5 (10 pts), boolean chains 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":"scripts/sync-gemini-skills.py"},"region":{"startLine":44}}}],"partialFingerprints":{"codehealthFindingId/v1":"fee7853c847e66f3b05bc5335444109a1aae2b40f4ec172c16970d3ef82c8b12"}},{"ruleId":"D2","level":"warning","message":{"text":"pricing_model_picker.score_models (cognitive 48): pricing_model_picker.score_models has cognitive complexity 48 (threshold 15). Drivers by points: if/else 22 (25 pts), boolean chains 21, loops 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."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"commercial/skills/pricing-strategist/scripts/pricing_model_picker.py"},"region":{"startLine":85}}}],"partialFingerprints":{"codehealthFindingId/v1":"c16653dd8d37593bc57d0247db5cca54af2235a6fbbe392186a9e055716fec7c"}},{"ruleId":"D2","level":"warning","message":{"text":"PaymentProcessor.process_payment (cognitive 48): PaymentProcessor.process_payment has cognitive complexity 48 (threshold 15). Drivers by points: if/else 22 (37 pts), error handling 3 (8 pts), boolean chains 3 (nesting depth added 20). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/tech-debt-tracker/assets/sample_codebase/src/payment_processor.py"},"region":{"startLine":27}}}],"partialFingerprints":{"codehealthFindingId/v1":"aa68e346cf9ad33b4bf854beab0b5ad612af0108ee462b3868461e759573f607"}},{"ruleId":"D2","level":"warning","message":{"text":"cloud_posture_check.main (cognitive 47): cloud_posture_check.main has cognitive complexity 47 (threshold 15). Drivers by points: if/else 23 (35 pts), loops 3 (8 pts), boolean chains 2, error handling 2 (nesting depth added 17). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/skills/cloud-security/scripts/cloud_posture_check.py"},"region":{"startLine":967}}}],"partialFingerprints":{"codehealthFindingId/v1":"276f2c5346ec9c91c5b0dc00a9eaf0c8b404b00c9d347cf3942e277a7e64a48e"}},{"ruleId":"D2","level":"warning","message":{"text":"dependencies.run_dependency_check (cognitive 47): dependencies.run_dependency_check has cognitive complexity 47 (threshold 15). Drivers by points: if/else 15 (29 pts), ternaries 3 (10 pts), loops 4 (6 pts), boolean chains 2 (nesting depth added 23). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/book-to-skill/skills/book-to-skill/scripts/book_to_skill/dependencies.py"},"region":{"startLine":236}}}],"partialFingerprints":{"codehealthFindingId/v1":"1f53ca3085d13b9ba147384ab5a0c20f202b1be2c1e497b2d300d38eae7d4db2"}},{"ruleId":"D2","level":"warning","message":{"text":"IndexOptimizer.analyze_missing_indexes (cognitive 47): IndexOptimizer.analyze_missing_indexes has cognitive complexity 47 (threshold 15). Drivers by points: if/else 12 (38 pts), loops 3 (5 pts), boolean chains 4 (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":"engineering/skills/database-designer/index_optimizer.py"},"region":{"startLine":227}}}],"partialFingerprints":{"codehealthFindingId/v1":"3eb44605deed57f9159aa726e1860c6bd51324a4f479ee8bbf1c8498e36d2fbf"}},{"ruleId":"D2","level":"warning","message":{"text":"decision_tracker.parse_decisions (cognitive 46): decision_tracker.parse_decisions has cognitive complexity 46 (threshold 15). Drivers by points: if/else 20 (42 pts), boolean chains 3, 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":"c-level-advisor/skills/decision-logger/scripts/decision_tracker.py"},"region":{"startLine":141}}}],"partialFingerprints":{"codehealthFindingId/v1":"4855cd270e0893af124fb3db18a856a9358569a07d6793b5e07a88344c4b91e8"}},{"ruleId":"D2","level":"warning","message":{"text":"UserService.create_user (cognitive 46): UserService.create_user has cognitive complexity 46 (threshold 15). Drivers by points: if/else 25 (46 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":"engineering/skills/tech-debt-tracker/assets/sample_codebase/src/user_service.py"},"region":{"startLine":24}}}],"partialFingerprints":{"codehealthFindingId/v1":"6bc26eec750a77f23f3c09e462ef9f510eb5d164ea85844baa9fab34402a6621"}},{"ruleId":"D2","level":"warning","message":{"text":"cloud_posture_check.check_security_group (cognitive 45): cloud_posture_check.check_security_group has cognitive complexity 45 (threshold 15). Drivers by points: if/else 12 (25 pts), loops 6 (12 pts), boolean chains 4, ternaries 1 (4 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":"engineering-team/skills/cloud-security/scripts/cloud_posture_check.py"},"region":{"startLine":724}}}],"partialFingerprints":{"codehealthFindingId/v1":"26256d52a9e4b069f6042ab940d327ac18559846d3d8c8c39277a565ff4cdb80"}},{"ruleId":"D2","level":"warning","message":{"text":"score_aggregator.main (cognitive 45): score_aggregator.main has cognitive complexity 45 (threshold 15). Drivers by points: if/else 16 (26 pts), loops 4 (10 pts), ternaries 4 (7 pts), error handling 1 (2 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":"engineering/skill-doctor/skills/skill-doctor/scripts/score_aggregator.py"},"region":{"startLine":289}}}],"partialFingerprints":{"codehealthFindingId/v1":"23e46dd915ada79c2dfe43e5426e8233111d5a20999cffb0e043a0a3a45bd7a1"}},{"ruleId":"D2","level":"warning","message":{"text":"adr_scanner.scan_directory (cognitive 44): adr_scanner.scan_directory has cognitive complexity 44 (threshold 15). Drivers by points: if/else 21 (35 pts), loops 4, ternaries 2 (4 pts), boolean chains 1 (nesting depth added 16). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/grill-with-docs/skills/grill-with-docs/scripts/adr_scanner.py"},"region":{"startLine":87}}}],"partialFingerprints":{"codehealthFindingId/v1":"b4890b333534347bcf8564a549bab64425ffd98df4e1454b9bf7e66db0931e21"}},{"ruleId":"D2","level":"warning","message":{"text":"SQLParser._parse_table_body (cognitive 43): SQLParser._parse_table_body has cognitive complexity 43 (threshold 15). Drivers by points: if/else 12 (37 pts), ternaries 1 (4 pts), boolean chains 1, loops 1 (nesting depth added 28). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/skills/senior-backend/scripts/database_migration_tool.py"},"region":{"startLine":127}}}],"partialFingerprints":{"codehealthFindingId/v1":"d9d7fa42b43e255ca04da83817fe22dcdcb0957b1f4ca7f7e84a8cf461e1253f"}},{"ruleId":"D2","level":"warning","message":{"text":"chart_analyzer.check_security (cognitive 43): chart_analyzer.check_security has cognitive complexity 43 (threshold 15). Drivers by points: if/else 13 (33 pts), boolean chains 6, loops 3 (4 pts) (nesting depth added 21). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/helm-chart-builder/skills/helm-chart-builder/scripts/chart_analyzer.py"},"region":{"startLine":331}}}],"partialFingerprints":{"codehealthFindingId/v1":"d3290e9ccd185ccaa85cbca2e30599c963142359ef5ca0a393eed6bfbb932fe8"}},{"ruleId":"D2","level":"warning","message":{"text":"lint_wiki.scan (cognitive 43): lint_wiki.scan has cognitive complexity 43 (threshold 15). Drivers by points: if/else 16 (31 pts), loops 6 (8 pts), error handling 1 (3 pts), boolean chains 1 (nesting depth added 19). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/llm-wiki/skills/llm-wiki/scripts/lint_wiki.py"},"region":{"startLine":44}}}],"partialFingerprints":{"codehealthFindingId/v1":"aef8c56be8dc6e43dd4047e000d6520febc6e070b070c48f6957be1f5a51cc8b"}},{"ruleId":"D2","level":"warning","message":{"text":"valuation.render_text (cognitive 43): valuation.render_text has cognitive complexity 43 (threshold 15). Drivers by points: if/else 14 (17 pts), loops 5 (10 pts), ternaries 4 (10 pts), boolean chains 6 (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":"finance/skills/stock-analysis/scripts/valuation.py"},"region":{"startLine":648}}}],"partialFingerprints":{"codehealthFindingId/v1":"f4e9bf8335e40d8b47525c24d6874037bad1776b5f96b4b296bf4aa7428eedf4"}},{"ruleId":"D2","level":"warning","message":{"text":"repurpose_splitter.main (cognitive 43): repurpose_splitter.main has cognitive complexity 43 (threshold 15). Drivers by points: if/else 12 (17 pts), ternaries 6 (11 pts), loops 4 (8 pts), boolean chains 5, error handling 1 (2 pts) (nesting depth added 15). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"marketing/linkedin/skills/linkedin-content/scripts/repurpose_splitter.py"},"region":{"startLine":196}}}],"partialFingerprints":{"codehealthFindingId/v1":"a21364ec3206996c9d91987210629372dadaf7e5f65965c00baad91e2eaffc45"}},{"ruleId":"D2","level":"warning","message":{"text":"sync-hermes-skills.discover_skills (cognitive 43): sync-hermes-skills.discover_skills has cognitive complexity 43 (threshold 15). Drivers by points: if/else 9 (29 pts), loops 4 (9 pts), boolean chains 5 (nesting depth added 25). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"scripts/sync-hermes-skills.py"},"region":{"startLine":58}}}],"partialFingerprints":{"codehealthFindingId/v1":"0acac57038841d50038b7e873121e41310cd8ad0a6bf8326643ea4fcb18a0e6f"}},{"ruleId":"D2","level":"warning","message":{"text":"sync-vibe-skills.discover_skills (cognitive 43): sync-vibe-skills.discover_skills has cognitive complexity 43 (threshold 15). Drivers by points: if/else 9 (29 pts), loops 4 (9 pts), boolean chains 5 (nesting depth added 25). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"scripts/sync-vibe-skills.py"},"region":{"startLine":71}}}],"partialFingerprints":{"codehealthFindingId/v1":"d2050a9468edc51cd29bb2d844e48f2e48aa678ee8704f3c6e5726903c47a8e6"}},{"ruleId":"D2","level":"warning","message":{"text":"discount_matrix_builder.build_matrix (cognitive 42): discount_matrix_builder.build_matrix has cognitive complexity 42 (threshold 15). Drivers by points: ternaries 4 (20 pts), loops 5 (11 pts), if/else 2 (10 pts), boolean chains 1 (nesting depth added 30). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"commercial/skills/commercial-policy/scripts/discount_matrix_builder.py"},"region":{"startLine":148}}}],"partialFingerprints":{"codehealthFindingId/v1":"30d8c8daab61338adb0a3d3a3d342f59fde7872a9651f5c0ac22c5bdfefa8353"}},{"ruleId":"D2","level":"warning","message":{"text":"skill_security_auditor.scan_dependencies (cognitive 42): skill_security_auditor.scan_dependencies has cognitive complexity 42 (threshold 15). Drivers by points: if/else 9 (24 pts), loops 5 (10 pts), boolean chains 4, error handling 2 (4 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":"engineering/skills/skill-security-auditor/scripts/skill_security_auditor.py"},"region":{"startLine":682}}}],"partialFingerprints":{"codehealthFindingId/v1":"f761cce7f530fcb5884be832c2689c268ece9bfee0dd6204a9e8f3bbe28e0628"}},{"ruleId":"D2","level":"warning","message":{"text":"okf_linter.lint (cognitive 41): okf_linter.lint has cognitive complexity 41 (threshold 15). Drivers by points: if/else 11 (26 pts), loops 5 (7 pts), ternaries 2 (4 pts), boolean chains 2, error handling 1 (2 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":"c-level-advisor/arquiteto-de-empresa/skills/arquiteto-de-empresa/scripts/okf_linter.py"},"region":{"startLine":55}}}],"partialFingerprints":{"codehealthFindingId/v1":"64575687eb55971a63304cebb006400148c39c4f3a1af4b617323dba6839ab25"}},{"ruleId":"D2","level":"warning","message":{"text":"okf_linter.lint (cognitive 41): okf_linter.lint has cognitive complexity 41 (threshold 15). Drivers by points: if/else 11 (26 pts), loops 5 (7 pts), ternaries 2 (4 pts), boolean chains 2, error handling 1 (2 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":"c-level-advisor/skills/arquiteto-de-empresa/scripts/okf_linter.py"},"region":{"startLine":55}}}],"partialFingerprints":{"codehealthFindingId/v1":"2586c4edc813dd6856dd8f764d264f9eb40549394e1a476ae95a02b1ace7d0e1"}},{"ruleId":"D2","level":"warning","message":{"text":"churn_analyzer.print_full_report (cognitive 41): churn_analyzer.print_full_report has cognitive complexity 41 (threshold 15). Drivers by points: ternaries 9 (17 pts), if/else 14 (15 pts), loops 5 (8 pts), boolean chains 1 (nesting depth added 12). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"c-level-advisor/skills/cro-advisor/scripts/churn_analyzer.py"},"region":{"startLine":441}}}],"partialFingerprints":{"codehealthFindingId/v1":"a22bd48269f2af801d3d12c9efddf1331f48563082c8fab84072f1093db5d2a0"}},{"ruleId":"D2","level":"warning","message":{"text":"cloud_posture_check.analyze_statement (cognitive 41): cloud_posture_check.analyze_statement has cognitive complexity 41 (threshold 15). Drivers by points: if/else 15 (35 pts), ternaries 2 (4 pts), loops 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":"engineering-team/skills/cloud-security/scripts/cloud_posture_check.py"},"region":{"startLine":288}}}],"partialFingerprints":{"codehealthFindingId/v1":"b859f17a28f1f928e0c4c0b862e0ee052e690a58283c637a262e55846e7e5a9d"}},{"ruleId":"D2","level":"warning","message":{"text":"DataContractValidator._parse_simple_yaml (cognitive 41): DataContractValidator._parse_simple_yaml has cognitive complexity 41 (threshold 15). Drivers by points: if/else 8 (21 pts), ternaries 2 (10 pts), loops 3 (7 pts), boolean chains 3 (nesting depth added 25). To reduce it, flatten the nesting: this score is depth rather than breadth \u2014 most of its points come from checks stacked inside one another, so the work sits several levels in. Invert each enclosing check into an early exit (a return, or the language\u0027s equivalent) so the happy path stays at one level, and where a level cannot be exited early, lift the block it encloses into its own named function."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/skills/senior-data-engineer/scripts/data_quality_validator.py"},"region":{"startLine":937}}}],"partialFingerprints":{"codehealthFindingId/v1":"d505f46b235a68a04e17bb3f2b8519b3a58f090995457a94e8937e85524e2a6f"}},{"ruleId":"D2","level":"warning","message":{"text":"ship_gate_scanner.main (cognitive 41): ship_gate_scanner.main has cognitive complexity 41 (threshold 15). Drivers by points: if/else 14 (26 pts), ternaries 3 (6 pts), boolean chains 3, error handling 1 (3 pts), 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":"engineering/skills/ship-gate/scripts/ship_gate_scanner.py"},"region":{"startLine":1147}}}],"partialFingerprints":{"codehealthFindingId/v1":"fa9103ade488314c916377f26dde9f47f8fcd56c8c1ace22764e45241822a519"}},{"ruleId":"D2","level":"warning","message":{"text":"positioning_brief.validate (cognitive 41): positioning_brief.validate has cognitive complexity 41 (threshold 15). Drivers by points: if/else 15 (22 pts), boolean chains 11, ternaries 4 (6 pts), loops 1 (2 pts) (nesting depth added 10). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"marketing/linkedin/skills/linkedin-strategy/scripts/positioning_brief.py"},"region":{"startLine":117}}}],"partialFingerprints":{"codehealthFindingId/v1":"48872539866d6677cef2867594df62ba69928198604d3950e12304b377118f9c"}},{"ruleId":"D2","level":"warning","message":{"text":"codebase_analyzer.detect_framework (cognitive 41): codebase_analyzer.detect_framework has cognitive complexity 41 (threshold 15). Drivers by points: if/else 10 (24 pts), loops 4 (7 pts), error handling 2 (6 pts), boolean chains 4 (nesting depth added 21). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"product-team/code-to-prd/skills/code-to-prd/scripts/codebase_analyzer.py"},"region":{"startLine":163}}}],"partialFingerprints":{"codehealthFindingId/v1":"1683eb86e67c6f44f136aa57540b01e53f9213572dbc33319e08cd75596c657d"}},{"ruleId":"D2","level":"warning","message":{"text":"codebase_analyzer.format_markdown (cognitive 41): codebase_analyzer.format_markdown has cognitive complexity 41 (threshold 15). Drivers by points: loops 7 (18 pts), if/else 10 (14 pts), ternaries 4 (8 pts), boolean chains 1 (nesting depth added 19). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"product-team/code-to-prd/skills/code-to-prd/scripts/codebase_analyzer.py"},"region":{"startLine":622}}}],"partialFingerprints":{"codehealthFindingId/v1":"cf62e1304a9bb0da8fb9a9dbd10ae6f82d8cb4adc7b55b3970283af7c0338077"}},{"ruleId":"D2","level":"warning","message":{"text":"term_sheet_analyzer.score (cognitive 40): term_sheet_analyzer.score has cognitive complexity 40 (threshold 15). Drivers by points: if/else 26 (27 pts), boolean chains 12, ternaries 1 (nesting depth added 1). To reduce it, split the body: this score is breadth rather than depth \u2014 many checks laid out side by side rather than nested inside one another, so inverting conditions into early returns has nothing left to flatten. Group the statements between the checks into named steps and move each step into its own function, so the body reads as a short sequence of named stages."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"c-level-advisor/general-counsel-advisor/skills/general-counsel-advisor/scripts/term_sheet_analyzer.py"},"region":{"startLine":80}}}],"partialFingerprints":{"codehealthFindingId/v1":"52ad0e4ad133c2c5bd14670d1ac69248c87d89a343e1ff3041bed889b0dd26ba"}},{"ruleId":"D2","level":"warning","message":{"text":"term_sheet_analyzer.score (cognitive 40): term_sheet_analyzer.score has cognitive complexity 40 (threshold 15). Drivers by points: if/else 26 (27 pts), boolean chains 12, ternaries 1 (nesting depth added 1). To reduce it, split the body: this score is breadth rather than depth \u2014 many checks laid out side by side rather than nested inside one another, so inverting conditions into early returns has nothing left to flatten. Group the statements between the checks into named steps and move each step into its own function, so the body reads as a short sequence of named stages."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"c-level-advisor/skills/general-counsel-advisor/scripts/term_sheet_analyzer.py"},"region":{"startLine":80}}}],"partialFingerprints":{"codehealthFindingId/v1":"c2de65117660ff1bb3809d0cdb44675c3a35e8bb2ef8c76f62822088ce141162"}},{"ruleId":"D2","level":"warning","message":{"text":"health_scorer.print_dashboard (cognitive 40): health_scorer.print_dashboard has cognitive complexity 40 (threshold 15). Drivers by points: if/else 15 (22 pts), ternaries 4 (8 pts), loops 4 (7 pts), boolean chains 3 (nesting depth added 14). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"c-level-advisor/skills/org-health-diagnostic/scripts/health_scorer.py"},"region":{"startLine":337}}}],"partialFingerprints":{"codehealthFindingId/v1":"9e8553b72d086040420d01bba58968741d32f1a1d71ab50850bef7ef11a0da44"}},{"ruleId":"D2","level":"warning","message":{"text":"DataContractValidator.validate_contract (cognitive 40): DataContractValidator.validate_contract has cognitive complexity 40 (threshold 15). Drivers by points: if/else 12 (33 pts), boolean chains 5, loops 1 (2 pts) (nesting depth added 22). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/skills/senior-data-engineer/scripts/data_quality_validator.py"},"region":{"startLine":990}}}],"partialFingerprints":{"codehealthFindingId/v1":"9f8c2249dbf5c4f3cc8858302baf40962df6ee51d25360ea2a49c24e7c4e6064"}},{"ruleId":"D2","level":"warning","message":{"text":"score.main (cognitive 40): score.main has cognitive complexity 40 (threshold 15). Drivers by points: if/else 14 (16 pts), error handling 6 (9 pts), ternaries 3 (7 pts), loops 2 (5 pts), boolean chains 3 (nesting depth added 12). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"finance/skills/stock-analysis/scripts/score.py"},"region":{"startLine":1983}}}],"partialFingerprints":{"codehealthFindingId/v1":"50bbb8651bdacf2f9d492a1c8f687c1638a185fbd2e7cc1060a0a18a548cf5b1"}},{"ruleId":"D2","level":"warning","message":{"text":"slide_splitter.split_slides (cognitive 40): slide_splitter.split_slides has cognitive complexity 40 (threshold 15). Drivers by points: if/else 12 (27 pts), loops 5 (9 pts), boolean chains 2, ternaries 1 (2 pts) (nesting depth added 20). To reduce it, flatten the nesting: this score is depth rather than breadth \u2014 most of its points come from checks stacked inside one another, so the work sits several levels in. Invert each enclosing check into an early exit (a return, or the language\u0027s equivalent) so the happy path stays at one level, and where a level cannot be exited early, lift the block it encloses into its own named function."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"markdown-html/skills/md-slides/scripts/slide_splitter.py"},"region":{"startLine":76}}}],"partialFingerprints":{"codehealthFindingId/v1":"6172f6c6b6d91729ea96261cbcffcc5f0c2b5fb74cbbb37715eb421ae21f3f40"}},{"ruleId":"D2","level":"warning","message":{"text":"MigrationGenerator._compare_tables (cognitive 39): MigrationGenerator._compare_tables has cognitive complexity 39 (threshold 15). Drivers by points: ternaries 8 (24 pts), if/else 5 (10 pts), loops 5 (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":"engineering-team/skills/senior-backend/scripts/database_migration_tool.py"},"region":{"startLine":503}}}],"partialFingerprints":{"codehealthFindingId/v1":"a3ceb3cb471908cbaeec5d253bb09c039b92f1de955db26c88b8bd4c9649e2de"}},{"ruleId":"D2","level":"warning","message":{"text":"tf_security_scanner.check_security_groups (cognitive 39): tf_security_scanner.check_security_groups has cognitive complexity 39 (threshold 15). Drivers by points: if/else 8 (33 pts), boolean chains 3, loops 2 (3 pts) (nesting depth added 26). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/terraform-patterns/skills/terraform-patterns/scripts/tf_security_scanner.py"},"region":{"startLine":273}}}],"partialFingerprints":{"codehealthFindingId/v1":"3268e05786c8f3b7246e408f0816e24064b540e0cd69ea84ce03615266a5fccb"}},{"ruleId":"D2","level":"warning","message":{"text":"campaign_roi_calculator.format_text (cognitive 39): campaign_roi_calculator.format_text has cognitive complexity 39 (threshold 15). Drivers by points: if/else 16 (27 pts), loops 5 (12 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":"marketing-skill/skills/campaign-analytics/scripts/campaign_roi_calculator.py"},"region":{"startLine":299}}}],"partialFingerprints":{"codehealthFindingId/v1":"783645075a8ae90c70c771beac8ee8a8d22ce8938ede88ce5ca0663dac603e6d"}},{"ruleId":"D2","level":"warning","message":{"text":"revenue_forecast_model.print_report (cognitive 38): revenue_forecast_model.print_report has cognitive complexity 38 (threshold 15). Drivers by points: if/else 10 (15 pts), ternaries 5 (10 pts), loops 7 (9 pts), boolean chains 4 (nesting depth added 12). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"c-level-advisor/skills/cro-advisor/scripts/revenue_forecast_model.py"},"region":{"startLine":295}}}],"partialFingerprints":{"codehealthFindingId/v1":"dfba075dcfbb46ff18d240483375113b4e817104cb28d35c1e2fe1c91052cbc5"}},{"ruleId":"D2","level":"warning","message":{"text":"cloud_posture_check.check_s3_policy (cognitive 38): cloud_posture_check.check_s3_policy has cognitive complexity 38 (threshold 15). Drivers by points: if/else 15 (22 pts), boolean chains 12, loops 2 (4 pts) (nesting depth added 9). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/skills/cloud-security/scripts/cloud_posture_check.py"},"region":{"startLine":518}}}],"partialFingerprints":{"codehealthFindingId/v1":"41cb55c56b4730c75ec1e492450f629e615febbcf30bf7582dd61448baec5e53"}},{"ruleId":"D2","level":"warning","message":{"text":"engagement_planner.main (cognitive 38): engagement_planner.main has cognitive complexity 38 (threshold 15). Drivers by points: if/else 16 (21 pts), loops 6 (15 pts), ternaries 1 (2 pts) (nesting depth added 15). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/skills/red-team/scripts/engagement_planner.py"},"region":{"startLine":283}}}],"partialFingerprints":{"codehealthFindingId/v1":"7164890606cc277e4a6a8fd27db0a5d5b189330570279ff3e8ff666add4414a6"}},{"ruleId":"D2","level":"warning","message":{"text":"DatasetValidator._validate_voc (cognitive 38): DatasetValidator._validate_voc has cognitive complexity 38 (threshold 15). Drivers by points: if/else 9 (23 pts), loops 4 (10 pts), error handling 2 (4 pts), boolean chains 1 (nesting depth added 22). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/skills/senior-computer-vision/scripts/dataset_pipeline_builder.py"},"region":{"startLine":1408}}}],"partialFingerprints":{"codehealthFindingId/v1":"42a8ff75338502a0d2daa8e2f5aab8f23d596cf7d22d3663732c669db2d7766a"}},{"ruleId":"D2","level":"warning","message":{"text":"log_results.main (cognitive 38): log_results.main has cognitive complexity 38 (threshold 15). Drivers by points: if/else 17 (29 pts), ternaries 2 (5 pts), boolean chains 2, loops 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":"engineering/autoresearch-agent/skills/autoresearch-agent/scripts/log_results.py"},"region":{"startLine":316}}}],"partialFingerprints":{"codehealthFindingId/v1":"1930e974ee3d406f185be998edaf0a1ff0dbbf5c63e42cd3656ed89d778bbb60"}},{"ruleId":"D2","level":"warning","message":{"text":"APIScoringEngine._check_error_handling (cognitive 38): APIScoringEngine._check_error_handling has cognitive complexity 38 (threshold 15). Drivers by points: if/else 6 (21 pts), loops 4 (13 pts), boolean chains 3, 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":"engineering/skills/api-design-reviewer/scripts/api_scorecard.py"},"region":{"startLine":1085}}}],"partialFingerprints":{"codehealthFindingId/v1":"8c03d30e99a51bfb6e79c182e6c5c6ce41b708cbc84cc9d02d53a81fcc5bdfb9"}},{"ruleId":"D2","level":"warning","message":{"text":"ship_gate_scanner.grep_files (cognitive 38): ship_gate_scanner.grep_files has cognitive complexity 38 (threshold 15). Drivers by points: if/else 8 (25 pts), error handling 3 (6 pts), loops 3 (5 pts), boolean chains 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":"engineering/skills/ship-gate/scripts/ship_gate_scanner.py"},"region":{"startLine":150}}}],"partialFingerprints":{"codehealthFindingId/v1":"6fadae7bc4c4ae4daa5448be01010f6650a4f0d15027fac72669c79aa021ed21"}},{"ruleId":"D2","level":"warning","message":{"text":"sitemap_analyzer.print_report (cognitive 38): sitemap_analyzer.print_report has cognitive complexity 38 (threshold 15). Drivers by points: if/else 12 (15 pts), loops 7 (12 pts), ternaries 6 (11 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":"marketing-skill/skills/site-architecture/scripts/sitemap_analyzer.py"},"region":{"startLine":236}}}],"partialFingerprints":{"codehealthFindingId/v1":"ca37db2fb88073c4638a967d25c833a47caa29c375cb772979f16c4b58ca97b6"}},{"ruleId":"D2","level":"warning","message":{"text":"gap_analyzer.analyze_coverage (cognitive 38): gap_analyzer.analyze_coverage has cognitive complexity 38 (threshold 15). Drivers by points: if/else 9 (26 pts), loops 4 (8 pts), ternaries 1 (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":"ra-qm-team/skills/soc2-compliance/scripts/gap_analyzer.py"},"region":{"startLine":168}}}],"partialFingerprints":{"codehealthFindingId/v1":"c0753ea181a87477432b20702ce3758dbb20ecff5b2f3dfaf536dabb3cba8456"}},{"ruleId":"D2","level":"warning","message":{"text":"UserInterface.renderUserDashboard (cognitive 38): UserInterface.renderUserDashboard has cognitive complexity 38 (threshold 15). Drivers by points: if/else 18 (26 pts), loops 3 (7 pts), boolean chains 5 (nesting depth added 12). Of this number, 27 points are the body\u0027s own statements and 11 belong to one function literal inside it that branches. To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/tech-debt-tracker/assets/sample_codebase/src/frontend.js"},"region":{"startLine":59}}}],"partialFingerprints":{"codehealthFindingId/v1":"0cc4cd48e984edd79c8fc8ff7ad3b1ff61585153ee6e09cbcfc1a396c91a3f01"}},{"ruleId":"D2","level":"warning","message":{"text":"renderUserDashboard (cognitive 38): renderUserDashboard has cognitive complexity 38 (threshold 15). Drivers by points: if/else 18 (26 pts), loops 3 (7 pts), boolean chains 5 (nesting depth added 12). Of this number, 27 points are the body\u0027s own statements and 11 belong to one function literal inside it that branches. To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":".codex/skills/tech-debt-tracker/assets/sample_codebase/src/frontend.js"},"region":{"startLine":59}}}],"partialFingerprints":{"codehealthFindingId/v1":"566e023163e225578a8dccf6c126d4243fe6b70da9ecdf06016fadd6e0658e08"}},{"ruleId":"D2","level":"warning","message":{"text":"renderUserDashboard (cognitive 38): renderUserDashboard has cognitive complexity 38 (threshold 15). Drivers by points: if/else 18 (26 pts), loops 3 (7 pts), boolean chains 5 (nesting depth added 12). Of this number, 27 points are the body\u0027s own statements and 11 belong to one function literal inside it that branches. To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":".vibe/skills/claude-skills/engineering/tech-debt-tracker/assets/sample_codebase/src/frontend.js"},"region":{"startLine":59}}}],"partialFingerprints":{"codehealthFindingId/v1":"885691bb1065df26c23367b377dd7b8d0722be51d8560839b68fd6140baea975"}},{"ruleId":"D2","level":"warning","message":{"text":"renderUserDashboard (cognitive 38): renderUserDashboard has cognitive complexity 38 (threshold 15). Drivers by points: if/else 18 (26 pts), loops 3 (7 pts), boolean chains 5 (nesting depth added 12). Of this number, 27 points are the body\u0027s own statements and 11 belong to one function literal inside it that branches. To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":".hermes/skills/claude-skills/engineering/tech-debt-tracker/assets/sample_codebase/src/frontend.js"},"region":{"startLine":59}}}],"partialFingerprints":{"codehealthFindingId/v1":"6cff345b4021f3f842018c9e33e180b4658f12cc2d3f3fb58ebbe607adb4d39e"}},{"ruleId":"D2","level":"warning","message":{"text":"stakeholder_mapper.print_report (cognitive 37): stakeholder_mapper.print_report has cognitive complexity 37 (threshold 15). Drivers by points: loops 10 (17 pts), if/else 6 (12 pts), ternaries 3 (8 pts) (nesting depth added 18). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"c-level-advisor/executive-mentor/skills/executive-mentor/scripts/stakeholder_mapper.py"},"region":{"startLine":232}}}],"partialFingerprints":{"codehealthFindingId/v1":"e194cd3586c04bc2e1a95d9f2324e8d3dde3b26dd706b99d64ae2009997c8dcf"}},{"ruleId":"D2","level":"warning","message":{"text":"memory_inspect.main (cognitive 37): memory_inspect.main has cognitive complexity 37 (threshold 15). Drivers by points: if/else 13 (24 pts), loops 4 (8 pts), ternaries 3 (5 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":"engineering/agent-memory/skills/agent-memory/scripts/memory_inspect.py"},"region":{"startLine":170}}}],"partialFingerprints":{"codehealthFindingId/v1":"4e09a8944d9afb072eb768fd5d890cb6aae0f0d33b4d442c3aba7c7e335f5746"}},{"ruleId":"D2","level":"warning","message":{"text":"review_page_builder.markdown_blocks (cognitive 37): review_page_builder.markdown_blocks has cognitive complexity 37 (threshold 15). Drivers by points: if/else 8 (16 pts), loops 6 (15 pts), boolean chains 6 (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":"engineering/human-gate/skills/human-gate/scripts/review_page_builder.py"},"region":{"startLine":164}}}],"partialFingerprints":{"codehealthFindingId/v1":"4d10cd70a1249ef79076aa76d74c9b33f1351bee86c4f9648e597e09460c3e6b"}},{"ruleId":"D2","level":"warning","message":{"text":"score.run_segmented_scorecard (cognitive 37): score.run_segmented_scorecard has cognitive complexity 37 (threshold 15). Drivers by points: if/else 13 (16 pts), boolean chains 11, ternaries 4 (5 pts), loops 2 (3 pts), error handling 1 (2 pts) (nesting depth added 6). To reduce it, split the body: most of this score is breadth rather than depth \u2014 checks laid out side by side rather than stacked \u2014 so group the statements between the checks into named steps and move each step into its own function. Some of it IS depth: where a check sits inside another whose only job is to reach it, merge the two into one condition."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"finance/skills/stock-analysis/scripts/score.py"},"region":{"startLine":1110}}}],"partialFingerprints":{"codehealthFindingId/v1":"f482989f92901eec677d8fb8e12df2225024f1400618591bf76a6b87a4662a81"}},{"ruleId":"D2","level":"warning","message":{"text":"time_block_planner.plan (cognitive 37): time_block_planner.plan has cognitive complexity 37 (threshold 15). Drivers by points: if/else 17 (24 pts), boolean chains 5, loops 4 (5 pts), 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":"productivity/deep-work/skills/deep-work/scripts/time_block_planner.py"},"region":{"startLine":86}}}],"partialFingerprints":{"codehealthFindingId/v1":"2ff275dcd2b51aa38056fb6b0ba2b09af6e0722f6caba822cfc3f64edbdd48c8"}},{"ruleId":"D2","level":"warning","message":{"text":"sync-codex-skills.main (cognitive 37): sync-codex-skills.main has cognitive complexity 37 (threshold 15). Drivers by points: if/else 16 (21 pts), loops 3 (8 pts), boolean chains 4, ternaries 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":"scripts/sync-codex-skills.py"},"region":{"startLine":357}}}],"partialFingerprints":{"codehealthFindingId/v1":"2025bac7b1f05447e748699f7dd2dd420a613f563e1ce4ae3647b4d9cc21798c"}},{"ruleId":"D2","level":"warning","message":{"text":"output_analyzer.main (cognitive 36): output_analyzer.main has cognitive complexity 36 (threshold 15). Drivers by points: if/else 20 (26 pts), loops 3 (9 pts), boolean chains 1 (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":"engineering-team/google-workspace-cli/skills/google-workspace-cli/scripts/output_analyzer.py"},"region":{"startLine":228}}}],"partialFingerprints":{"codehealthFindingId/v1":"1d422867db3f9e231445c08c2f4706122bc670d8dcf8a334f72b228625fbca70"}},{"ruleId":"D2","level":"warning","message":{"text":"CodeAnalyzer._detect_god_classes (cognitive 36): CodeAnalyzer._detect_god_classes has cognitive complexity 36 (threshold 15). Drivers by points: if/else 6 (25 pts), loops 3 (6 pts), error handling 1 (3 pts), boolean chains 2 (nesting depth added 24). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/skills/senior-architect/scripts/project_architect.py"},"region":{"startLine":270}}}],"partialFingerprints":{"codehealthFindingId/v1":"52f7337cab5e995f7fa3098c463fb80817846b6867f69d478d10674cf53fa30e"}},{"ruleId":"D2","level":"warning","message":{"text":"utils.resolve_input_files (cognitive 36): utils.resolve_input_files has cognitive complexity 36 (threshold 15). Drivers by points: if/else 7 (19 pts), loops 5 (14 pts), ternaries 1 (2 pts), boolean chains 1 (nesting depth added 22). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/book-to-skill/skills/book-to-skill/scripts/book_to_skill/utils.py"},"region":{"startLine":352}}}],"partialFingerprints":{"codehealthFindingId/v1":"61601092c966fa72057be3fdca475fce446e576faffbfc4d5088c7adc6680b70"}},{"ruleId":"D2","level":"warning","message":{"text":"skill_security_auditor.scan_filesystem (cognitive 36): skill_security_auditor.scan_filesystem has cognitive complexity 36 (threshold 15). Drivers by points: if/else 9 (21 pts), error handling 3 (9 pts), ternaries 1 (3 pts), boolean chains 2, loops 1 (nesting depth added 20). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/skill-security-auditor/scripts/skill_security_auditor.py"},"region":{"startLine":776}}}],"partialFingerprints":{"codehealthFindingId/v1":"684157100a8fddb39f1db00210ce691be510e10934109e25c1661375fd7841a6"}},{"ruleId":"D2","level":"warning","message":{"text":"verify_data.check_cross_source (cognitive 36): verify_data.check_cross_source has cognitive complexity 36 (threshold 15). Drivers by points: if/else 8 (20 pts), ternaries 3 (10 pts), boolean chains 3, loops 2 (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":"finance/skills/stock-analysis/scripts/verify_data.py"},"region":{"startLine":858}}}],"partialFingerprints":{"codehealthFindingId/v1":"2af192c33a7bc5f445bb900f85653a904ab0d0ce567d54706a10029403d8093d"}},{"ruleId":"D2","level":"warning","message":{"text":"verify_data._check_magnitude (cognitive 36): verify_data._check_magnitude has cognitive complexity 36 (threshold 15). Drivers by points: if/else 9 (23 pts), loops 6 (10 pts), boolean chains 3 (nesting depth added 18). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"finance/skills/stock-analysis/scripts/verify_data.py"},"region":{"startLine":1043}}}],"partialFingerprints":{"codehealthFindingId/v1":"36ee47f111f9ac6a7bf6cb81fd70989ca35851382f424dfaa5bb0499bbbba192"}},{"ruleId":"D2","level":"warning","message":{"text":"review_html_renderer.render (cognitive 36): review_html_renderer.render has cognitive complexity 36 (threshold 15). Drivers by points: if/else 7 (13 pts), loops 8 (13 pts), boolean chains 5, ternaries 3 (5 pts) (nesting depth added 13). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"markdown-html/skills/md-review/scripts/review_html_renderer.py"},"region":{"startLine":395}}}],"partialFingerprints":{"codehealthFindingId/v1":"79f0f9b87b49fe01f84eb75b675ebef890d9f9e4bdc3426b631a191ef85d038c"}},{"ruleId":"D2","level":"warning","message":{"text":"campaign_roi_calculator.calculate_campaign_metrics (cognitive 36): campaign_roi_calculator.calculate_campaign_metrics has cognitive complexity 36 (threshold 15). Drivers by points: if/else 13 (16 pts), ternaries 16, boolean chains 4 (nesting depth added 3). To reduce it, split the body: most of this score is breadth rather than depth \u2014 checks laid out side by side rather than stacked \u2014 so group the statements between the checks into named steps and move each step into its own function. Some of it IS depth: where a check sits inside another whose only job is to reach it, merge the two into one condition."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"marketing-skill/skills/campaign-analytics/scripts/campaign_roi_calculator.py"},"region":{"startLine":117}}}],"partialFingerprints":{"codehealthFindingId/v1":"04d910277fa8fcf21dd76e47c20e2798e08575ab3f44c259effd12e3ec067bcd"}},{"ruleId":"D2","level":"warning","message":{"text":"seo_checker.analyze_html (cognitive 36): seo_checker.analyze_html has cognitive complexity 36 (threshold 15). Drivers by points: ternaries 26, if/else 4 (5 pts), boolean chains 4, 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":"marketing-skill/skills/seo-audit/scripts/seo_checker.py"},"region":{"startLine":120}}}],"partialFingerprints":{"codehealthFindingId/v1":"53f24c5287746b0428e3d645dd02226e29df330d07e73d72e0942ed31c6b1de3"}},{"ruleId":"D2","level":"warning","message":{"text":"ai_training_data_audit._decide (cognitive 35): ai_training_data_audit._decide has cognitive complexity 35 (threshold 15). Drivers by points: if/else 19 (34 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":"c-level-advisor/chief-data-officer-advisor/skills/chief-data-officer-advisor/scripts/ai_training_data_audit.py"},"region":{"startLine":123}}}],"partialFingerprints":{"codehealthFindingId/v1":"3969ead6b51038b8fb333eb8f5d968278756065880c3a776cc00d661ddd0502b"}},{"ruleId":"D2","level":"warning","message":{"text":"ai_training_data_audit._decide (cognitive 35): ai_training_data_audit._decide has cognitive complexity 35 (threshold 15). Drivers by points: if/else 19 (34 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":"c-level-advisor/skills/chief-data-officer-advisor/scripts/ai_training_data_audit.py"},"region":{"startLine":123}}}],"partialFingerprints":{"codehealthFindingId/v1":"19a7f4ac41223674538d1c80e45646efbfb3087bb5c36e78b416039b9adb8f50"}},{"ruleId":"D2","level":"warning","message":{"text":"DatasetSplitter._create_split_directories (cognitive 35): DatasetSplitter._create_split_directories has cognitive complexity 35 (threshold 15). Drivers by points: if/else 7 (22 pts), error handling 2 (10 pts), loops 2 (3 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":"engineering-team/skills/senior-computer-vision/scripts/dataset_pipeline_builder.py"},"region":{"startLine":991}}}],"partialFingerprints":{"codehealthFindingId/v1":"974c355eb2ffeb2f6de88196b3106753894429612b94c66732b520d0feaa6cbf"}},{"ruleId":"D2","level":"warning","message":{"text":"SchemaValidator._validate_column (cognitive 35): SchemaValidator._validate_column has cognitive complexity 35 (threshold 15). Drivers by points: if/else 18 (27 pts), boolean chains 8 (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":"engineering-team/skills/senior-data-engineer/scripts/data_quality_validator.py"},"region":{"startLine":279}}}],"partialFingerprints":{"codehealthFindingId/v1":"d18347657af8895af97dca9d0287ac1484f48d1e57b35488dc025cf0e97d5873"}},{"ruleId":"D2","level":"warning","message":{"text":"agent_orchestrator.parse_yaml_simple (cognitive 35): agent_orchestrator.parse_yaml_simple has cognitive complexity 35 (threshold 15). Drivers by points: if/else 11 (28 pts), loops 2 (4 pts), boolean chains 3 (nesting depth added 19). To reduce it, flatten the nesting: this score is depth rather than breadth \u2014 most of its points come from checks stacked inside one another, so the work sits several levels in. Invert each enclosing check into an early exit (a return, or the language\u0027s equivalent) so the happy path stays at one level, and where a level cannot be exited early, lift the block it encloses into its own named function."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/skills/senior-prompt-engineer/scripts/agent_orchestrator.py"},"region":{"startLine":73}}}],"partialFingerprints":{"codehealthFindingId/v1":"5c34eab80816365a6de2b9f0efcbc938fb92927dcba9da6623429022c709fa44"}},{"ruleId":"D2","level":"warning","message":{"text":"rag_evaluator.evaluate_rag_system (cognitive 35): rag_evaluator.evaluate_rag_system has cognitive complexity 35 (threshold 15). Drivers by points: if/else 9 (19 pts), ternaries 7 (9 pts), loops 3 (5 pts), boolean chains 2 (nesting depth added 14). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/skills/senior-prompt-engineer/scripts/rag_evaluator.py"},"region":{"startLine":343}}}],"partialFingerprints":{"codehealthFindingId/v1":"70cee794c5cec7dd497613c71dc8ccbf7213cee162ff45d495182f3bdc2547cd"}},{"ruleId":"D2","level":"warning","message":{"text":"log_results.print_dashboard (cognitive 35): log_results.print_dashboard has cognitive complexity 35 (threshold 15). Drivers by points: ternaries 4 (16 pts), if/else 5 (13 pts), loops 3 (4 pts), boolean chains 2 (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":"engineering/autoresearch-agent/skills/autoresearch-agent/scripts/log_results.py"},"region":{"startLine":135}}}],"partialFingerprints":{"codehealthFindingId/v1":"ff9e54d4a8026f8b3b2c0df8591d11697b80f0848bfc0905dffaa1691d6a6f26"}},{"ruleId":"D2","level":"warning","message":{"text":"book_skill_validator.check_frontmatter (cognitive 35): book_skill_validator.check_frontmatter has cognitive complexity 35 (threshold 15). Drivers by points: if/else 19 (29 pts), boolean chains 3, ternaries 1 (2 pts), loops 1 (nesting depth added 11). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/book-to-skill/skills/book-to-skill/scripts/book_skill_validator.py"},"region":{"startLine":288}}}],"partialFingerprints":{"codehealthFindingId/v1":"a041009793d910abbb6b50278f4bfc0e12884e1edfd8bbd513a107f6b02934b6"}},{"ruleId":"D2","level":"warning","message":{"text":"pdf.clean_pdftotext (cognitive 35): pdf.clean_pdftotext has cognitive complexity 35 (threshold 15). Drivers by points: if/else 8 (21 pts), loops 3 (7 pts), ternaries 2 (6 pts), boolean chains 1 (nesting depth added 21). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/book-to-skill/skills/book-to-skill/scripts/book_to_skill/parsers/pdf.py"},"region":{"startLine":14}}}],"partialFingerprints":{"codehealthFindingId/v1":"0bf78ab968007c42d27bad0fe24d08cbee5d73bedf12037ccdf865770370cbc3"}},{"ruleId":"D2","level":"warning","message":{"text":"tc_status.render_single (cognitive 35): tc_status.render_single has cognitive complexity 35 (threshold 15). Drivers by points: if/else 12 (16 pts), loops 4 (10 pts), boolean chains 9 (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":"engineering/skills/tc-tracker/scripts/tc_status.py"},"region":{"startLine":39}}}],"partialFingerprints":{"codehealthFindingId/v1":"e211ab00e786a01f1e728f3c8ea5ad7ed33a2761525697251f0b9c256fcaa606"}},{"ruleId":"D2","level":"warning","message":{"text":"html_renderer._render_block (cognitive 35): html_renderer._render_block has cognitive complexity 35 (threshold 15). Drivers by points: ternaries 9 (18 pts), if/else 10 (12 pts), boolean chains 5 (nesting depth added 11). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"markdown-html/skills/md-document/scripts/html_renderer.py"},"region":{"startLine":404}}}],"partialFingerprints":{"codehealthFindingId/v1":"6aa80c948b8a03f90e8df81c9340d61eee9192ba8c5ae318120bd0ff31ccb249"}},{"ruleId":"D2","level":"warning","message":{"text":"deck_html_renderer._render_block (cognitive 35): deck_html_renderer._render_block has cognitive complexity 35 (threshold 15). Drivers by points: ternaries 9 (18 pts), if/else 10 (12 pts), boolean chains 5 (nesting depth added 11). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"markdown-html/skills/md-slides/scripts/deck_html_renderer.py"},"region":{"startLine":94}}}],"partialFingerprints":{"codehealthFindingId/v1":"45caeb7e0a5dd08fc031a19e70cfcb11e085b99f9ba627ea6851d2d798faa910"}},{"ruleId":"D2","level":"warning","message":{"text":"OKRGenerator.calculate_alignment_score (cognitive 35): OKRGenerator.calculate_alignment_score has cognitive complexity 35 (threshold 15). Drivers by points: if/else 11 (21 pts), loops 5 (12 pts), boolean chains 2 (nesting depth added 17). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"product-team/skills/product-strategist/scripts/okr_cascade_generator.py"},"region":{"startLine":304}}}],"partialFingerprints":{"codehealthFindingId/v1":"d2941f004804e8780d166ab8a0f8246323ae86fbf72d1fb9c4b6c44996ea8b1f"}},{"ruleId":"D2","level":"warning","message":{"text":"kb_validator.validate (cognitive 35): kb_validator.validate has cognitive complexity 35 (threshold 15). Drivers by points: if/else 19 (26 pts), boolean chains 6, loops 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":"productivity/email/skills/inbox-setup/scripts/kb_validator.py"},"region":{"startLine":114}}}],"partialFingerprints":{"codehealthFindingId/v1":"126481cd9c37a581150ac1f635544e5ba87f2db15fa8cc46cf736d9f68dd9c77"}},{"ruleId":"D2","level":"warning","message":{"text":"handoff_self_check.check (cognitive 35): handoff_self_check.check has cognitive complexity 35 (threshold 15). Drivers by points: if/else 15 (25 pts), boolean chains 4, loops 3 (4 pts), ternaries 1 (2 pts) (nesting depth added 12). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"productivity/handoff/skills/handoff/scripts/handoff_self_check.py"},"region":{"startLine":165}}}],"partialFingerprints":{"codehealthFindingId/v1":"55bfbcdf612008da416725dc3530d8695687bd4ed76e6193a119c4b962b79d94"}},{"ruleId":"D2","level":"warning","message":{"text":"sync-codex-skills.create_symlinks (cognitive 35): sync-codex-skills.create_symlinks has cognitive complexity 35 (threshold 15). Drivers by points: if/else 12 (32 pts), error handling 1 (2 pts), loops 1 (nesting depth added 21). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"scripts/sync-codex-skills.py"},"region":{"startLine":226}}}],"partialFingerprints":{"codehealthFindingId/v1":"a491cdc2a56a7ad250bbb4984cf2b01fe2d0a20ff59d272641dcd18a26003d73"}},{"ruleId":"D2","level":"warning","message":{"text":"decision_tracker.report_conflicts (cognitive 34): decision_tracker.report_conflicts has cognitive complexity 34 (threshold 15). Drivers by points: if/else 8 (22 pts), loops 6 (9 pts), boolean chains 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":"c-level-advisor/skills/decision-logger/scripts/decision_tracker.py"},"region":{"startLine":394}}}],"partialFingerprints":{"codehealthFindingId/v1":"04d189dc8de5bf68afbb975f8f9881ba15cef7fee40fffe0c7ef4399c432f85c"}},{"ruleId":"D2","level":"warning","message":{"text":"revshare_modeler.model (cognitive 34): revshare_modeler.model has cognitive complexity 34 (threshold 15). Drivers by points: if/else 13 (16 pts), boolean chains 11, ternaries 4 (7 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":"commercial/skills/partnerships-architect/scripts/revshare_modeler.py"},"region":{"startLine":139}}}],"partialFingerprints":{"codehealthFindingId/v1":"5baffef91fad32f880475e7d7fe415fe5565bf1829672a35c9468156c0c6a7dd"}},{"ruleId":"D2","level":"warning","message":{"text":"context_md_linter.lint (cognitive 34): context_md_linter.lint has cognitive complexity 34 (threshold 15). Drivers by points: if/else 18 (28 pts), loops 3 (5 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":"engineering/grill-with-docs/skills/grill-with-docs/scripts/context_md_linter.py"},"region":{"startLine":110}}}],"partialFingerprints":{"codehealthFindingId/v1":"fa5e1096c911797cce15d9d9a8e4b82e7aba738120afef3dc1340b5251d1e162"}},{"ruleId":"D2","level":"warning","message":{"text":"AgentEvaluator.calculate_performance_metrics (cognitive 34): AgentEvaluator.calculate_performance_metrics has cognitive complexity 34 (threshold 15). Drivers by points: if/else 16 (19 pts), ternaries 8 (10 pts), error handling 1 (3 pts), boolean chains 2 (nesting depth added 7). To reduce it, split the body: most of this score is breadth rather than depth \u2014 checks laid out side by side rather than stacked \u2014 so group the statements between the checks into named steps and move each step into its own function. Some of it IS depth: where a check sits inside another whose only job is to reach it, merge the two into one condition, 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":"engineering/skills/agent-designer/agent_evaluator.py"},"region":{"startLine":259}}}],"partialFingerprints":{"codehealthFindingId/v1":"6319f0b99ed7a4e65fc9733828f9a169fce1ac3d35bc357a80a66f8a14581dd9"}},{"ruleId":"D2","level":"warning","message":{"text":"BreakingChangeDetector.generate_text_report (cognitive 34): BreakingChangeDetector.generate_text_report has cognitive complexity 34 (threshold 15). Drivers by points: if/else 13 (22 pts), loops 4 (12 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":"engineering/skills/api-design-reviewer/scripts/breaking_change_detector.py"},"region":{"startLine":875}}}],"partialFingerprints":{"codehealthFindingId/v1":"ea64ee33557c04ac27ec3ffa439a9d04e961929d7c0e305545ac3319434a2941"}},{"ruleId":"D2","level":"warning","message":{"text":"hiring_calibrator.format_human_readable (cognitive 34): hiring_calibrator.format_human_readable has cognitive complexity 34 (threshold 15). Drivers by points: if/else 13 (22 pts), loops 4 (11 pts), boolean chains 1 (nesting depth added 16). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/interview-system-designer/hiring_calibrator.py"},"region":{"startLine":1112}}}],"partialFingerprints":{"codehealthFindingId/v1":"53645582576b479eac29084f373d03184e3aac8168ee8036a27297eb53fe727d"}},{"ruleId":"D2","level":"warning","message":{"text":"RollbackGenerator.generate_human_readable_runbook (cognitive 34): RollbackGenerator.generate_human_readable_runbook has cognitive complexity 34 (threshold 15). Drivers by points: loops 12 (20 pts), if/else 4 (11 pts), ternaries 1 (2 pts), boolean chains 1 (nesting depth added 16). To reduce it, break up the iteration: give each loop body a named function, and split a multi-phase loop into one function per phase so no single body carries the whole pipeline."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/migration-architect/scripts/rollback_generator.py"},"region":{"startLine":940}}}],"partialFingerprints":{"codehealthFindingId/v1":"c6fb9d685a2cd8947fa92469e3d6ed6fe87a8a29d8f9c606024d61a496628ac3"}},{"ruleId":"D2","level":"warning","message":{"text":"audit_log_analyzer.analyze (cognitive 34): audit_log_analyzer.analyze has cognitive complexity 34 (threshold 15). Drivers by points: if/else 10 (20 pts), loops 7 (10 pts), boolean chains 4 (nesting depth added 13). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/secrets-vault-manager/scripts/audit_log_analyzer.py"},"region":{"startLine":101}}}],"partialFingerprints":{"codehealthFindingId/v1":"40628050677737bfcea6ec2ff562cb7a9266791cb423d0352ae50be031e011a2"}},{"ruleId":"D2","level":"warning","message":{"text":"pattern_miner.mine (cognitive 34): pattern_miner.mine has cognitive complexity 34 (threshold 15). Drivers by points: if/else 11 (23 pts), ternaries 4 (6 pts), loops 2 (3 pts), boolean chains 2 (nesting depth added 15). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"marketing/linkedin/skills/linkedin-analytics/scripts/pattern_miner.py"},"region":{"startLine":146}}}],"partialFingerprints":{"codehealthFindingId/v1":"e5c784d74e0862e45b63fd45a26c9b1e091a981b4a87ce2ef5d425d863e9e890"}},{"ruleId":"D2","level":"warning","message":{"text":"data_subject_rights_tracker.main (cognitive 34): data_subject_rights_tracker.main has cognitive complexity 34 (threshold 15). Drivers by points: if/else 15 (25 pts), loops 2 (5 pts), ternaries 1 (4 pts) (nesting depth added 16). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"ra-qm-team/skills/gdpr-dsgvo-expert/scripts/data_subject_rights_tracker.py"},"region":{"startLine":449}}}],"partialFingerprints":{"codehealthFindingId/v1":"b17df3e8ae2b42adcf0d2637ac995ff38d1b9b16e43231f1c643f1364a39c63d"}},{"ruleId":"D2","level":"warning","message":{"text":"ReportGenerator.generate_text_report (cognitive 33): ReportGenerator.generate_text_report has cognitive complexity 33 (threshold 15). Drivers by points: if/else 10 (19 pts), ternaries 3 (9 pts), loops 2 (3 pts), boolean chains 2 (nesting depth added 16). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/skills/senior-data-engineer/scripts/data_quality_validator.py"},"region":{"startLine":1111}}}],"partialFingerprints":{"codehealthFindingId/v1":"08d81e69bd80c0d81e4fc4aa3de57f53a425063703acfb164c6775c259093b66"}},{"ruleId":"D2","level":"warning","message":{"text":"CoverageParser._parse_lcov (cognitive 33): CoverageParser._parse_lcov has cognitive complexity 33 (threshold 15). Drivers by points: if/else 8 (24 pts), loops 2 (5 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":"engineering-team/skills/senior-qa/scripts/coverage_analyzer.py"},"region":{"startLine":200}}}],"partialFingerprints":{"codehealthFindingId/v1":"826cc687ffb227e1d8ee9b7ecdb647f6279a6ef1321a9c1a0693c9a66d3996d8"}},{"ruleId":"D2","level":"warning","message":{"text":"SemanticChunker._identify_sections (cognitive 33): SemanticChunker._identify_sections has cognitive complexity 33 (threshold 15). Drivers by points: if/else 9 (24 pts), ternaries 1 (6 pts), boolean chains 2, loops 1 (nesting depth added 20). To reduce it, flatten the nesting: this score is depth rather than breadth \u2014 most of its points come from checks stacked inside one another, so the work sits several levels in. Invert each enclosing check into an early exit (a return, or the language\u0027s equivalent) so the happy path stays at one level, and where a level cannot be exited early, lift the block it encloses into its own named function."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/rag-architect/chunking_optimizer.py"},"region":{"startLine":310}}}],"partialFingerprints":{"codehealthFindingId/v1":"550bce8c6f47c9436c295b73a7a7764467b14c67cb0ecf1da562ba5b9186cf15"}},{"ruleId":"D2","level":"warning","message":{"text":"context_validator.validate_context (cognitive 33): context_validator.validate_context has cognitive complexity 33 (threshold 15). Drivers by points: if/else 11 (20 pts), ternaries 2 (5 pts), boolean chains 4, error handling 1 (3 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":"marketing-skill/skills/marketing-context/scripts/context_validator.py"},"region":{"startLine":27}}}],"partialFingerprints":{"codehealthFindingId/v1":"338415131256c4ddacb3c654bf4ec1a4de3ccab4b882d6598237864f2d2b12cf"}},{"ruleId":"D2","level":"warning","message":{"text":"tweet_composer.main (cognitive 33): tweet_composer.main has cognitive complexity 33 (threshold 15). Drivers by points: if/else 11 (19 pts), loops 3 (9 pts), ternaries 1 (3 pts), boolean chains 2 (nesting depth added 16). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"marketing-skill/skills/x-twitter-growth/scripts/tweet_composer.py"},"region":{"startLine":222}}}],"partialFingerprints":{"codehealthFindingId/v1":"4c29975752e90c9a1f758a0e80f3bb7f3b3277abf037eaf4389c79fbc25dcd85"}},{"ruleId":"D2","level":"warning","message":{"text":"a11y_scanner.check_media_captions_block (cognitive 32): a11y_scanner.check_media_captions_block has cognitive complexity 32 (threshold 15). Drivers by points: if/else 9 (26 pts), boolean chains 4, loops 2 (nesting depth added 17). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/a11y-audit/skills/a11y-audit/scripts/a11y_scanner.py"},"region":{"startLine":407}}}],"partialFingerprints":{"codehealthFindingId/v1":"4370db356fcd56d80535014a80d4322ed73b2824e578dc5e7d61d7cfd19b72a4"}},{"ruleId":"D2","level":"warning","message":{"text":"LayerViolationDetector._analyze_imports (cognitive 32): LayerViolationDetector._analyze_imports has cognitive complexity 32 (threshold 15). Drivers by points: if/else 6 (21 pts), loops 3 (6 pts), error handling 1 (3 pts), boolean chains 2 (nesting depth added 20). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/skills/senior-architect/scripts/project_architect.py"},"region":{"startLine":391}}}],"partialFingerprints":{"codehealthFindingId/v1":"9ea9b41018e025369d8cd23fd211c26e304b26548293d140c53fbbfda01313b0"}},{"ruleId":"D2","level":"warning","message":{"text":"epub.extract_with_zipfile (cognitive 32): epub.extract_with_zipfile has cognitive complexity 32 (threshold 15). Drivers by points: if/else 6 (12 pts), loops 4 (7 pts), ternaries 3 (6 pts), boolean chains 4, error handling 2 (3 pts) (nesting depth added 13). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/book-to-skill/skills/book-to-skill/scripts/book_to_skill/parsers/epub.py"},"region":{"startLine":67}}}],"partialFingerprints":{"codehealthFindingId/v1":"42b08840467f9c60fa7a9224ffa957fcb2feb5d346a88da1bb63cdf407e02a32"}},{"ruleId":"D2","level":"warning","message":{"text":"question_bank_generator.main (cognitive 32): question_bank_generator.main has cognitive complexity 32 (threshold 15). Drivers by points: if/else 11 (16 pts), ternaries 4 (10 pts), boolean chains 3, error handling 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":"engineering/skills/interview-system-designer/question_bank_generator.py"},"region":{"startLine":970}}}],"partialFingerprints":{"codehealthFindingId/v1":"ec3a0f5a2824098283a03bb6135a10d78937d4cf272b69d76c1574e7b4435269"}},{"ruleId":"D2","level":"warning","message":{"text":"ratios.render_text (cognitive 32): ratios.render_text has cognitive complexity 32 (threshold 15). Drivers by points: if/else 13 (15 pts), loops 6 (10 pts), ternaries 3 (7 pts) (nesting depth added 10). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"finance/skills/stock-analysis/scripts/ratios.py"},"region":{"startLine":2368}}}],"partialFingerprints":{"codehealthFindingId/v1":"f0cf75225c05c966c623c7c407af8ecfabe6228a011205d714b6c3d0da94b303"}},{"ruleId":"D2","level":"warning","message":{"text":"verify_data.check_period_alignment (cognitive 32): verify_data.check_period_alignment has cognitive complexity 32 (threshold 15). Drivers by points: if/else 7 (14 pts), ternaries 4 (12 pts), boolean chains 4, loops 2 (nesting depth added 15). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"finance/skills/stock-analysis/scripts/verify_data.py"},"region":{"startLine":1108}}}],"partialFingerprints":{"codehealthFindingId/v1":"9cac5151769c430c62bdc3be2aff8db6014eea01621aee43799c38c447b5aa1d"}},{"ruleId":"D2","level":"warning","message":{"text":"annotation_extractor.extract_annotations (cognitive 32): annotation_extractor.extract_annotations has cognitive complexity 32 (threshold 15). Drivers by points: if/else 9 (25 pts), loops 4 (7 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":"markdown-html/skills/md-review/scripts/annotation_extractor.py"},"region":{"startLine":57}}}],"partialFingerprints":{"codehealthFindingId/v1":"c249d3bc698004733366e2e6daf2e783e876dce4f434e53989eecd92ec74b2a1"}},{"ruleId":"D2","level":"warning","message":{"text":"project_health_dashboard.format_text_output (cognitive 32): project_health_dashboard.format_text_output has cognitive complexity 32 (threshold 15). Drivers by points: if/else 13 (20 pts), loops 5 (12 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":"project-management/skills/senior-pm/scripts/project_health_dashboard.py"},"region":{"startLine":635}}}],"partialFingerprints":{"codehealthFindingId/v1":"c53947d4046e3c2f71d909c414d17756b01c66fff1daf2f8590f36afbc72963d"}},{"ruleId":"D2","level":"warning","message":{"text":"kb_ingester.generate_report (cognitive 31): kb_ingester.generate_report has cognitive complexity 31 (threshold 15). Drivers by points: if/else 12 (14 pts), loops 6 (13 pts), ternaries 1 (3 pts), boolean chains 1 (nesting depth added 11). To reduce it, split the body: most of this score is breadth rather than depth \u2014 checks laid out side by side rather than stacked \u2014 so group the statements between the checks into named steps and move each step into its own function. Some of it IS depth: where a check sits inside another whose only job is to reach it, merge the two into one condition, and where an else follows a branch that already returns, drop the trailing else and let the rest of the body continue at one level."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"business-operations/skills/knowledge-ops/scripts/kb_ingester.py"},"region":{"startLine":264}}}],"partialFingerprints":{"codehealthFindingId/v1":"aa4c8c5656e36a12fdcedce2b3db26bdd5ee98bb763f878d8e33b4b1fcdf90bc"}},{"ruleId":"D2","level":"warning","message":{"text":"pipeline_orchestrator.main (cognitive 31): pipeline_orchestrator.main has cognitive complexity 31 (threshold 15). Drivers by points: if/else 14 (23 pts), ternaries 2 (5 pts), boolean chains 2, error handling 1 (nesting depth added 12). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/skills/senior-data-engineer/scripts/pipeline_orchestrator.py"},"region":{"startLine":717}}}],"partialFingerprints":{"codehealthFindingId/v1":"cf1b605b2a7efbe8d0c9f797d7b06647cbcc205d86296afe0fa3456e9b18e0c3"}},{"ruleId":"D2","level":"warning","message":{"text":"log_results.export_dashboard_markdown (cognitive 31): log_results.export_dashboard_markdown has cognitive complexity 31 (threshold 15). Drivers by points: ternaries 4 (14 pts), if/else 4 (10 pts), boolean chains 4, loops 2 (3 pts) (nesting depth added 17). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/autoresearch-agent/skills/autoresearch-agent/scripts/log_results.py"},"region":{"startLine":280}}}],"partialFingerprints":{"codehealthFindingId/v1":"1bc01a716958b254f36a4b02522ab44857b2114ddea8eee7c98693fb19f7ca27"}},{"ruleId":"D2","level":"warning","message":{"text":"data_profiler.print_report (cognitive 31): data_profiler.print_report has cognitive complexity 31 (threshold 15). Drivers by points: if/else 9 (18 pts), loops 5 (8 pts), boolean chains 3, ternaries 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":"engineering/data-quality-auditor/skills/data-quality-auditor/scripts/data_profiler.py"},"region":{"startLine":151}}}],"partialFingerprints":{"codehealthFindingId/v1":"fb63ca29e5315289301ed072e60eaf6afeb0ea4aab6e6b8ff29f7fe017190a82"}},{"ruleId":"D2","level":"warning","message":{"text":"reading_path_planner.main (cognitive 31): reading_path_planner.main has cognitive complexity 31 (threshold 15). Drivers by points: if/else 12 (15 pts), loops 4 (12 pts), boolean chains 2, ternaries 2 (nesting depth added 11). To reduce it, split the body: most of this score is breadth rather than depth \u2014 checks laid out side by side rather than stacked \u2014 so group the statements between the checks into named steps and move each step into its own function. Some of it IS depth: where a check sits inside another whose only job is to reach it, merge the two into one condition, and where an else follows a branch that already returns, drop the trailing else and let the rest of the body continue at one level."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/deep-learning-book/skills/deep-learning-book/scripts/reading_path_planner.py"},"region":{"startLine":373}}}],"partialFingerprints":{"codehealthFindingId/v1":"d95f30ccdd50727f24a175acfdebb9d1ee24e0568638f49ef06c70df51ceef44"}},{"ruleId":"D2","level":"warning","message":{"text":"feedback_parser._strip_comments (cognitive 31): feedback_parser._strip_comments has cognitive complexity 31 (threshold 15). Drivers by points: if/else 11 (30 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":"engineering/human-gate/skills/human-gate/scripts/feedback_parser.py"},"region":{"startLine":111}}}],"partialFingerprints":{"codehealthFindingId/v1":"7f08d17dedf42d4eb62b96ce0a67a00df7189bb5c32307589f6259eab806431a"}},{"ruleId":"D2","level":"warning","message":{"text":"diff_surgeon.main (cognitive 31): diff_surgeon.main has cognitive complexity 31 (threshold 15). Drivers by points: if/else 9 (14 pts), loops 5 (13 pts), ternaries 4 (nesting depth added 13). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/karpathy-coder/skills/karpathy-coder/scripts/diff_surgeon.py"},"region":{"startLine":141}}}],"partialFingerprints":{"codehealthFindingId/v1":"e4a6808395f6e638db1a2bb2ddbb8813f6790712a83b67d668260f1d9f2ebd1a"}},{"ruleId":"D2","level":"warning","message":{"text":"loop_designer.main (cognitive 31): loop_designer.main has cognitive complexity 31 (threshold 15). Drivers by points: if/else 11 (16 pts), ternaries 3 (8 pts), boolean chains 4, error handling 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":"engineering/skills/interview-system-designer/loop_designer.py"},"region":{"startLine":826}}}],"partialFingerprints":{"codehealthFindingId/v1":"7d317a5d46c82d85aa5851da4494e006afbf442d75870c9c5f4537ae28ece2fc"}},{"ruleId":"D2","level":"warning","message":{"text":"ReportFormatter.format_human_readable (cognitive 31): ReportFormatter.format_human_readable has cognitive complexity 31 (threshold 15). Drivers by points: loops 6 (12 pts), if/else 9, ternaries 3 (9 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":"engineering/skills/skill-tester/scripts/skill_validator.py"},"region":{"startLine":578}}}],"partialFingerprints":{"codehealthFindingId/v1":"64d863ecc9ba35146f9f90b3cbc831f5d03f48217a393bd65428dc65c93e34e9"}},{"ruleId":"D2","level":"warning","message":{"text":"prompt_versioner.main (cognitive 31): prompt_versioner.main has cognitive complexity 31 (threshold 15). Drivers by points: if/else 13 (23 pts), ternaries 2 (4 pts), loops 1 (3 pts), boolean chains 1 (nesting depth added 14). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"marketing-skill/skills/prompt-engineer-toolkit/scripts/prompt_versioner.py"},"region":{"startLine":126}}}],"partialFingerprints":{"codehealthFindingId/v1":"661fd307bc6c23a24c4a093abdc13538127d5de8a9146e6ecff76e9a85b58988"}},{"ruleId":"D2","level":"warning","message":{"text":"content_planner.generate_plan (cognitive 31): content_planner.generate_plan has cognitive complexity 31 (threshold 15). Drivers by points: ternaries 4 (13 pts), if/else 3 (9 pts), loops 3 (6 pts), boolean chains 3 (nesting depth added 18). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"marketing-skill/skills/x-twitter-growth/scripts/content_planner.py"},"region":{"startLine":78}}}],"partialFingerprints":{"codehealthFindingId/v1":"aea74d165e922be8b1be0da67db57eecc8274edaa1508c6047cf3fe25a2447ac"}},{"ruleId":"D2","level":"warning","message":{"text":"post_linter.lint (cognitive 31): post_linter.lint has cognitive complexity 31 (threshold 15). Drivers by points: if/else 26 (27 pts), boolean chains 4 (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":"marketing/linkedin/skills/linkedin-content/scripts/post_linter.py"},"region":{"startLine":117}}}],"partialFingerprints":{"codehealthFindingId/v1":"3e876464044d10d8dc1e5f2e92773e6ae2d7cab28f66a10f66c4db2f1b7bd655"}},{"ruleId":"D2","level":"warning","message":{"text":"action_item_extractor.extract (cognitive 31): action_item_extractor.extract has cognitive complexity 31 (threshold 15). Drivers by points: if/else 12 (27 pts), ternaries 1 (2 pts), boolean chains 1, loops 1 (nesting depth added 16). To reduce it, flatten the nesting: this score is depth rather than breadth \u2014 most of its points come from checks stacked inside one another, so the work sits several levels in. Invert each enclosing check into an early exit (a return, or the language\u0027s equivalent) so the happy path stays at one level, and where a level cannot be exited early, lift the block it encloses into its own named function."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"productivity/meetings/skills/meetings/scripts/action_item_extractor.py"},"region":{"startLine":105}}}],"partialFingerprints":{"codehealthFindingId/v1":"d41bdcc9f15c4a95fc43a4037ec86377898192c204c3c313bac4466e074b354e"}},{"ruleId":"D2","level":"warning","message":{"text":"open_loop_scanner.scan (cognitive 31): open_loop_scanner.scan has cognitive complexity 31 (threshold 15). Drivers by points: if/else 6 (21 pts), loops 3 (6 pts), error handling 1 (3 pts), boolean chains 1 (nesting depth added 20). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"productivity/weekly-review/skills/weekly-review/scripts/open_loop_scanner.py"},"region":{"startLine":50}}}],"partialFingerprints":{"codehealthFindingId/v1":"4c3b7f15f30bc15cb09e45d3eef9f9e54d8ce2843dcf2a5edc141c8b95997fcb"}},{"ruleId":"D2","level":"warning","message":{"text":"resource_capacity_planner.format_text_output (cognitive 31): resource_capacity_planner.format_text_output has cognitive complexity 31 (threshold 15). Drivers by points: loops 8 (16 pts), if/else 10 (15 pts) (nesting depth added 13). To reduce it, break up the iteration: give each loop body a named function, and split a multi-phase loop into one function per phase so no single body carries the whole pipeline."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"project-management/skills/senior-pm/scripts/resource_capacity_planner.py"},"region":{"startLine":646}}}],"partialFingerprints":{"codehealthFindingId/v1":"058da9bc6c227fc1e4cf36faf02bd8e95c0c8570e9a852aa69ac447440685cb3"}},{"ruleId":"D2","level":"warning","message":{"text":"full-page-screenshot.captureFullPage (cognitive 31): full-page-screenshot.captureFullPage has cognitive complexity 31 (threshold 15). Drivers by points: if/else 10 (14 pts), error handling 5 (9 pts), loops 3 (7 pts), boolean chains 1 (nesting depth added 12). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/full-page-screenshot/scripts/full-page-screenshot.mjs"},"region":{"startLine":221}}}],"partialFingerprints":{"codehealthFindingId/v1":"8336618a80e3d6b2477cd0625406482b36f15531d60bf7295b941699c8cf1d82"}},{"ruleId":"D2","level":"warning","message":{"text":"cron_validator._valid_field (cognitive 30): cron_validator._valid_field has cognitive complexity 30 (threshold 15). Drivers by points: if/else 10 (24 pts), boolean chains 5, 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":"agent-launcher/skills/run-without-you/scripts/cron_validator.py"},"region":{"startLine":25}}}],"partialFingerprints":{"codehealthFindingId/v1":"ee6078238f4b00fe82d26522771909e0b2cf4a122f91a1d6b0fc8b5601b46a02"}},{"ruleId":"D2","level":"warning","message":{"text":"gtm_efficiency_calculator.rate_metric (cognitive 30): gtm_efficiency_calculator.rate_metric has cognitive complexity 30 (threshold 15). Drivers by points: if/else 17 (25 pts), boolean chains 5 (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":"business-growth/skills/revenue-operations/scripts/gtm_efficiency_calculator.py"},"region":{"startLine":75}}}],"partialFingerprints":{"codehealthFindingId/v1":"52e044d5151e8998b4581ddbca69ef8b9fb25d777c9ecac542aaa6ef69f43db4"}},{"ruleId":"D2","level":"warning","message":{"text":"vendor_risk_classifier.classify_regulatory_exposure (cognitive 30): vendor_risk_classifier.classify_regulatory_exposure has cognitive complexity 30 (threshold 15). Drivers by points: if/else 13 (21 pts), boolean chains 9 (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":"business-operations/skills/vendor-management/scripts/vendor_risk_classifier.py"},"region":{"startLine":127}}}],"partialFingerprints":{"codehealthFindingId/v1":"493a84ef9124c6ab5d78896113625c5d9db89c49a9f8f5bac9467c33027f7cff"}},{"ruleId":"D2","level":"warning","message":{"text":"engagement_planner.build_engagement_plan (cognitive 30): engagement_planner.build_engagement_plan has cognitive complexity 30 (threshold 15). Drivers by points: if/else 11 (20 pts), boolean chains 5, loops 5 (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":"engineering-team/skills/red-team/scripts/engagement_planner.py"},"region":{"startLine":137}}}],"partialFingerprints":{"codehealthFindingId/v1":"860f464605e8c354006056a1fc0ae324862182867f744ab9ea6854aeb5ab9ffe"}},{"ruleId":"D2","level":"warning","message":{"text":"api_scaffolder.load_yaml_as_json (cognitive 30): api_scaffolder.load_yaml_as_json has cognitive complexity 30 (threshold 15). Drivers by points: if/else 9 (24 pts), boolean chains 3, 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":"engineering-team/skills/senior-backend/scripts/api_scaffolder.py"},"region":{"startLine":24}}}],"partialFingerprints":{"codehealthFindingId/v1":"e02887e5d7d80c91b939fd3403c9d09917f96290673658ff7cf7933b4a35d7d4"}},{"ruleId":"D2","level":"warning","message":{"text":"CoverageAnalyzer._parse_json (cognitive 30): CoverageAnalyzer._parse_json has cognitive complexity 30 (threshold 15). Drivers by points: if/else 5 (15 pts), loops 5 (14 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":"engineering-team/skills/tdd-guide/scripts/coverage_analyzer.py"},"region":{"startLine":102}}}],"partialFingerprints":{"codehealthFindingId/v1":"66d7c3c12ab91e72bbc6158976be8a4e86d181a2021d363773a183967b354468"}},{"ruleId":"D2","level":"warning","message":{"text":"AgentEvaluator.analyze_errors (cognitive 30): AgentEvaluator.analyze_errors has cognitive complexity 30 (threshold 15). Drivers by points: if/else 8 (16 pts), loops 5 (8 pts), ternaries 2 (4 pts), boolean chains 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":"engineering/skills/agent-designer/agent_evaluator.py"},"region":{"startLine":355}}}],"partialFingerprints":{"codehealthFindingId/v1":"46a4e9d5f2064bc4218b9e10e4dc3a61c3e6bf9cafdb7cfef8f43b186e4595ce"}},{"ruleId":"D2","level":"warning","message":{"text":"ship_gate_scanner.print_report (cognitive 30): ship_gate_scanner.print_report has cognitive complexity 30 (threshold 15). Drivers by points: if/else 18 (22 pts), boolean chains 4, ternaries 2 (4 pts) (nesting depth added 6). To reduce it, split the body: most of this score is breadth rather than depth \u2014 checks laid out side by side rather than stacked \u2014 so group the statements between the checks into named steps and move each step into its own function. Some of it IS depth: where a check sits inside another whose only job is to reach it, merge the two into one condition, and where an else follows a branch that already returns, drop the trailing else and let the rest of the body continue at one level."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/ship-gate/scripts/ship_gate_scanner.py"},"region":{"startLine":1031}}}],"partialFingerprints":{"codehealthFindingId/v1":"b8d0053754a1375a4ceca638bc5756300cd2802fdbcdc4f35173fd27a1407ff0"}},{"ruleId":"D2","level":"warning","message":{"text":"tc_create.main (cognitive 30): tc_create.main has cognitive complexity 30 (threshold 15). Drivers by points: ternaries 8 (16 pts), if/else 7, boolean chains 4, error handling 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":"engineering/skills/tc-tracker/scripts/tc_create.py"},"region":{"startLine":146}}}],"partialFingerprints":{"codehealthFindingId/v1":"df74452ce09c5e96dd8d4044b1a7061e2fcfed2104c1e7d13a464b04f6ea9a62"}},{"ruleId":"D2","level":"warning","message":{"text":"tc_init.main (cognitive 30): tc_init.main has cognitive complexity 30 (threshold 15). Drivers by points: if/else 9 (13 pts), ternaries 3 (7 pts), error handling 3 (6 pts), boolean chains 4 (nesting depth added 11). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/tc-tracker/scripts/tc_init.py"},"region":{"startLine":106}}}],"partialFingerprints":{"codehealthFindingId/v1":"c69d037107c54fcababae81f0f553142f0296cd7253937720646ae9e8a8d81e3"}},{"ruleId":"D2","level":"warning","message":{"text":"nap_checker.build_report (cognitive 30): nap_checker.build_report has cognitive complexity 30 (threshold 15). Drivers by points: if/else 12 (21 pts), loops 4 (8 pts), boolean chains 1 (nesting depth added 13). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"marketing-skill/skills/local-seo-manager/scripts/nap_checker.py"},"region":{"startLine":169}}}],"partialFingerprints":{"codehealthFindingId/v1":"6f4904230d2be1b9339f2480a9b65c0ec6be7b911202979a70353e49c848a48a"}},{"ruleId":"D2","level":"warning","message":{"text":"comment_target_planner.build (cognitive 30): comment_target_planner.build has cognitive complexity 30 (threshold 15). Drivers by points: if/else 13 (24 pts), boolean chains 3, loops 2 (3 pts) (nesting depth added 12). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"marketing/linkedin/skills/linkedin-engagement/scripts/comment_target_planner.py"},"region":{"startLine":89}}}],"partialFingerprints":{"codehealthFindingId/v1":"be7e70949855305ee14f230d690e44ee3278fb59767c3bf09a5666cdee6040fc"}},{"ruleId":"D2","level":"warning","message":{"text":"citation_tracker.main (cognitive 30): citation_tracker.main has cognitive complexity 30 (threshold 15). Drivers by points: if/else 15 (23 pts), boolean chains 5, 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":"research/pulse/skills/pulse/scripts/citation_tracker.py"},"region":{"startLine":471}}}],"partialFingerprints":{"codehealthFindingId/v1":"468d0725d0e39b57798c59c35472855f8d6be4b6cafcacd352a514f6a6b3f580"}},{"ruleId":"D2","level":"warning","message":{"text":"full-page-screenshot.modeUrl (cognitive 30): full-page-screenshot.modeUrl has cognitive complexity 30 (threshold 15). Drivers by points: if/else 9 (16 pts), error handling 5 (11 pts), boolean chains 2, 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":"engineering/skills/full-page-screenshot/scripts/full-page-screenshot.mjs"},"region":{"startLine":524}}}],"partialFingerprints":{"codehealthFindingId/v1":"61567cb67a5a9de863b392a6f6ac2d2ed43ff3734e918a447e3bdf5c2b204080"}},{"ruleId":"D2","level":"warning","message":{"text":"backend_decision_engine.render_markdown (cognitive 29): backend_decision_engine.render_markdown has cognitive complexity 29 (threshold 15). Drivers by points: loops 9 (16 pts), if/else 10 (11 pts), boolean chains 1, ternaries 1 (nesting depth added 8). To reduce it, break up the iteration: give each loop body a named function, and split a multi-phase loop into one function per phase so no single body carries the whole pipeline."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/skills/senior-backend/scripts/backend_decision_engine.py"},"region":{"startLine":191}}}],"partialFingerprints":{"codehealthFindingId/v1":"84ac3c0d36ccd50c5bcf437203ae8530f3c4b45c57c435b6635e20f4043baddc"}},{"ruleId":"D2","level":"warning","message":{"text":"DatasetAnalyzer._detect_format (cognitive 29): DatasetAnalyzer._detect_format has cognitive complexity 29 (threshold 15). Drivers by points: if/else 6 (15 pts), error handling 3 (7 pts), loops 3 (4 pts), boolean chains 3 (nesting depth added 14). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/skills/senior-computer-vision/scripts/dataset_pipeline_builder.py"},"region":{"startLine":204}}}],"partialFingerprints":{"codehealthFindingId/v1":"245ee808de8f721fdebcb6edba5c5bb2de225f35d770a2e14fde0b7c869f2815"}},{"ruleId":"D2","level":"warning","message":{"text":"APIScoringEngine._check_parameter_documentation (cognitive 29): APIScoringEngine._check_parameter_documentation has cognitive complexity 29 (threshold 15). Drivers by points: if/else 6 (21 pts), loops 3 (6 pts), boolean chains 1, ternaries 1 (nesting depth added 18). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/api-design-reviewer/scripts/api_scorecard.py"},"region":{"startLine":691}}}],"partialFingerprints":{"codehealthFindingId/v1":"82a6df98205c80f9d2659b84a1ad59c0479506a9b75852c53ab3085c696a7d85"}},{"ruleId":"D2","level":"warning","message":{"text":"HiringCalibrator._analyze_competency_bias (cognitive 29): HiringCalibrator._analyze_competency_bias has cognitive complexity 29 (threshold 15). Drivers by points: if/else 6 (18 pts), loops 4 (9 pts), ternaries 1 (2 pts) (nesting depth added 18). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/interview-system-designer/hiring_calibrator.py"},"region":{"startLine":398}}}],"partialFingerprints":{"codehealthFindingId/v1":"1d34288364a693c6faa92f2d7524c29ff228d277730709f6efe96a25ba57544b"}},{"ruleId":"D2","level":"warning","message":{"text":"AlertOptimizer.analyze_thresholds (cognitive 29): AlertOptimizer.analyze_thresholds has cognitive complexity 29 (threshold 15). Drivers by points: if/else 10 (25 pts), boolean chains 3, loops 1 (nesting depth added 15). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/observability-designer/scripts/alert_optimizer.py"},"region":{"startLine":509}}}],"partialFingerprints":{"codehealthFindingId/v1":"40b2eb810dfddf0893931162c903ffa30b8aff598b68c8e4f89c3af18f6dc187"}},{"ruleId":"D2","level":"warning","message":{"text":"ship_gate_scanner.detect_stack (cognitive 29): ship_gate_scanner.detect_stack has cognitive complexity 29 (threshold 15). Drivers by points: if/else 11 (19 pts), loops 3 (5 pts), error handling 1 (3 pts), boolean chains 2 (nesting depth added 12). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/ship-gate/scripts/ship_gate_scanner.py"},"region":{"startLine":227}}}],"partialFingerprints":{"codehealthFindingId/v1":"89be231bd798caffb140faef96f3c7377418ac49e937d41aaea7b71e1e0208d4"}},{"ruleId":"D2","level":"warning","message":{"text":"score.apply_gates (cognitive 29): score.apply_gates has cognitive complexity 29 (threshold 15). Drivers by points: if/else 8 (15 pts), boolean chains 6, ternaries 2 (5 pts), loops 2 (3 pts) (nesting depth added 11). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"finance/skills/stock-analysis/scripts/score.py"},"region":{"startLine":556}}}],"partialFingerprints":{"codehealthFindingId/v1":"e528a5764a2ac06059b975d0e93af3fa7b864fe6afe63550b6ce0ab7b0e65761"}},{"ruleId":"D2","level":"warning","message":{"text":"score.explain (cognitive 29): score.explain has cognitive complexity 29 (threshold 15). Drivers by points: if/else 11 (15 pts), loops 5 (9 pts), ternaries 1 (3 pts), boolean chains 2 (nesting depth added 10). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"finance/skills/stock-analysis/scripts/score.py"},"region":{"startLine":1632}}}],"partialFingerprints":{"codehealthFindingId/v1":"730ac55e711df198c4ccb354ee55a4cbde0142dcaecdd890c27a981f40c8dcc8"}},{"ruleId":"D2","level":"warning","message":{"text":"campaign_tracker.analyze_campaign (cognitive 29): campaign_tracker.analyze_campaign has cognitive complexity 29 (threshold 15). Drivers by points: if/else 11 (23 pts), boolean chains 3, loops 2, ternaries 1 (nesting depth added 12). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"marketing-skill/skills/marketing-ops/scripts/campaign_tracker.py"},"region":{"startLine":29}}}],"partialFingerprints":{"codehealthFindingId/v1":"ca8fb16383dc95150bb3211be42475a26fe52bac95f633225fe23d67a80d3e91"}},{"ruleId":"D2","level":"warning","message":{"text":"codebase_analyzer.extract_backend_routes (cognitive 29): codebase_analyzer.extract_backend_routes has cognitive complexity 29 (threshold 15). Drivers by points: if/else 7 (15 pts), loops 3 (6 pts), ternaries 1 (4 pts), boolean chains 3, error handling 1 (nesting depth added 14). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"product-team/code-to-prd/skills/code-to-prd/scripts/codebase_analyzer.py"},"region":{"startLine":367}}}],"partialFingerprints":{"codehealthFindingId/v1":"c6810834fadc72fc47fc3d753021fa818e3dd9dfe25c09619ff7ccb3eda94ac1"}},{"ruleId":"D2","level":"warning","message":{"text":"anti_todo_card.main (cognitive 29): anti_todo_card.main has cognitive complexity 29 (threshold 15). Drivers by points: if/else 13 (17 pts), ternaries 3 (6 pts), boolean chains 2, error handling 1 (2 pts), loops 1 (2 pts) (nesting depth added 9). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"productivity/andreessen/skills/andreessen/scripts/anti_todo_card.py"},"region":{"startLine":146}}}],"partialFingerprints":{"codehealthFindingId/v1":"0c63b46dd77db2110ea5266f838e3d37b4d716c43176a37001ac859117289ee7"}},{"ruleId":"D2","level":"warning","message":{"text":"gdpr_compliance_checker.analyze_project (cognitive 29): gdpr_compliance_checker.analyze_project has cognitive complexity 29 (threshold 15). Drivers by points: if/else 12 (20 pts), error handling 1 (4 pts), loops 3 (4 pts), boolean chains 1 (nesting depth added 12). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"ra-qm-team/skills/gdpr-dsgvo-expert/scripts/gdpr_compliance_checker.py"},"region":{"startLine":201}}}],"partialFingerprints":{"codehealthFindingId/v1":"860275f0c7cbb24432175a41de0012657e49b44604ca0879dc2208c1bb7e1555"}},{"ruleId":"D2","level":"warning","message":{"text":"check_frontmatter.main (cognitive 29): check_frontmatter.main has cognitive complexity 29 (threshold 15). Drivers by points: loops 7 (16 pts), if/else 8 (11 pts), boolean chains 1, ternaries 1 (nesting depth added 12). To reduce it, break up the iteration: give each loop body a named function, and split a multi-phase loop into one function per phase so no single body carries the whole pipeline."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"scripts/check_frontmatter.py"},"region":{"startLine":174}}}],"partialFingerprints":{"codehealthFindingId/v1":"1671ca6d1e840690b1b40270d70647d791ee4ae425c53d1295f42a6fba634315"}},{"ruleId":"D2","level":"warning","message":{"text":"derive_counters.run_check (cognitive 29): derive_counters.run_check has cognitive complexity 29 (threshold 15). Drivers by points: if/else 10 (16 pts), loops 4 (8 pts), error handling 2 (4 pts), boolean chains 1 (nesting depth added 12). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"scripts/derive_counters.py"},"region":{"startLine":273}}}],"partialFingerprints":{"codehealthFindingId/v1":"883af068904e0b69974df26bc692c0c7977894b11e036fdc4f1dd059a592d500"}},{"ruleId":"D2","level":"warning","message":{"text":"decision_matrix_scorer.interactive_mode (cognitive 28): decision_matrix_scorer.interactive_mode has cognitive complexity 28 (threshold 15). Drivers by points: if/else 6 (15 pts), loops 4 (7 pts), error handling 2 (6 pts) (nesting depth added 16). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"c-level-advisor/executive-mentor/skills/executive-mentor/scripts/decision_matrix_scorer.py"},"region":{"startLine":288}}}],"partialFingerprints":{"codehealthFindingId/v1":"c8cda1efeacd838d98dc7a4dfab3f895459fb6be576423a5a952e534d8cdb394"}},{"ruleId":"D2","level":"warning","message":{"text":"alignment_checker.print_report (cognitive 28): alignment_checker.print_report has cognitive complexity 28 (threshold 15). Drivers by points: if/else 11 (14 pts), loops 5 (9 pts), ternaries 2 (5 pts) (nesting depth added 10). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"c-level-advisor/skills/strategic-alignment/scripts/alignment_checker.py"},"region":{"startLine":317}}}],"partialFingerprints":{"codehealthFindingId/v1":"4131298dd126fbcbd5274237aa37e9585f4c1c4c410804052d70697431c1defb"}},{"ruleId":"D2","level":"warning","message":{"text":"bookings_forecaster.compute_forecast (cognitive 28): bookings_forecaster.compute_forecast has cognitive complexity 28 (threshold 15). Drivers by points: boolean chains 11, if/else 7 (10 pts), ternaries 3 (5 pts), loops 2 (nesting depth added 5). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"commercial/skills/commercial-forecaster/scripts/bookings_forecaster.py"},"region":{"startLine":197}}}],"partialFingerprints":{"codehealthFindingId/v1":"0d7354e55b908e0f0c93f032c54e087d55f5ef805cd938ba7e7b0d2deed292df"}},{"ruleId":"D2","level":"warning","message":{"text":"code_quality_analyzer.analyze_project (cognitive 28): code_quality_analyzer.analyze_project has cognitive complexity 28 (threshold 15). Drivers by points: ternaries 8 (12 pts), if/else 7 (11 pts), error handling 1 (2 pts), loops 2, boolean chains 1 (nesting depth added 9). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/skills/senior-fullstack/scripts/code_quality_analyzer.py"},"region":{"startLine":334}}}],"partialFingerprints":{"codehealthFindingId/v1":"800147debd0f24544656ed2346c81a9b4a3ed8f9bce2adf0d11d2b544aac0fb8"}},{"ruleId":"D2","level":"warning","message":{"text":"CoverageParser._parse_istanbul_json (cognitive 28): CoverageParser._parse_istanbul_json has cognitive complexity 28 (threshold 15). Drivers by points: if/else 7 (19 pts), loops 4 (8 pts), boolean chains 1 (nesting depth added 16). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/skills/senior-qa/scripts/coverage_analyzer.py"},"region":{"startLine":103}}}],"partialFingerprints":{"codehealthFindingId/v1":"195b46ad229198949090d9edb954cb5c33796e09a68649740da0c80c3517d805"}},{"ruleId":"D2","level":"warning","message":{"text":"dry_run.check_markdown (cognitive 28): dry_run.check_markdown has cognitive complexity 28 (threshold 15). Drivers by points: if/else 8 (21 pts), loops 4 (6 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":"engineering/agenthub/skills/agenthub/scripts/dry_run.py"},"region":{"startLine":150}}}],"partialFingerprints":{"codehealthFindingId/v1":"4ec47a31d80822abd8f967a9b68fb7cab9c6fa9b65fcfb694435a66ce5b0aad4"}},{"ruleId":"D2","level":"warning","message":{"text":"rtf._strip_destination_groups (cognitive 28): rtf._strip_destination_groups has cognitive complexity 28 (threshold 15). Drivers by points: if/else 10 (23 pts), boolean chains 4, loops 1 (nesting depth added 13). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/book-to-skill/skills/book-to-skill/scripts/book_to_skill/parsers/rtf.py"},"region":{"startLine":44}}}],"partialFingerprints":{"codehealthFindingId/v1":"1a1fc3caf04b8b8936c15a984c5cfcaf5c2b2af24231661a729bb18964a7d306"}},{"ruleId":"D2","level":"warning","message":{"text":"APIScoringEngine._check_error_format_consistency (cognitive 28): APIScoringEngine._check_error_format_consistency has cognitive complexity 28 (threshold 15). Drivers by points: loops 5 (12 pts), if/else 4 (10 pts), error handling 1 (4 pts), ternaries 2 (nesting depth added 16). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/api-design-reviewer/scripts/api_scorecard.py"},"region":{"startLine":314}}}],"partialFingerprints":{"codehealthFindingId/v1":"1bef815779b3d49ae03d50f549edeaffba54fb9624c138154cb95943456f0fde"}},{"ruleId":"D2","level":"warning","message":{"text":"APIScoringEngine._check_parameter_consistency (cognitive 28): APIScoringEngine._check_parameter_consistency has cognitive complexity 28 (threshold 15). Drivers by points: if/else 8 (19 pts), loops 3 (6 pts), boolean chains 2, ternaries 1 (nesting depth added 14). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/api-design-reviewer/scripts/api_scorecard.py"},"region":{"startLine":353}}}],"partialFingerprints":{"codehealthFindingId/v1":"4da2c5de80e8deff85723b34c4ddada4ab14f96f10ec9c46ffb1477c6a79576e"}},{"ruleId":"D2","level":"warning","message":{"text":"APIScoringEngine._check_status_code_consistency (cognitive 28): APIScoringEngine._check_status_code_consistency has cognitive complexity 28 (threshold 15). Drivers by points: if/else 8 (19 pts), loops 5 (8 pts), ternaries 1 (nesting depth added 14). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/api-design-reviewer/scripts/api_scorecard.py"},"region":{"startLine":505}}}],"partialFingerprints":{"codehealthFindingId/v1":"3242d2d0a79e93c42c852062e5c0b904d060833b3df6600889b80f649c48924e"}},{"ruleId":"D2","level":"warning","message":{"text":"APIScoringEngine._check_example_coverage (cognitive 28): APIScoringEngine._check_example_coverage has cognitive complexity 28 (threshold 15). Drivers by points: if/else 6 (17 pts), loops 4 (7 pts), boolean chains 2, ternaries 2 (nesting depth added 14). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/api-design-reviewer/scripts/api_scorecard.py"},"region":{"startLine":751}}}],"partialFingerprints":{"codehealthFindingId/v1":"9e1a96e4c11341fab488cb5ff280b1555825b3e8829b68445c5cf224498e639c"}},{"ruleId":"D2","level":"warning","message":{"text":"APIScoringEngine._check_discoverability (cognitive 28): APIScoringEngine._check_discoverability has cognitive complexity 28 (threshold 15). Drivers by points: if/else 5 (15 pts), loops 4 (10 pts), boolean chains 2, ternaries 1 (nesting depth added 16). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/api-design-reviewer/scripts/api_scorecard.py"},"region":{"startLine":1034}}}],"partialFingerprints":{"codehealthFindingId/v1":"ebad250799c94ee6d93f290f5dcbccd1fcbfbcb95e32fb0f62cd57a414797769"}},{"ruleId":"D2","level":"warning","message":{"text":"SchemaAnalyzer.generate_mermaid_erd (cognitive 28): SchemaAnalyzer.generate_mermaid_erd has cognitive complexity 28 (threshold 15). Drivers by points: if/else 7 (22 pts), 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":"engineering/skills/database-designer/schema_analyzer.py"},"region":{"startLine":709}}}],"partialFingerprints":{"codehealthFindingId/v1":"433ed991df639eb285fbc40de659fa28823046b155939151e0a14f3e7180d5c8"}},{"ruleId":"D2","level":"warning","message":{"text":"UpgradePlanner.generate_report (cognitive 28): UpgradePlanner.generate_report has cognitive complexity 28 (threshold 15). Drivers by points: if/else 7 (11 pts), ternaries 3 (9 pts), loops 4 (8 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":"engineering/skills/dependency-auditor/scripts/upgrade_planner.py"},"region":{"startLine":884}}}],"partialFingerprints":{"codehealthFindingId/v1":"b38412c074b2697c5e2530157cd830efa0ec46ea6ceb9582709b455590e62ce0"}},{"ruleId":"D2","level":"warning","message":{"text":"validate_workflow._strip_comments (cognitive 28): validate_workflow._strip_comments has cognitive complexity 28 (threshold 15). Drivers by points: if/else 8 (18 pts), ternaries 2 (6 pts), boolean chains 3, loops 1 (nesting depth added 14). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/workflow-builder/skills/workflow-builder/scripts/validate_workflow.py"},"region":{"startLine":22}}}],"partialFingerprints":{"codehealthFindingId/v1":"94324f9f11e5f68e5bf969d324dd5b77674501e940ee060b7e7e3cdb816016c6"}},{"ruleId":"D2","level":"warning","message":{"text":"metrics_calculator.calculate (cognitive 28): metrics_calculator.calculate has cognitive complexity 28 (threshold 15). Drivers by points: if/else 18, boolean chains 10. 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":"finance/skills/saas-metrics-coach/scripts/metrics_calculator.py"},"region":{"startLine":19}}}],"partialFingerprints":{"codehealthFindingId/v1":"6289a821099c8829683ed44adc9ad3b4280ba3a9041bb445f4be69a25015d561"}},{"ruleId":"D2","level":"warning","message":{"text":"Period._derive (cognitive 28): Period._derive has cognitive complexity 28 (threshold 15). Drivers by points: if/else 12 (15 pts), boolean chains 13 (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":"finance/skills/stock-analysis/scripts/ratios.py"},"region":{"startLine":507}}}],"partialFingerprints":{"codehealthFindingId/v1":"c25f3ac472e639ceab5b568422cc3ea76b09f675a414b79947feb7e3449295ba"}},{"ruleId":"D2","level":"warning","message":{"text":"Analysis.build_ev_bridge (cognitive 28): Analysis.build_ev_bridge has cognitive complexity 28 (threshold 15). Drivers by points: if/else 17 (23 pts), boolean chains 5 (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":"finance/skills/stock-analysis/scripts/ratios.py"},"region":{"startLine":1673}}}],"partialFingerprints":{"codehealthFindingId/v1":"e558e8c88016140580dd5695bff3e3d3663c9e1d605c70f9bc52c5d9db4b41ba"}},{"ruleId":"D2","level":"warning","message":{"text":"valuation.scenario_value (cognitive 28): valuation.scenario_value has cognitive complexity 28 (threshold 15). Drivers by points: boolean chains 14, if/else 8 (12 pts), 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":"finance/skills/stock-analysis/scripts/valuation.py"},"region":{"startLine":491}}}],"partialFingerprints":{"codehealthFindingId/v1":"fe993d5786d55ace5b83193fe8cc751c79f8603e9c5d01956fd3a7e07f56c578"}},{"ruleId":"D2","level":"warning","message":{"text":"seo_health_scorer.score_checks (cognitive 28): seo_health_scorer.score_checks has cognitive complexity 28 (threshold 15). Drivers by points: if/else 15 (19 pts), loops 4 (5 pts), boolean chains 2, ternaries 1 (2 pts) (nesting depth added 6). To reduce it, split the body: most of this score is breadth rather than depth \u2014 checks laid out side by side rather than stacked \u2014 so group the statements between the checks into named steps and move each step into its own function. Some of it IS depth: where a check sits inside another whose only job is to reach it, merge the two into one condition, and where an else follows a branch that already returns, drop the trailing else and let the rest of the body continue at one level."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"marketing-skill/skills/seo-audit/scripts/seo_health_scorer.py"},"region":{"startLine":109}}}],"partialFingerprints":{"codehealthFindingId/v1":"a17e0d46578da87a063ab50ffa287d5773d2cce0350cf703dba5790c4800a70e"}},{"ruleId":"D2","level":"warning","message":{"text":"social_calendar_generator.build_markdown (cognitive 28): social_calendar_generator.build_markdown has cognitive complexity 28 (threshold 15). Drivers by points: loops 10 (17 pts), if/else 3 (8 pts), ternaries 1 (3 pts) (nesting depth added 14). To reduce it, break up the iteration: give each loop body a named function, and split a multi-phase loop into one function per phase so no single body carries the whole pipeline."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"marketing-skill/skills/social-media-manager/scripts/social_calendar_generator.py"},"region":{"startLine":220}}}],"partialFingerprints":{"codehealthFindingId/v1":"936ab92fefce4f374920b75f7c88df650413c3994db4ded496f1710693252ee1"}},{"ruleId":"D2","level":"warning","message":{"text":"jira_snapshot_bridge.flow_report (cognitive 28): jira_snapshot_bridge.flow_report has cognitive complexity 28 (threshold 15). Drivers by points: if/else 9 (10 pts), loops 3 (9 pts), boolean chains 6, ternaries 3 (nesting depth added 7). 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":"project-management/skills/pm-skills/scripts/jira_snapshot_bridge.py"},"region":{"startLine":116}}}],"partialFingerprints":{"codehealthFindingId/v1":"349632d8405216829e8da2d2918b2a34af656dcb7d6bc238d7959cb39ed603e5"}},{"ruleId":"D2","level":"warning","message":{"text":"retrospective_analyzer.analyze_action_item_completion (cognitive 28): retrospective_analyzer.analyze_action_item_completion has cognitive complexity 28 (threshold 15). Drivers by points: if/else 10 (20 pts), loops 5, ternaries 2, boolean chains 1 (nesting depth added 10). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"project-management/skills/scrum-master/scripts/retrospective_analyzer.py"},"region":{"startLine":236}}}],"partialFingerprints":{"codehealthFindingId/v1":"f2a40e1f5ec352bfa8673e202c546d3b903f9c53d942cf2d57e0ee4aded6700f"}},{"ruleId":"D2","level":"warning","message":{"text":"fda_submission_tracker.print_text_report (cognitive 28): fda_submission_tracker.print_text_report has cognitive complexity 28 (threshold 15). Drivers by points: ternaries 7 (17 pts), if/else 6, loops 3 (5 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":"ra-qm-team/skills/fda-consultant-specialist/scripts/fda_submission_tracker.py"},"region":{"startLine":305}}}],"partialFingerprints":{"codehealthFindingId/v1":"119c4a2afe6c3dcd6f3159275fd65822279dde82154bcd84a77f4aa6facefe9d"}},{"ruleId":"D2","level":"warning","message":{"text":"hipaa_risk_assessment.scan_code_patterns (cognitive 28): hipaa_risk_assessment.scan_code_patterns has cognitive complexity 28 (threshold 15). Drivers by points: if/else 3 (11 pts), loops 4 (10 pts), error handling 2 (7 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":"ra-qm-team/skills/fda-consultant-specialist/scripts/hipaa_risk_assessment.py"},"region":{"startLine":253}}}],"partialFingerprints":{"codehealthFindingId/v1":"d438ec067853d13a50a10c68cc52281e297c4ed308944f0d4f13f2f073127e45"}},{"ruleId":"D2","level":"warning","message":{"text":"source_tier_classifier.classify (cognitive 28): source_tier_classifier.classify has cognitive complexity 28 (threshold 15). Drivers by points: if/else 13 (16 pts), boolean chains 8, loops 3, error handling 1 (nesting depth added 3). To reduce it, split the body: most of this score is breadth rather than depth \u2014 checks laid out side by side rather than stacked \u2014 so group the statements between the checks into named steps and move each step into its own function. Some of it IS depth: where a check sits inside another whose only job is to reach it, merge the two into one condition, 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":"research/dossier/skills/dossier/scripts/source_tier_classifier.py"},"region":{"startLine":125}}}],"partialFingerprints":{"codehealthFindingId/v1":"d7d64f70f46081423823d237e142675a6ca3cbfbbe9ee1121e9a79e96398ec6e"}},{"ruleId":"D2","level":"warning","message":{"text":"check_model_freshness.main (cognitive 28): check_model_freshness.main has cognitive complexity 28 (threshold 15). Drivers by points: if/else 10 (15 pts), loops 4 (8 pts), ternaries 2 (5 pts) (nesting depth added 12). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"scripts/check_model_freshness.py"},"region":{"startLine":171}}}],"partialFingerprints":{"codehealthFindingId/v1":"6ad0117a2e2858298c2be83542b604a6f34e807c9812142cd1d35647bfd74e00"}},{"ruleId":"D2","level":"warning","message":{"text":"smoke_json_output.main (cognitive 28): smoke_json_output.main has cognitive complexity 28 (threshold 15). Drivers by points: if/else 11 (16 pts), loops 4 (8 pts), boolean chains 2, error handling 1, 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":"scripts/smoke_json_output.py"},"region":{"startLine":148}}}],"partialFingerprints":{"codehealthFindingId/v1":"556fb9c8e307d0c533d45591d6b6968111f00d1fc850fe4cc73f22a1aaba95bd"}},{"ruleId":"D2","level":"warning","message":{"text":"full-page-screenshot.captureViaProxy (cognitive 28): full-page-screenshot.captureViaProxy has cognitive complexity 28 (threshold 15). Drivers by points: error handling 3 (10 pts), boolean chains 5, if/else 4 (5 pts), loops 2 (5 pts), ternaries 2 (3 pts) (nesting depth added 12). Of this number, 26 points are the body\u0027s own statements and 2 belong to one function literal inside it that branches. To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/full-page-screenshot/scripts/full-page-screenshot.mjs"},"region":{"startLine":646}}}],"partialFingerprints":{"codehealthFindingId/v1":"75d1204b931006b4635df51ae2dc7a4e67e0bf2baf248c6a1ac71bdd1de71749"}},{"ruleId":"D2","level":"warning","message":{"text":"code_quality_checker.check_c_specific_smells (cognitive 27): code_quality_checker.check_c_specific_smells has cognitive complexity 27 (threshold 15). Drivers by points: if/else 6 (14 pts), loops 9 (12 pts), boolean chains 1 (nesting depth added 11). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/skills/code-reviewer/scripts/code_quality_checker.py"},"region":{"startLine":610}}}],"partialFingerprints":{"codehealthFindingId/v1":"0abee7771162e459674392fc44702ba692036b7fa6f41b0b7ec1b1426921eed5"}},{"ruleId":"D2","level":"warning","message":{"text":"incident_triage.main (cognitive 27): incident_triage.main has cognitive complexity 27 (threshold 15). Drivers by points: if/else 20 (24 pts), error handling 2, boolean chains 1 (nesting depth added 4). To reduce it, split the body: most of this score is breadth rather than depth \u2014 checks laid out side by side rather than stacked \u2014 so group the statements between the checks into named steps and move each step into its own function. Some of it IS depth: where a check sits inside another whose only job is to reach it, merge the two into one condition, 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":"engineering-team/skills/incident-response/scripts/incident_triage.py"},"region":{"startLine":600}}}],"partialFingerprints":{"codehealthFindingId/v1":"be918561cf15ddfdc396839594ef2d90491f771417dfd68b67e2492a24ee7c93"}},{"ruleId":"D2","level":"warning","message":{"text":"FormatConverter._coco_to_yolo (cognitive 27): FormatConverter._coco_to_yolo has cognitive complexity 27 (threshold 15). Drivers by points: loops 8 (16 pts), if/else 3 (9 pts), error handling 1 (2 pts) (nesting depth added 15). To reduce it, break up the iteration: give each loop body a named function, and split a multi-phase loop into one function per phase so no single body carries the whole pipeline."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/skills/senior-computer-vision/scripts/dataset_pipeline_builder.py"},"region":{"startLine":549}}}],"partialFingerprints":{"codehealthFindingId/v1":"bb78e3ebc47f42969d86a29baafab56433a4a5b90e1a1869b12203a011b2c0ba"}},{"ruleId":"D2","level":"warning","message":{"text":"DatasetValidator._validate_coco (cognitive 27): DatasetValidator._validate_coco has cognitive complexity 27 (threshold 15). Drivers by points: if/else 7 (19 pts), error handling 2 (4 pts), loops 2 (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":"engineering-team/skills/senior-computer-vision/scripts/dataset_pipeline_builder.py"},"region":{"startLine":1303}}}],"partialFingerprints":{"codehealthFindingId/v1":"a508bbfbfbfd0287f90abf625737c53b16805f378b468432cd997669d8304bf2"}},{"ruleId":"D2","level":"warning","message":{"text":"frontend_decision_engine.render_markdown (cognitive 27): frontend_decision_engine.render_markdown has cognitive complexity 27 (threshold 15). Drivers by points: loops 8 (15 pts), if/else 10, boolean chains 1, ternaries 1 (nesting depth added 7). To reduce it, break up the iteration: give each loop body a named function, and split a multi-phase loop into one function per phase so no single body carries the whole pipeline."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/skills/senior-frontend/scripts/frontend_decision_engine.py"},"region":{"startLine":145}}}],"partialFingerprints":{"codehealthFindingId/v1":"4ebe1706d09fa28f9f94fa2c02f25905995253d188d5570c98c96297c95b10fe"}},{"ruleId":"D2","level":"warning","message":{"text":"fullstack_decision_engine.render_markdown (cognitive 27): fullstack_decision_engine.render_markdown has cognitive complexity 27 (threshold 15). Drivers by points: loops 8 (15 pts), if/else 10, boolean chains 1, ternaries 1 (nesting depth added 7). To reduce it, break up the iteration: give each loop body a named function, and split a multi-phase loop into one function per phase so no single body carries the whole pipeline."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/skills/senior-fullstack/scripts/fullstack_decision_engine.py"},"region":{"startLine":187}}}],"partialFingerprints":{"codehealthFindingId/v1":"3184e5dd4a1e3bf8e269e9fda5ed3a728444bd63e79beca5c37c289eadbeac3b"}},{"ruleId":"D2","level":"warning","message":{"text":"chart_analyzer.check_templates (cognitive 27): chart_analyzer.check_templates has cognitive complexity 27 (threshold 15). Drivers by points: if/else 8 (15 pts), loops 4 (8 pts), boolean chains 4 (nesting depth added 11). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/helm-chart-builder/skills/helm-chart-builder/scripts/chart_analyzer.py"},"region":{"startLine":257}}}],"partialFingerprints":{"codehealthFindingId/v1":"541f25da021749014ca03109c65d1802bfdb9b30dd36ff6ba1f388ff2bd998a5"}},{"ruleId":"D2","level":"warning","message":{"text":"values_validator.parse_values (cognitive 27): values_validator.parse_values has cognitive complexity 27 (threshold 15). Drivers by points: if/else 8 (17 pts), boolean chains 7, 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":"engineering/helm-chart-builder/skills/helm-chart-builder/scripts/values_validator.py"},"region":{"startLine":78}}}],"partialFingerprints":{"codehealthFindingId/v1":"71948576f2dd9949af9f47b1acc0002f7a7353dc7c2b02168f31abfdee533783"}},{"ruleId":"D2","level":"warning","message":{"text":"memory_density_auditor.load_records (cognitive 27): memory_density_auditor.load_records has cognitive complexity 27 (threshold 15). Drivers by points: if/else 6 (13 pts), error handling 3 (8 pts), loops 3 (5 pts), boolean chains 1 (nesting depth added 14). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/memory-engineering/skills/memory-engineering/scripts/memory_density_auditor.py"},"region":{"startLine":321}}}],"partialFingerprints":{"codehealthFindingId/v1":"bbb171417401e099be9ca0e8806ea952af182b7223f5ebbf65da5a0745f65133"}},{"ruleId":"D2","level":"warning","message":{"text":"AgentPlanner.design_communication_topology (cognitive 27): AgentPlanner.design_communication_topology has cognitive complexity 27 (threshold 15). Drivers by points: loops 6 (15 pts), if/else 5 (12 pts) (nesting depth added 16). To reduce it, break up the iteration: give each loop body a named function, and split a multi-phase loop into one function per phase so no single body carries the whole pipeline."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/agent-designer/agent_planner.py"},"region":{"startLine":544}}}],"partialFingerprints":{"codehealthFindingId/v1":"b09a9e9e33cf270c88ea0ab1eb9281cf37540e0f7ee19eb4c9f287f2e116a5e3"}},{"ruleId":"D2","level":"warning","message":{"text":"tc_init.detect_project_name (cognitive 27): tc_init.detect_project_name has cognitive complexity 27 (threshold 15). Drivers by points: if/else 7 (15 pts), error handling 3 (6 pts), loops 2 (4 pts), boolean chains 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":"engineering/skills/tc-tracker/scripts/tc_init.py"},"region":{"startLine":35}}}],"partialFingerprints":{"codehealthFindingId/v1":"7adbccaf18d97fa453903a2d94c85eac8a2f5fd3c5c138b6d38a4ab20686a661"}},{"ruleId":"D2","level":"warning","message":{"text":"onboard.main (cognitive 27): onboard.main has cognitive complexity 27 (threshold 15). Drivers by points: if/else 12 (18 pts), error handling 1 (4 pts), loops 1 (2 pts), ternaries 1 (2 pts), boolean chains 1 (nesting depth added 11). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"markdown-html/skills/design-system/scripts/onboard.py"},"region":{"startLine":173}}}],"partialFingerprints":{"codehealthFindingId/v1":"b1729d387735126553434a609be702ddeb215d299588198b5822cfab8ec4b605"}},{"ruleId":"D2","level":"warning","message":{"text":"cross_search_aggregator.aggregate (cognitive 27): cross_search_aggregator.aggregate has cognitive complexity 27 (threshold 15). Drivers by points: if/else 6 (16 pts), loops 6 (9 pts), boolean chains 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":"research/litreview/skills/litreview/scripts/cross_search_aggregator.py"},"region":{"startLine":88}}}],"partialFingerprints":{"codehealthFindingId/v1":"9776285ff191ef725d67cf02f3f712f83f9b9f8d5d80032a5ff4e44a732d9ae9"}},{"ruleId":"D2","level":"warning","message":{"text":"family_resolver.resolve_families (cognitive 27): family_resolver.resolve_families has cognitive complexity 27 (threshold 15). Drivers by points: if/else 7 (15 pts), loops 6 (11 pts), boolean chains 1 (nesting depth added 13). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"research/patent/skills/patent/scripts/family_resolver.py"},"region":{"startLine":138}}}],"partialFingerprints":{"codehealthFindingId/v1":"b2a3c810da0f417e016b17c5f42e193640a1779ffaf35083173e6f884bac766b"}},{"ruleId":"D2","level":"warning","message":{"text":"check_dual_publish.discover_pairs (cognitive 27): check_dual_publish.discover_pairs has cognitive complexity 27 (threshold 15). Drivers by points: if/else 6 (17 pts), loops 4 (9 pts), boolean chains 1 (nesting depth added 16). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"scripts/check_dual_publish.py"},"region":{"startLine":53}}}],"partialFingerprints":{"codehealthFindingId/v1":"6b8ff0db05ab0242dbc8fdc21387d29f78373170019d6bad4e0904c525e5d02e"}},{"ruleId":"D2","level":"warning","message":{"text":"check_plugin_json.main (cognitive 27): check_plugin_json.main has cognitive complexity 27 (threshold 15). Drivers by points: if/else 9 (13 pts), loops 5 (13 pts), ternaries 1 (nesting depth added 12). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"scripts/check_plugin_json.py"},"region":{"startLine":204}}}],"partialFingerprints":{"codehealthFindingId/v1":"490d04a4b41ffb480278d812117cbb062d5f75eb177b074f66d95aec80d0fdf7"}},{"ruleId":"D2","level":"warning","message":{"text":"cron_validator.main (cognitive 26): cron_validator.main has cognitive complexity 26 (threshold 15). Drivers by points: ternaries 6 (14 pts), if/else 5 (6 pts), loops 2 (4 pts), boolean chains 2 (nesting depth added 11). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"agent-launcher/skills/run-without-you/scripts/cron_validator.py"},"region":{"startLine":86}}}],"partialFingerprints":{"codehealthFindingId/v1":"e73abec55e2da5720eb308330b37a7179b586e20066eb1890fe2beca19f27585"}},{"ruleId":"D2","level":"warning","message":{"text":"deployment_builder.main (cognitive 26): deployment_builder.main has cognitive complexity 26 (threshold 15). Drivers by points: if/else 11 (15 pts), boolean chains 7, ternaries 2 (4 pts) (nesting depth added 6). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"agent-launcher/skills/run-without-you/scripts/deployment_builder.py"},"region":{"startLine":58}}}],"partialFingerprints":{"codehealthFindingId/v1":"ef1c17e243ba87a7073707dc268dce0d24446c301b53b88db297111c1a066fb9"}},{"ruleId":"D2","level":"warning","message":{"text":"supplier_consolidation.render_markdown (cognitive 26): supplier_consolidation.render_markdown has cognitive complexity 26 (threshold 15). Drivers by points: if/else 9 (11 pts), loops 3 (7 pts), boolean chains 4, ternaries 1 (4 pts) (nesting depth added 9). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"business-operations/skills/procurement-optimizer/scripts/supplier_consolidation.py"},"region":{"startLine":223}}}],"partialFingerprints":{"codehealthFindingId/v1":"a47fa654b33d369c35da4b73eb555bb6eaf35b10c7df6c2223002be2b73858de"}},{"ruleId":"D2","level":"warning","message":{"text":"decision_tracker.report_search (cognitive 26): decision_tracker.report_search has cognitive complexity 26 (threshold 15). Drivers by points: if/else 9 (21 pts), loops 2 (5 pts) (nesting depth added 15). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"c-level-advisor/skills/decision-logger/scripts/decision_tracker.py"},"region":{"startLine":367}}}],"partialFingerprints":{"codehealthFindingId/v1":"5438a1e1e9dc5c9cf6bda61c94775106493619bd4e11b6cd69983da99cb01ffd"}},{"ruleId":"D2","level":"warning","message":{"text":"complexity_checker.extract_functions (cognitive 26): complexity_checker.extract_functions has cognitive complexity 26 (threshold 15). Drivers by points: if/else 4 (14 pts), boolean chains 6, loops 2 (3 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":"engineering/karpathy-coder/skills/karpathy-coder/scripts/complexity_checker.py"},"region":{"startLine":99}}}],"partialFingerprints":{"codehealthFindingId/v1":"f8ca59dbd2597c7d28c6cf027defa70dbd71621c55f8b6706f3365ef49c8fc10"}},{"ruleId":"D2","level":"warning","message":{"text":"question_bank_generator.format_human_readable (cognitive 26): question_bank_generator.format_human_readable has cognitive complexity 26 (threshold 15). Drivers by points: if/else 7 (13 pts), loops 8 (13 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":"engineering/skills/interview-system-designer/question_bank_generator.py"},"region":{"startLine":880}}}],"partialFingerprints":{"codehealthFindingId/v1":"8713635351f99a1deb70950d0306e8230637d81b3a3882cebf23a226156ba15c"}},{"ruleId":"D2","level":"warning","message":{"text":"SchemaCompatibilityChecker._analyze_endpoint_changes (cognitive 26): SchemaCompatibilityChecker._analyze_endpoint_changes has cognitive complexity 26 (threshold 15). Drivers by points: if/else 6 (19 pts), loops 4 (7 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":"engineering/skills/migration-architect/scripts/compatibility_checker.py"},"region":{"startLine":534}}}],"partialFingerprints":{"codehealthFindingId/v1":"1b240d616483bea112f3a3297ab3b5fde229d66ba2057fa2a91f3c474ebd22a2"}},{"ruleId":"D2","level":"warning","message":{"text":"ship_gate_scanner.run_manual_checks (cognitive 26): ship_gate_scanner.run_manual_checks has cognitive complexity 26 (threshold 15). Drivers by points: if/else 6 (12 pts), loops 4 (6 pts), boolean chains 5, 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":"engineering/skills/ship-gate/scripts/ship_gate_scanner.py"},"region":{"startLine":977}}}],"partialFingerprints":{"codehealthFindingId/v1":"40044629bc68f70060e326e4ccb6c13cc3c307734c6f551ecdd42606b511d3c2"}},{"ruleId":"D2","level":"warning","message":{"text":"markdown_parser.parse_markdown (cognitive 26): markdown_parser.parse_markdown has cognitive complexity 26 (threshold 15). Drivers by points: if/else 10 (22 pts), boolean chains 3, loops 1 (nesting depth added 12). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"markdown-html/skills/md-document/scripts/markdown_parser.py"},"region":{"startLine":208}}}],"partialFingerprints":{"codehealthFindingId/v1":"c6f8b08a3594d5c07297954727cc51e89520ad858d6be6bfda203f52336f7e19"}},{"ruleId":"D2","level":"warning","message":{"text":"hig_checker.main (cognitive 26): hig_checker.main has cognitive complexity 26 (threshold 15). Drivers by points: if/else 8 (18 pts), boolean chains 2, error handling 1 (2 pts), loops 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":"product-team/apple-hig-expert/skills/apple-hig-expert/scripts/hig_checker.py"},"region":{"startLine":36}}}],"partialFingerprints":{"codehealthFindingId/v1":"950dba957319420406b0522dbafc850b1a82aae8bcf1efb792295c2540895ad8"}},{"ruleId":"D2","level":"warning","message":{"text":"jql_query_builder.build_jql_from_description (cognitive 26): jql_query_builder.build_jql_from_description has cognitive complexity 26 (threshold 15). Drivers by points: if/else 16 (20 pts), boolean chains 5, loops 1 (nesting depth added 4). To reduce it, split the body: most of this score is breadth rather than depth \u2014 checks laid out side by side rather than stacked \u2014 so group the statements between the checks into named steps and move each step into its own function. Some of it IS depth: where a check sits inside another whose only job is to reach it, merge the two into one condition, and where an else follows a branch that already returns, drop the trailing else and let the rest of the body continue at one level."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"project-management/skills/jira-expert/scripts/jql_query_builder.py"},"region":{"startLine":209}}}],"partialFingerprints":{"codehealthFindingId/v1":"350ef9c5a2a9f9f794cf89393c7b864b7821291bb10afa0c7cb10a200fcc4753"}},{"ruleId":"D2","level":"warning","message":{"text":"CAPATracker.calculate_metrics (cognitive 26): CAPATracker.calculate_metrics has cognitive complexity 26 (threshold 15). Drivers by points: if/else 15 (21 pts), loops 4, boolean chains 1 (nesting depth added 6). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"ra-qm-team/skills/capa-officer/scripts/capa_tracker.py"},"region":{"startLine":114}}}],"partialFingerprints":{"codehealthFindingId/v1":"3f3a26528c2f2ac630e95439097f9f871ad59feac18d1a1d109f1ac665fd9965"}},{"ruleId":"D2","level":"warning","message":{"text":"root_cause_analyzer.format_rca_text (cognitive 26): root_cause_analyzer.format_rca_text has cognitive complexity 26 (threshold 15). Drivers by points: if/else 5 (12 pts), loops 6 (12 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":"ra-qm-team/skills/capa-officer/scripts/root_cause_analyzer.py"},"region":{"startLine":363}}}],"partialFingerprints":{"codehealthFindingId/v1":"3e5fdd0edcff4fdbe07b9a245538827130a0e52316800f1f4623fd0a9e6003ec"}},{"ruleId":"D2","level":"warning","message":{"text":"generate-docs.find_skill_files (cognitive 26): generate-docs.find_skill_files has cognitive complexity 26 (threshold 15). Drivers by points: if/else 7 (15 pts), loops 3 (4 pts), ternaries 1 (4 pts), boolean chains 3 (nesting depth added 12). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"scripts/generate-docs.py"},"region":{"startLine":41}}}],"partialFingerprints":{"codehealthFindingId/v1":"8974a02a0171f49d7a42fd3ab1b3720dce3c3245c059df4c84166566ee519d4e"}},{"ruleId":"D2","level":"warning","message":{"text":"full-page-screenshot.modeTarget (cognitive 26): full-page-screenshot.modeTarget has cognitive complexity 26 (threshold 15). Drivers by points: if/else 8 (13 pts), error handling 5 (12 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":"engineering/skills/full-page-screenshot/scripts/full-page-screenshot.mjs"},"region":{"startLine":871}}}],"partialFingerprints":{"codehealthFindingId/v1":"39e8534631cda5807b4b91546f60c65dec672a3fae965bc7851501f65f7dabff"}},{"ruleId":"D2","level":"warning","message":{"text":"comms_calendar_builder.build_calendar (cognitive 25): comms_calendar_builder.build_calendar has cognitive complexity 25 (threshold 15). Drivers by points: if/else 13 (15 pts), boolean chains 7, ternaries 1 (2 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."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"business-operations/skills/internal-comms/scripts/comms_calendar_builder.py"},"region":{"startLine":78}}}],"partialFingerprints":{"codehealthFindingId/v1":"5ccc34bb5b4b7424d84910909121a4f56089bbcd5d8c0917ed31adbf71ec5921"}},{"ruleId":"D2","level":"warning","message":{"text":"hiring_plan_modeler.print_report (cognitive 25): hiring_plan_modeler.print_report has cognitive complexity 25 (threshold 15). Drivers by points: if/else 7 (14 pts), loops 6 (8 pts), ternaries 1 (3 pts) (nesting depth added 11). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"c-level-advisor/skills/chro-advisor/scripts/hiring_plan_modeler.py"},"region":{"startLine":275}}}],"partialFingerprints":{"codehealthFindingId/v1":"6f2bbfba25ef984264144541bfd7facbbe95a3401cb92c513aa46df779e17e91"}},{"ruleId":"D2","level":"warning","message":{"text":"ops_efficiency_analyzer.analyze_team_structure (cognitive 25): ops_efficiency_analyzer.analyze_team_structure has cognitive complexity 25 (threshold 15). Drivers by points: ternaries 5 (13 pts), if/else 4 (7 pts), loops 3 (4 pts), boolean chains 1 (nesting depth added 12). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"c-level-advisor/skills/coo-advisor/scripts/ops_efficiency_analyzer.py"},"region":{"startLine":320}}}],"partialFingerprints":{"codehealthFindingId/v1":"2bc7ef5b8dbd885798bea49d732b8a720f21271c91b1565d3c2517c95fba011e"}},{"ruleId":"D2","level":"warning","message":{"text":"portfolio_analyzer._product_findings (cognitive 25): portfolio_analyzer._product_findings has cognitive complexity 25 (threshold 15). Drivers by points: if/else 16 (25 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":"c-level-advisor/skills/cpo-advisor/scripts/portfolio_analyzer.py"},"region":{"startLine":222}}}],"partialFingerprints":{"codehealthFindingId/v1":"0b029f9fbc55bfff7bcba65742a30bd718936dd626d75253aa0fcad856862d79"}},{"ruleId":"D2","level":"warning","message":{"text":"decision_tracker.main (cognitive 25): decision_tracker.main has cognitive complexity 25 (threshold 15). Drivers by points: if/else 12 (16 pts), ternaries 2 (6 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":"c-level-advisor/skills/decision-logger/scripts/decision_tracker.py"},"region":{"startLine":546}}}],"partialFingerprints":{"codehealthFindingId/v1":"4e70876ec74deb41c715b5847a54348ef7e37e7c8d741ee66518f05e7fb48d35"}},{"ruleId":"D2","level":"warning","message":{"text":"review_report_generator.format_markdown_report (cognitive 25): review_report_generator.format_markdown_report has cognitive complexity 25 (threshold 15). Drivers by points: if/else 8 (10 pts), loops 5 (9 pts), ternaries 2 (6 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":"engineering-team/skills/code-reviewer/scripts/review_report_generator.py"},"region":{"startLine":224}}}],"partialFingerprints":{"codehealthFindingId/v1":"8058c87ffc83d4a9de67d40716458dc72a0252e21cbcb1874bc9be8f7731040d"}},{"ruleId":"D2","level":"warning","message":{"text":"project_architect.main (cognitive 25): project_architect.main has cognitive complexity 25 (threshold 15). Drivers by points: if/else 12 (16 pts), loops 2 (6 pts), ternaries 1 (3 pts) (nesting depth added 10). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/skills/senior-architect/scripts/project_architect.py"},"region":{"startLine":647}}}],"partialFingerprints":{"codehealthFindingId/v1":"18fd0b90934941992df7a40507776bdaa3430a3d5ec7b199528f413adaf19ece"}},{"ruleId":"D2","level":"warning","message":{"text":"bundle_analyzer.analyze_imports (cognitive 25): bundle_analyzer.analyze_imports has cognitive complexity 25 (threshold 15). Drivers by points: if/else 3 (11 pts), loops 4 (10 pts), error handling 1 (4 pts) (nesting depth added 17). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/skills/senior-frontend/scripts/bundle_analyzer.py"},"region":{"startLine":220}}}],"partialFingerprints":{"codehealthFindingId/v1":"ae19040eb58ff1f6f11d86fc97e028eac6b3afdac497d05411f93f996de2a499"}},{"ruleId":"D2","level":"warning","message":{"text":"bundle_analyzer.print_report (cognitive 25): bundle_analyzer.print_report has cognitive complexity 25 (threshold 15). Drivers by points: if/else 11 (14 pts), loops 5 (11 pts) (nesting depth added 9). To reduce it, split the body: most of this score is breadth rather than depth \u2014 checks laid out side by side rather than stacked \u2014 so group the statements between the checks into named steps and move each step into its own function. Some of it IS depth: where a check sits inside another whose only job is to reach it, merge the two into one condition, and where an else follows a branch that already returns, drop the trailing else and let the rest of the body continue at one level."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/skills/senior-frontend/scripts/bundle_analyzer.py"},"region":{"startLine":293}}}],"partialFingerprints":{"codehealthFindingId/v1":"192c4b794de62461a8280a17961adb75aedea915646ca4b9c1dca911ca7be0b2"}},{"ruleId":"D2","level":"warning","message":{"text":"setup_experiment.list_experiments (cognitive 25): setup_experiment.list_experiments has cognitive complexity 25 (threshold 15). Drivers by points: if/else 7 (17 pts), loops 4 (7 pts), boolean chains 1 (nesting depth added 13). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/autoresearch-agent/skills/autoresearch-agent/scripts/setup_experiment.py"},"region":{"startLine":178}}}],"partialFingerprints":{"codehealthFindingId/v1":"0769f8935b6e3d91263e866bcdaa544a1d113b61aa77b88f798e6a5bdafb31bf"}},{"ruleId":"D2","level":"warning","message":{"text":"APIScoringEngine._check_naming_consistency (cognitive 25): APIScoringEngine._check_naming_consistency has cognitive complexity 25 (threshold 15). Drivers by points: if/else 5 (13 pts), loops 5 (8 pts), boolean chains 3, ternaries 1 (nesting depth added 11). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/api-design-reviewer/scripts/api_scorecard.py"},"region":{"startLine":223}}}],"partialFingerprints":{"codehealthFindingId/v1":"6ed7ed5a59bce04d169ffa7cfecb3393ea1a88d784dc6a0543d2e5ec82de3d53"}},{"ruleId":"D2","level":"warning","message":{"text":"score.resolve_sector (cognitive 25): score.resolve_sector has cognitive complexity 25 (threshold 15). Drivers by points: if/else 7 (13 pts), loops 6 (8 pts), boolean chains 4 (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":"finance/skills/stock-analysis/scripts/score.py"},"region":{"startLine":157}}}],"partialFingerprints":{"codehealthFindingId/v1":"5d392b3822e185dce7e6a8968b4db255e008dc7db56cbe3c0e35fe61c9b33178"}},{"ruleId":"D2","level":"warning","message":{"text":"score.score_metric (cognitive 25): score.score_metric has cognitive complexity 25 (threshold 15). Drivers by points: if/else 12 (16 pts), boolean chains 5, ternaries 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":"finance/skills/stock-analysis/scripts/score.py"},"region":{"startLine":364}}}],"partialFingerprints":{"codehealthFindingId/v1":"2dd6b9c03fd8da72215f6a59adefa3de3946d26c3d77a9110f9df1efcbc4f261"}},{"ruleId":"D2","level":"warning","message":{"text":"score.aggregate (cognitive 25): score.aggregate has cognitive complexity 25 (threshold 15). Drivers by points: if/else 6 (10 pts), ternaries 4 (7 pts), loops 5, 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":"finance/skills/stock-analysis/scripts/score.py"},"region":{"startLine":479}}}],"partialFingerprints":{"codehealthFindingId/v1":"a2d5f6168d9b9177f779fa4674ec8d8dc0608df6eb8b7135738235e7a5e9ab54"}},{"ruleId":"D2","level":"warning","message":{"text":"comparison_matrix_builder.build_matrix (cognitive 25): comparison_matrix_builder.build_matrix has cognitive complexity 25 (threshold 15). Drivers by points: if/else 8 (13 pts), ternaries 4 (7 pts), loops 4 (5 pts) (nesting depth added 9). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"marketing-skill/skills/competitor-alternatives/scripts/comparison_matrix_builder.py"},"region":{"startLine":77}}}],"partialFingerprints":{"codehealthFindingId/v1":"83e12f63e6515fbe30fb7a63723cfed597cb3a341bc800388f77e5d239767e55"}},{"ruleId":"D2","level":"warning","message":{"text":"form_field_analyzer.analyze_form (cognitive 25): form_field_analyzer.analyze_form has cognitive complexity 25 (threshold 15). Drivers by points: if/else 16 (19 pts), boolean chains 5, 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":"marketing-skill/skills/form-cro/scripts/form_field_analyzer.py"},"region":{"startLine":108}}}],"partialFingerprints":{"codehealthFindingId/v1":"f8f8f8434a3f616d802c5e19eb5a55c5e90dd7a9404446dbfaca751519b169a2"}},{"ruleId":"D2","level":"warning","message":{"text":"headline_scorer.score_headline (cognitive 25): headline_scorer.score_headline has cognitive complexity 25 (threshold 15). Drivers by points: if/else 12, ternaries 11, boolean chains 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":"marketing/linkedin/skills/linkedin-profile/scripts/headline_scorer.py"},"region":{"startLine":103}}}],"partialFingerprints":{"codehealthFindingId/v1":"86389d39841ddc36e31dcb27974e45b30ebe8164bfd3621b4ecaf08066a37684"}},{"ruleId":"D2","level":"warning","message":{"text":"session_start._find_latest (cognitive 25): session_start._find_latest has cognitive complexity 25 (threshold 15). Drivers by points: if/else 5 (14 pts), error handling 2 (5 pts), loops 2 (3 pts), boolean chains 2, ternaries 1 (nesting depth added 13). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"productivity/handoff/hooks/session_start.py"},"region":{"startLine":66}}}],"partialFingerprints":{"codehealthFindingId/v1":"f06e53bcb84a99e8265de60d9b02d95a86bd4c39b626f847a6235857da608d37"}},{"ruleId":"D2","level":"warning","message":{"text":"citation_tracker.normalize_export (cognitive 25): citation_tracker.normalize_export has cognitive complexity 25 (threshold 15). Drivers by points: if/else 7 (16 pts), boolean chains 4, error handling 1 (3 pts), loops 1, ternaries 1 (nesting depth added 11). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"research/pulse/skills/pulse/scripts/citation_tracker.py"},"region":{"startLine":227}}}],"partialFingerprints":{"codehealthFindingId/v1":"f6f02b2a1b01da517724a91765a6df982e3675c4c63117a6996fbd681b725e1a"}},{"ruleId":"D2","level":"warning","message":{"text":"check_paths.extract_candidates (cognitive 25): check_paths.extract_candidates has cognitive complexity 25 (threshold 15). Drivers by points: if/else 6 (18 pts), boolean chains 4, loops 2 (3 pts) (nesting depth added 13). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"scripts/check_paths.py"},"region":{"startLine":72}}}],"partialFingerprints":{"codehealthFindingId/v1":"2807fa138500bff3b1254d344c9312281a2050cd0463250deba52fbb22cfbab3"}},{"ruleId":"D2","level":"warning","message":{"text":"scenario_modeler.print_report (cognitive 24): scenario_modeler.print_report has cognitive complexity 24 (threshold 15). Drivers by points: loops 7 (10 pts), if/else 5 (8 pts), ternaries 2 (4 pts), boolean chains 2 (nesting depth added 8). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"c-level-advisor/skills/scenario-war-room/scripts/scenario_modeler.py"},"region":{"startLine":212}}}],"partialFingerprints":{"codehealthFindingId/v1":"57b76054cfb59e2a695a5ae15e967c926c04e143d5d6116c9314f88e2d62bbec"}},{"ruleId":"D2","level":"warning","message":{"text":"packaging_designer.detect_anti_patterns (cognitive 24): packaging_designer.detect_anti_patterns has cognitive complexity 24 (threshold 15). Drivers by points: if/else 11 (16 pts), boolean chains 7, 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":"commercial/skills/pricing-strategist/scripts/packaging_designer.py"},"region":{"startLine":107}}}],"partialFingerprints":{"codehealthFindingId/v1":"fc9a82921e41bfd3b95991c50d262e9c309f8d887082f9d9b8f1378b3e2fccfa"}},{"ruleId":"D2","level":"warning","message":{"text":"DatasetValidator._validate_yolo (cognitive 24): DatasetValidator._validate_yolo has cognitive complexity 24 (threshold 15). Drivers by points: if/else 5 (14 pts), error handling 2 (5 pts), loops 2 (3 pts), boolean chains 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":"engineering-team/skills/senior-computer-vision/scripts/dataset_pipeline_builder.py"},"region":{"startLine":1354}}}],"partialFingerprints":{"codehealthFindingId/v1":"b8638692ea98a9eb929617d66a88f638f41fccc446d9035c1d215d7da2929430"}},{"ruleId":"D2","level":"warning","message":{"text":"prompt_rater.rate (cognitive 24): prompt_rater.rate has cognitive complexity 24 (threshold 15). Drivers by points: if/else 8 (13 pts), ternaries 7, boolean chains 4 (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":"engineering/claude-coach/skills/claude-coach/scripts/prompt_rater.py"},"region":{"startLine":57}}}],"partialFingerprints":{"codehealthFindingId/v1":"0e653aaa4b67dfa65b99c0f05b0e3882b2a53bc9aa22919c09fc9fc190c4e800"}},{"ruleId":"D2","level":"warning","message":{"text":"outlier_detector.print_report (cognitive 24): outlier_detector.print_report has cognitive complexity 24 (threshold 15). Drivers by points: if/else 10 (18 pts), ternaries 1 (3 pts), loops 1 (2 pts), boolean chains 1 (nesting depth added 11). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/data-quality-auditor/skills/data-quality-auditor/scripts/outlier_detector.py"},"region":{"startLine":174}}}],"partialFingerprints":{"codehealthFindingId/v1":"7407c6e9b74e50d7e1fa21995cdaa7c21dd6c81ec4fd3804bc3f34fd01e3eac9"}},{"ruleId":"D2","level":"warning","message":{"text":"feedback_parser.render_human (cognitive 24): feedback_parser.render_human has cognitive complexity 24 (threshold 15). Drivers by points: if/else 7 (13 pts), loops 2 (4 pts), ternaries 2 (4 pts), boolean chains 3 (nesting depth added 10). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/human-gate/skills/human-gate/scripts/feedback_parser.py"},"region":{"startLine":391}}}],"partialFingerprints":{"codehealthFindingId/v1":"199f5ae2300122d8485a3da9bdd623e3e1f1e8f8df4354a7e4ff10a27248bbda"}},{"ruleId":"D2","level":"warning","message":{"text":"APILinter._validate_path_structure (cognitive 24): APILinter._validate_path_structure has cognitive complexity 24 (threshold 15). Drivers by points: if/else 12 (21 pts), boolean chains 2, loops 1 (nesting depth added 9). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/api-design-reviewer/scripts/api_linter.py"},"region":{"startLine":279}}}],"partialFingerprints":{"codehealthFindingId/v1":"49bc4cd2c83865cf6ef6cdc42d8b38cfdd78489a4100148bdf7402af1bda5385"}},{"ruleId":"D2","level":"warning","message":{"text":"APIScoringEngine._check_response_consistency (cognitive 24): APIScoringEngine._check_response_consistency has cognitive complexity 24 (threshold 15). Drivers by points: loops 5 (11 pts), if/else 4 (10 pts), ternaries 2, boolean chains 1 (nesting depth added 12). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/api-design-reviewer/scripts/api_scorecard.py"},"region":{"startLine":255}}}],"partialFingerprints":{"codehealthFindingId/v1":"32bb4b157b463090ccd7cd5b055c2f44039a6ad3e3ba45f0d112d093e8e8f188"}},{"ruleId":"D2","level":"warning","message":{"text":"HiringCalibrator._analyze_interviewer_bias (cognitive 24): HiringCalibrator._analyze_interviewer_bias has cognitive complexity 24 (threshold 15). Drivers by points: if/else 6 (15 pts), ternaries 3 (5 pts), loops 3 (4 pts) (nesting depth added 12). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/interview-system-designer/hiring_calibrator.py"},"region":{"startLine":335}}}],"partialFingerprints":{"codehealthFindingId/v1":"530e1e3cec8b16cadb5f8be5c543dfbdb8064349f7cfceac51de502adfc19a27"}},{"ruleId":"D2","level":"warning","message":{"text":"QuestionBankGenerator._generate_questions (cognitive 24): QuestionBankGenerator._generate_questions has cognitive complexity 24 (threshold 15). Drivers by points: if/else 5 (13 pts), loops 3 (6 pts), ternaries 1 (3 pts), boolean chains 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":"engineering/skills/interview-system-designer/question_bank_generator.py"},"region":{"startLine":617}}}],"partialFingerprints":{"codehealthFindingId/v1":"4cddb28bd3ef9749b5c96896508c45cdcdf213be012ca498ca5e214e8d0836c5"}},{"ruleId":"D2","level":"warning","message":{"text":"SemanticChunker._chunk_section (cognitive 24): SemanticChunker._chunk_section has cognitive complexity 24 (threshold 15). Drivers by points: if/else 8 (12 pts), ternaries 4 (8 pts), boolean chains 3, loops 1 (nesting depth added 8). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/rag-architect/chunking_optimizer.py"},"region":{"startLine":364}}}],"partialFingerprints":{"codehealthFindingId/v1":"7f8cb6abae164efc3bb8a036db95112083118324e8248f0f05ef676cd923a0b2"}},{"ruleId":"D2","level":"warning","message":{"text":"TestReportFormatter.format_human_readable (cognitive 24): TestReportFormatter.format_human_readable has cognitive complexity 24 (threshold 15). Drivers by points: loops 5 (12 pts), if/else 5 (8 pts), ternaries 1 (4 pts) (nesting depth added 13). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/skill-tester/scripts/script_tester.py"},"region":{"startLine":598}}}],"partialFingerprints":{"codehealthFindingId/v1":"1b597f267d5ff0bf79b174cb2fbc7961f370fbc8e402f0b4b881f05fd7305c0e"}},{"ruleId":"D2","level":"warning","message":{"text":"Analysis.not_computed (cognitive 24): Analysis.not_computed has cognitive complexity 24 (threshold 15). Drivers by points: if/else 3 (9 pts), loops 4 (8 pts), ternaries 1 (4 pts), boolean chains 3 (nesting depth added 13). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"finance/skills/stock-analysis/scripts/ratios.py"},"region":{"startLine":2277}}}],"partialFingerprints":{"codehealthFindingId/v1":"fc151b59926f4fd33dd285ed2dbfba6cf71abee9a0bb12ef3fb5782466e91e69"}},{"ruleId":"D2","level":"warning","message":{"text":"tracking_plan_generator.print_report (cognitive 24): tracking_plan_generator.print_report has cognitive complexity 24 (threshold 15). Drivers by points: ternaries 4 (14 pts), loops 5 (7 pts), if/else 2 (3 pts) (nesting depth added 13). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"marketing-skill/skills/analytics-tracking/scripts/tracking_plan_generator.py"},"region":{"startLine":299}}}],"partialFingerprints":{"codehealthFindingId/v1":"188be6397ca5dc85613b4e4620f0a46f00118909581261bfb8eff59bafa74b15"}},{"ruleId":"D2","level":"warning","message":{"text":"sequence_analyzer.main (cognitive 24): sequence_analyzer.main has cognitive complexity 24 (threshold 15). Drivers by points: if/else 8 (12 pts), loops 4 (6 pts), ternaries 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":"marketing-skill/skills/email-sequence/scripts/sequence_analyzer.py"},"region":{"startLine":270}}}],"partialFingerprints":{"codehealthFindingId/v1":"f329e849c9e9c272f8a399ea5da02609476258da4417c2e1694161274db83259"}},{"ruleId":"D2","level":"warning","message":{"text":"directional_recommendation_validator.validate (cognitive 24): directional_recommendation_validator.validate has cognitive complexity 24 (threshold 15). Drivers by points: if/else 16 (19 pts), loops 4 (5 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, 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":"productivity/reflect/skills/reflect/scripts/directional_recommendation_validator.py"},"region":{"startLine":91}}}],"partialFingerprints":{"codehealthFindingId/v1":"3408c949a8f307dccd11e7c2725ebdf236a3f21b471190ae8bbb3dced3ee340d"}},{"ruleId":"D2","level":"warning","message":{"text":"a11y_scanner.check_table_headers (cognitive 23): a11y_scanner.check_table_headers has cognitive complexity 23 (threshold 15). Drivers by points: if/else 7 (21 pts), boolean chains 1, loops 1 (nesting depth added 14). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/a11y-audit/skills/a11y-audit/scripts/a11y_scanner.py"},"region":{"startLine":365}}}],"partialFingerprints":{"codehealthFindingId/v1":"c38fabb7665d986cb53dd5c4c8de9a890880d7a34ce3cc6ae475b74dc2c23d06"}},{"ruleId":"D2","level":"warning","message":{"text":"code_quality_checker.check_code_smells (cognitive 23): code_quality_checker.check_code_smells has cognitive complexity 23 (threshold 15). Drivers by points: if/else 6 (12 pts), loops 7 (8 pts), ternaries 1 (3 pts) (nesting depth added 9). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/skills/code-reviewer/scripts/code_quality_checker.py"},"region":{"startLine":336}}}],"partialFingerprints":{"codehealthFindingId/v1":"bfb607873425125239b01d3c48ee14e46d9513af01ebebb0b7b1c336628b0e9d"}},{"ruleId":"D2","level":"warning","message":{"text":"CostOptimizer._analyze_compute (cognitive 23): CostOptimizer._analyze_compute has cognitive complexity 23 (threshold 15). Drivers by points: if/else 10 (20 pts), loops 2, boolean chains 1 (nesting depth added 10). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/skills/gcp-cloud-architect/scripts/cost_optimizer.py"},"region":{"startLine":61}}}],"partialFingerprints":{"codehealthFindingId/v1":"848c7c307bf8bceae9dd1fedb8b310f4129df764d50b749d56bcc094ecd2a27d"}},{"ruleId":"D2","level":"warning","message":{"text":"PIRGenerator._create_rca_section (cognitive 23): PIRGenerator._create_rca_section has cognitive complexity 23 (threshold 15). Drivers by points: if/else 5 (11 pts), loops 4 (10 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":"engineering-team/skills/incident-commander/scripts/pir_generator.py"},"region":{"startLine":1163}}}],"partialFingerprints":{"codehealthFindingId/v1":"676c7d6e8ed8b9944d90b8c76fbc1403d15a1b84858839a652714ac00494a1f8"}},{"ruleId":"D2","level":"warning","message":{"text":"DependencyAnalyzer._parse_poetry (cognitive 23): DependencyAnalyzer._parse_poetry has cognitive complexity 23 (threshold 15). Drivers by points: if/else 7 (18 pts), boolean chains 3, error handling 1, loops 1 (nesting depth added 11). To reduce it, flatten the nesting: this score is depth rather than breadth \u2014 most of its points come from checks stacked inside one another, so the work sits several levels in. Invert each enclosing check into an early exit (a return, or the language\u0027s equivalent) so the happy path stays at one level, and where a level cannot be exited early, lift the block it encloses into its own named function."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/skills/senior-architect/scripts/dependency_analyzer.py"},"region":{"startLine":140}}}],"partialFingerprints":{"codehealthFindingId/v1":"0470f270a5b70168cdd9da4e933fe667ea47646811c3d428d2330b9534ad0957"}},{"ruleId":"D2","level":"warning","message":{"text":"DatasetAnalyzer._analyze_coco (cognitive 23): DatasetAnalyzer._analyze_coco has cognitive complexity 23 (threshold 15). Drivers by points: if/else 6 (15 pts), loops 3 (6 pts), error handling 1 (2 pts) (nesting depth added 13). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/skills/senior-computer-vision/scripts/dataset_pipeline_builder.py"},"region":{"startLine":293}}}],"partialFingerprints":{"codehealthFindingId/v1":"f3a00ab6b40909ab4466145214716aa9fc7acf5e1f87f0c8294d46ecfb22c714"}},{"ruleId":"D2","level":"warning","message":{"text":"threat_signal_analyzer.ioc_mode (cognitive 23): threat_signal_analyzer.ioc_mode has cognitive complexity 23 (threshold 15). Drivers by points: if/else 7 (13 pts), error handling 3 (4 pts), loops 3 (4 pts), boolean chains 1, ternaries 1 (nesting depth added 8). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/skills/threat-detection/scripts/threat_signal_analyzer.py"},"region":{"startLine":161}}}],"partialFingerprints":{"codehealthFindingId/v1":"3090f23cdcd3ab52d9f1ce6937e7212b4b955c413f64e771165d8c771b7ad0ab"}},{"ruleId":"D2","level":"warning","message":{"text":"memory_promote.promote_l2_to_l3 (cognitive 23): memory_promote.promote_l2_to_l3 has cognitive complexity 23 (threshold 15). Drivers by points: if/else 6 (14 pts), loops 4 (7 pts), boolean chains 2 (nesting depth added 11). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/agent-memory/skills/agent-memory/scripts/memory_promote.py"},"region":{"startLine":78}}}],"partialFingerprints":{"codehealthFindingId/v1":"00a15626f0ccdfc076ce2cec3d8ef782721f3f26f339ed17536a29b0efc5dc30"}},{"ruleId":"D2","level":"warning","message":{"text":"setup_experiment.main (cognitive 23): setup_experiment.main has cognitive complexity 23 (threshold 15). Drivers by points: if/else 15 (20 pts), loops 1 (2 pts), boolean chains 1 (nesting depth added 6). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/autoresearch-agent/skills/autoresearch-agent/scripts/setup_experiment.py"},"region":{"startLine":251}}}],"partialFingerprints":{"codehealthFindingId/v1":"919b0e4ab1ef7f6b24fea13c1a0cd874975cb8b17b6c79cd09dd5ff803cf1872"}},{"ruleId":"D2","level":"warning","message":{"text":"APIScoringEngine._check_developer_experience (cognitive 23): APIScoringEngine._check_developer_experience has cognitive complexity 23 (threshold 15). Drivers by points: if/else 7 (15 pts), loops 3 (5 pts), ternaries 2, boolean chains 1 (nesting depth added 10). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/api-design-reviewer/scripts/api_scorecard.py"},"region":{"startLine":1212}}}],"partialFingerprints":{"codehealthFindingId/v1":"787b9fbae9691175a1a8ea8e8a4bcbf355adfeb6ea08f69f537c18c329479aa8"}},{"ruleId":"D2","level":"warning","message":{"text":"AlertOptimizer.analyze_alert_noise (cognitive 23): AlertOptimizer.analyze_alert_noise has cognitive complexity 23 (threshold 15). Drivers by points: if/else 8 (19 pts), loops 2 (3 pts), boolean chains 1 (nesting depth added 12). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/observability-designer/scripts/alert_optimizer.py"},"region":{"startLine":82}}}],"partialFingerprints":{"codehealthFindingId/v1":"86b02027df9f7f35de843bc6d6c43b77d6015204dcd5598992e849085238884f"}},{"ruleId":"D2","level":"warning","message":{"text":"verify_data.render_text (cognitive 23): verify_data.render_text has cognitive complexity 23 (threshold 15). Drivers by points: boolean chains 11, if/else 6 (8 pts), loops 2 (3 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":"finance/skills/stock-analysis/scripts/verify_data.py"},"region":{"startLine":1452}}}],"partialFingerprints":{"codehealthFindingId/v1":"688ba92046a59620d53194a19181348885d7d72f0fac46649a44876ef20ebb0e"}},{"ruleId":"D2","level":"warning","message":{"text":"ad_copy_validator.validate_google_rsa (cognitive 23): ad_copy_validator.validate_google_rsa has cognitive complexity 23 (threshold 15). Drivers by points: if/else 10 (17 pts), ternaries 2 (4 pts), loops 2 (nesting depth added 9). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"marketing-skill/skills/ad-creative/scripts/ad_copy_validator.py"},"region":{"startLine":160}}}],"partialFingerprints":{"codehealthFindingId/v1":"6e9a062eb9066d7c217af8142b1ec160d2fa96dff69d6e7219176734a31b352e"}},{"ruleId":"D2","level":"warning","message":{"text":"activation_funnel_analyzer.analyze_funnel (cognitive 23): activation_funnel_analyzer.analyze_funnel has cognitive complexity 23 (threshold 15). Drivers by points: if/else 8 (13 pts), ternaries 4 (7 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":"marketing-skill/skills/onboarding-cro/scripts/activation_funnel_analyzer.py"},"region":{"startLine":31}}}],"partialFingerprints":{"codehealthFindingId/v1":"82b0bc72b859a53ba0189c62bf56abb73396fcabb42be6b0e77ae3214bb3e304"}},{"ruleId":"D2","level":"warning","message":{"text":"ad_health_scorer.score_platform (cognitive 23): ad_health_scorer.score_platform has cognitive complexity 23 (threshold 15). Drivers by points: if/else 8 (14 pts), loops 4 (5 pts), ternaries 2 (3 pts), boolean chains 1 (nesting depth added 8). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"marketing-skill/skills/paid-ads/scripts/ad_health_scorer.py"},"region":{"startLine":99}}}],"partialFingerprints":{"codehealthFindingId/v1":"7f16a946db0c18978d0e538693f3af39ccae56fd5831b2cff7c02efb94743032"}},{"ruleId":"D2","level":"warning","message":{"text":"ost_linter.lint (cognitive 23): ost_linter.lint has cognitive complexity 23 (threshold 15). Drivers by points: if/else 7 (12 pts), boolean chains 7, 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":"product-team/skills/product-skills/scripts/ost_linter.py"},"region":{"startLine":75}}}],"partialFingerprints":{"codehealthFindingId/v1":"8b9849da5861e41c785c5e68427d08bf3cc12e49e2434bf4354c20c3778338e8"}},{"ruleId":"D2","level":"warning","message":{"text":"setup.run_setup (cognitive 23): setup.run_setup has cognitive complexity 23 (threshold 15). Drivers by points: ternaries 8 (11 pts), if/else 7 (10 pts), loops 1 (2 pts) (nesting depth added 7). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"productivity/handoff/skills/handoff/scripts/setup.py"},"region":{"startLine":152}}}],"partialFingerprints":{"codehealthFindingId/v1":"d481b9d27cb5f7ee910b5de2c788045d71a1228f6a910abd59f0f16e6e3ad6b8"}},{"ruleId":"D2","level":"warning","message":{"text":"sprint_health_scorer._generate_detailed_metrics (cognitive 23): sprint_health_scorer._generate_detailed_metrics has cognitive complexity 23 (threshold 15). Drivers by points: if/else 9 (13 pts), ternaries 5 (8 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":"project-management/skills/scrum-master/scripts/sprint_health_scorer.py"},"region":{"startLine":518}}}],"partialFingerprints":{"codehealthFindingId/v1":"a30b26616c78d8b042cdce55339862aa50544133fe274c020fcd1625fac22b66"}},{"ruleId":"D2","level":"warning","message":{"text":"dpia_generator.generate_dpia_report (cognitive 23): dpia_generator.generate_dpia_report has cognitive complexity 23 (threshold 15). Drivers by points: loops 10 (15 pts), if/else 5, ternaries 3 (nesting depth added 5). To reduce it, break up the iteration: give each loop body a named function, and split a multi-phase loop into one function per phase so no single body carries the whole pipeline."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"ra-qm-team/skills/gdpr-dsgvo-expert/scripts/dpia_generator.py"},"region":{"startLine":390}}}],"partialFingerprints":{"codehealthFindingId/v1":"8b7960877b92ef4151be77f80dd78bef95de571d4a066c5559dd729f76d68472"}},{"ruleId":"D2","level":"warning","message":{"text":"onboard.main (cognitive 23): onboard.main has cognitive complexity 23 (threshold 15). Drivers by points: if/else 9 (15 pts), error handling 1 (4 pts), 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":"research-ops/skills/clinical-research/scripts/onboard.py"},"region":{"startLine":88}}}],"partialFingerprints":{"codehealthFindingId/v1":"7ae30d2c2f919ee2699b5e79e1b63308fc3cf10cced5e8180a11c5b8b3f11abc"}},{"ruleId":"D2","level":"warning","message":{"text":"onboard.main (cognitive 23): onboard.main has cognitive complexity 23 (threshold 15). Drivers by points: if/else 9 (15 pts), error handling 1 (4 pts), 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":"research-ops/skills/market-research/scripts/onboard.py"},"region":{"startLine":65}}}],"partialFingerprints":{"codehealthFindingId/v1":"2cc9c4abbac9c168e751ad6d39e02c1d815b809887144a01b12e88536ee376d0"}},{"ruleId":"D2","level":"warning","message":{"text":"onboard.main (cognitive 23): onboard.main has cognitive complexity 23 (threshold 15). Drivers by points: if/else 9 (15 pts), error handling 1 (4 pts), 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":"research-ops/skills/research-finance/scripts/onboard.py"},"region":{"startLine":68}}}],"partialFingerprints":{"codehealthFindingId/v1":"a50bcfd42112c7d528da2c0712e6982d47f96a3d8a4fbbbfde64dadd783db7be"}},{"ruleId":"D2","level":"warning","message":{"text":"action_router.main (cognitive 23): action_router.main has cognitive complexity 23 (threshold 15). Drivers by points: if/else 12 (20 pts), error handling 1 (2 pts), ternaries 1 (nesting depth added 9). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"research/notebooklm/skills/notebooklm/scripts/action_router.py"},"region":{"startLine":225}}}],"partialFingerprints":{"codehealthFindingId/v1":"c023b85e8127f68da96ec96a568724a6d30238e2814bc6f9cb801b3525730fce"}},{"ruleId":"D2","level":"warning","message":{"text":"routing_transparency_logger.main (cognitive 23): routing_transparency_logger.main has cognitive complexity 23 (threshold 15). Drivers by points: if/else 13 (18 pts), boolean chains 3, 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":"research/research/skills/research/scripts/routing_transparency_logger.py"},"region":{"startLine":127}}}],"partialFingerprints":{"codehealthFindingId/v1":"d7ea941b6ff7ce333adc5595a390c7dd0f253f120059a8888640d4056cae9df3"}},{"ruleId":"D2","level":"warning","message":{"text":"discussion_question_validator.main (cognitive 23): discussion_question_validator.main has cognitive complexity 23 (threshold 15). Drivers by points: if/else 7 (10 pts), loops 4 (10 pts), boolean chains 1, error handling 1, 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":"research/syllabus/skills/syllabus/scripts/discussion_question_validator.py"},"region":{"startLine":149}}}],"partialFingerprints":{"codehealthFindingId/v1":"09cd27f9e9c7a9ce1edfff30f18044701f107db72b98b92b9fee8bacc364a4e3"}},{"ruleId":"D2","level":"warning","message":{"text":"check_dual_publish.main (cognitive 23): check_dual_publish.main has cognitive complexity 23 (threshold 15). Drivers by points: if/else 8 (10 pts), loops 4 (9 pts), ternaries 2 (4 pts) (nesting depth added 9). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"scripts/check_dual_publish.py"},"region":{"startLine":121}}}],"partialFingerprints":{"codehealthFindingId/v1":"a90b62f941d1b6fb50d830a4090a33bd2881e53fd6478d5448f36517ad020d29"}},{"ruleId":"D2","level":"warning","message":{"text":"UserInterface.init (cognitive 23): UserInterface.init has cognitive complexity 23 (threshold 15). Drivers by points: if/else 8 (23 pts) (nesting depth added 15). To reduce it, flatten the nesting: this score is depth rather than breadth \u2014 most of its points come from checks stacked inside one another, so the work sits several levels in. Invert each enclosing check into an early exit (a return, or the language\u0027s equivalent) so the happy path stays at one level, and where a level cannot be exited early, lift the block it encloses into its own named function."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/tech-debt-tracker/assets/sample_codebase/src/frontend.js"},"region":{"startLine":29}}}],"partialFingerprints":{"codehealthFindingId/v1":"70d34e6292642d301b0e69bd0390614eb93d3ab909769103deb154c3bc5f7c1b"}},{"ruleId":"D2","level":"warning","message":{"text":"init (cognitive 23): init has cognitive complexity 23 (threshold 15). Drivers by points: if/else 8 (23 pts) (nesting depth added 15). To reduce it, flatten the nesting: this score is depth rather than breadth \u2014 most of its points come from checks stacked inside one another, so the work sits several levels in. Invert each enclosing check into an early exit (a return, or the language\u0027s equivalent) so the happy path stays at one level, and where a level cannot be exited early, lift the block it encloses into its own named function."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":".codex/skills/tech-debt-tracker/assets/sample_codebase/src/frontend.js"},"region":{"startLine":29}}}],"partialFingerprints":{"codehealthFindingId/v1":"2203edf78fab494ebbc9bb42419ed776f1d8a5120c551b7bf04125529d828a49"}},{"ruleId":"D2","level":"warning","message":{"text":"init (cognitive 23): init has cognitive complexity 23 (threshold 15). Drivers by points: if/else 8 (23 pts) (nesting depth added 15). To reduce it, flatten the nesting: this score is depth rather than breadth \u2014 most of its points come from checks stacked inside one another, so the work sits several levels in. Invert each enclosing check into an early exit (a return, or the language\u0027s equivalent) so the happy path stays at one level, and where a level cannot be exited early, lift the block it encloses into its own named function."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":".vibe/skills/claude-skills/engineering/tech-debt-tracker/assets/sample_codebase/src/frontend.js"},"region":{"startLine":29}}}],"partialFingerprints":{"codehealthFindingId/v1":"b1f8f20854403cdd9a98600f8c655b3e609adb09446369e70898a1610fa6cfa6"}},{"ruleId":"D2","level":"warning","message":{"text":"init (cognitive 23): init has cognitive complexity 23 (threshold 15). Drivers by points: if/else 8 (23 pts) (nesting depth added 15). To reduce it, flatten the nesting: this score is depth rather than breadth \u2014 most of its points come from checks stacked inside one another, so the work sits several levels in. Invert each enclosing check into an early exit (a return, or the language\u0027s equivalent) so the happy path stays at one level, and where a level cannot be exited early, lift the block it encloses into its own named function."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":".hermes/skills/claude-skills/engineering/tech-debt-tracker/assets/sample_codebase/src/frontend.js"},"region":{"startLine":29}}}],"partialFingerprints":{"codehealthFindingId/v1":"631947c7854d9049db9c45d0f4156374343d46040649e373345d2ffe4130f6a2"}},{"ruleId":"D2","level":"warning","message":{"text":"churn_risk_analyzer.format_text (cognitive 22): churn_risk_analyzer.format_text has cognitive complexity 22 (threshold 15). Drivers by points: if/else 8 (11 pts), loops 4 (9 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":"business-growth/skills/customer-success-manager/scripts/churn_risk_analyzer.py"},"region":{"startLine":366}}}],"partialFingerprints":{"codehealthFindingId/v1":"6c449f0f1c912cab11829a4c527ab07828451483a87fe5ffdf303c4b97c56c83"}},{"ruleId":"D2","level":"warning","message":{"text":"pipeline_analyzer.assess_pipeline_risk (cognitive 22): pipeline_analyzer.assess_pipeline_risk has cognitive complexity 22 (threshold 15). Drivers by points: if/else 12 (16 pts), loops 4, error handling 1 (2 pts) (nesting depth added 5). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"business-growth/skills/revenue-operations/scripts/pipeline_analyzer.py"},"region":{"startLine":203}}}],"partialFingerprints":{"codehealthFindingId/v1":"0c7ef96a5fd4d70166e46294e9b32ff0f8ddf21dd99df42bfd70ff29968a49c4"}},{"ruleId":"D2","level":"warning","message":{"text":"scaffold_bundle.main (cognitive 22): scaffold_bundle.main has cognitive complexity 22 (threshold 15). Drivers by points: if/else 6 (8 pts), ternaries 2 (6 pts), boolean chains 5, loops 1 (2 pts), error handling 1 (nesting depth added 7). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"c-level-advisor/arquiteto-de-empresa/skills/arquiteto-de-empresa/scripts/scaffold_bundle.py"},"region":{"startLine":141}}}],"partialFingerprints":{"codehealthFindingId/v1":"dc06674ec797d7dcec269aa2fd9c193fa26707fe3298cee3fb21b5b253e37f76"}},{"ruleId":"D2","level":"warning","message":{"text":"decision_matrix_scorer.print_report (cognitive 22): decision_matrix_scorer.print_report has cognitive complexity 22 (threshold 15). Drivers by points: loops 9 (11 pts), if/else 6 (7 pts), ternaries 2 (4 pts) (nesting depth added 5). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"c-level-advisor/executive-mentor/skills/executive-mentor/scripts/decision_matrix_scorer.py"},"region":{"startLine":164}}}],"partialFingerprints":{"codehealthFindingId/v1":"6a33184e3c61e1c2af9bf305f781f1a3b9e8dc69b5a81745f65ad156c7910fd1"}},{"ruleId":"D2","level":"warning","message":{"text":"scaffold_bundle.main (cognitive 22): scaffold_bundle.main has cognitive complexity 22 (threshold 15). Drivers by points: if/else 6 (8 pts), ternaries 2 (6 pts), boolean chains 5, loops 1 (2 pts), error handling 1 (nesting depth added 7). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"c-level-advisor/skills/arquiteto-de-empresa/scripts/scaffold_bundle.py"},"region":{"startLine":141}}}],"partialFingerprints":{"codehealthFindingId/v1":"514a887241e25b231d7a641ebc6371bd4c433bbf02872c4ef60b21c7cd799db0"}},{"ruleId":"D2","level":"warning","message":{"text":"alignment_checker.detect_conflicts (cognitive 22): alignment_checker.detect_conflicts has cognitive complexity 22 (threshold 15). Drivers by points: loops 6 (10 pts), if/else 2 (9 pts), boolean chains 3 (nesting depth added 11). To reduce it, break up the iteration: give each loop body a named function, and split a multi-phase loop into one function per phase so no single body carries the whole pipeline."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"c-level-advisor/skills/strategic-alignment/scripts/alignment_checker.py"},"region":{"startLine":244}}}],"partialFingerprints":{"codehealthFindingId/v1":"b363fc94d8a6ae0be39a79db642cb8866eb851cc9fa1e17b5b39ad3acd4838c4"}},{"ruleId":"D2","level":"warning","message":{"text":"channel_mix_optimizer.render_markdown (cognitive 22): channel_mix_optimizer.render_markdown has cognitive complexity 22 (threshold 15). Drivers by points: if/else 5 (8 pts), boolean chains 5, loops 3 (5 pts), ternaries 2 (4 pts) (nesting depth added 7). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"commercial/skills/channel-economics/scripts/channel_mix_optimizer.py"},"region":{"startLine":185}}}],"partialFingerprints":{"codehealthFindingId/v1":"24be73238a2771262c9e9dc59544914e9a5627d43cc863e84084649423437978"}},{"ruleId":"D2","level":"warning","message":{"text":"framework_selector.select_frameworks (cognitive 22): framework_selector.select_frameworks has cognitive complexity 22 (threshold 15). Drivers by points: if/else 11 (13 pts), boolean chains 9 (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":"compliance-os/skills/compliance-os/scripts/framework_selector.py"},"region":{"startLine":105}}}],"partialFingerprints":{"codehealthFindingId/v1":"e62c9a82907df5024cfb530a56114edb94f4e3d7dd2b0ad1b4620014b4efca54"}},{"ruleId":"D2","level":"warning","message":{"text":"IncidentClassifier._classify_severity (cognitive 22): IncidentClassifier._classify_severity has cognitive complexity 22 (threshold 15). Drivers by points: if/else 8 (14 pts), loops 3 (5 pts), error handling 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":"engineering-team/skills/incident-commander/scripts/incident_classifier.py"},"region":{"startLine":420}}}],"partialFingerprints":{"codehealthFindingId/v1":"e411508bfe2d76f8dd5e3fc185cfcdac370bf1b1bdc51017291b91d56190868d"}},{"ruleId":"D2","level":"warning","message":{"text":"PatternDetector._detect_pattern (cognitive 22): PatternDetector._detect_pattern has cognitive complexity 22 (threshold 15). Drivers by points: if/else 5 (12 pts), loops 5 (10 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":"engineering-team/skills/senior-architect/scripts/project_architect.py"},"region":{"startLine":115}}}],"partialFingerprints":{"codehealthFindingId/v1":"f367609790ab019ee7a32fe90d921cf5dc83be3a7124ba9a950c199c4f92c23c"}},{"ruleId":"D2","level":"warning","message":{"text":"DatabaseMigrationTool._analyze (cognitive 22): DatabaseMigrationTool._analyze has cognitive complexity 22 (threshold 15). Drivers by points: if/else 9 (15 pts), loops 3 (6 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":"engineering-team/skills/senior-backend/scripts/database_migration_tool.py"},"region":{"startLine":591}}}],"partialFingerprints":{"codehealthFindingId/v1":"833f7febaad7d345efcbb5bf962fc73b7de6a742de21a5c3d9c4e6c2e12c8400"}},{"ruleId":"D2","level":"warning","message":{"text":"inference_optimizer.main (cognitive 22): inference_optimizer.main has cognitive complexity 22 (threshold 15). Drivers by points: if/else 10 (15 pts), boolean chains 3, loops 1 (3 pts), error handling 1 (nesting depth added 7). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/skills/senior-computer-vision/scripts/inference_optimizer.py"},"region":{"startLine":474}}}],"partialFingerprints":{"codehealthFindingId/v1":"384c1ee8d9af175c06114f85e8e362f0d83d325b3ed8f423bc4d1235e3fb96db"}},{"ruleId":"D2","level":"warning","message":{"text":"prompt_optimizer.main (cognitive 22): prompt_optimizer.main has cognitive complexity 22 (threshold 15). Drivers by points: if/else 16 (22 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":"engineering-team/skills/senior-prompt-engineer/scripts/prompt_optimizer.py"},"region":{"startLine":417}}}],"partialFingerprints":{"codehealthFindingId/v1":"6ff59cd7880873e531b6ca0dc4f5236677023f77ff8fa46c1b5a7bc5b41c40a9"}},{"ruleId":"D2","level":"warning","message":{"text":"memory_extract.extract (cognitive 22): memory_extract.extract has cognitive complexity 22 (threshold 15). Drivers by points: if/else 4 (15 pts), loops 3 (6 pts), boolean chains 1 (nesting depth added 14). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/agent-memory/skills/agent-memory/scripts/memory_extract.py"},"region":{"startLine":86}}}],"partialFingerprints":{"codehealthFindingId/v1":"0ccc3311bdb5f1481580057b3d6dbb84f8d702ed285cce1e08fef808016a7af2"}},{"ruleId":"D2","level":"warning","message":{"text":"book_skill_validator.check_safety (cognitive 22): book_skill_validator.check_safety has cognitive complexity 22 (threshold 15). Drivers by points: if/else 7 (17 pts), loops 2 (3 pts), boolean chains 2 (nesting depth added 11). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/book-to-skill/skills/book-to-skill/scripts/book_skill_validator.py"},"region":{"startLine":369}}}],"partialFingerprints":{"codehealthFindingId/v1":"2148ba37ca0c32b21d3ad531f95f48cda060acce6eaa8f7e0f596283ce8b1736"}},{"ruleId":"D2","level":"warning","message":{"text":"book_skill_validator.check_indexes (cognitive 22): book_skill_validator.check_indexes has cognitive complexity 22 (threshold 15). Drivers by points: if/else 5 (10 pts), loops 6 (10 pts), boolean chains 2 (nesting depth added 9). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/book-to-skill/skills/book-to-skill/scripts/book_skill_validator.py"},"region":{"startLine":439}}}],"partialFingerprints":{"codehealthFindingId/v1":"debfad9ca98dfa4990360a78076726a93ac1f7f6e30e57d12e5eb233a70977cb"}},{"ruleId":"D2","level":"warning","message":{"text":"utils._structural_chapter_count (cognitive 22): utils._structural_chapter_count has cognitive complexity 22 (threshold 15). Drivers by points: if/else 7 (14 pts), boolean chains 3, ternaries 1 (3 pts), loops 2 (nesting depth added 9). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/book-to-skill/skills/book-to-skill/scripts/book_to_skill/utils.py"},"region":{"startLine":177}}}],"partialFingerprints":{"codehealthFindingId/v1":"0f0fa1f22eeff8ea9e62d013b4005aa2ab3e04c5b0b776f670a20b3d12fed98a"}},{"ruleId":"D2","level":"warning","message":{"text":"assumption_linter.main (cognitive 22): assumption_linter.main has cognitive complexity 22 (threshold 15). Drivers by points: if/else 7 (10 pts), loops 3 (6 pts), ternaries 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":"engineering/karpathy-coder/skills/karpathy-coder/scripts/assumption_linter.py"},"region":{"startLine":111}}}],"partialFingerprints":{"codehealthFindingId/v1":"85923b97dc5223f14531ea663281fa3021ec5a57bdfed0cba24b4d9be8382d9e"}},{"ruleId":"D2","level":"warning","message":{"text":"tool_schema_generator.main (cognitive 22): tool_schema_generator.main has cognitive complexity 22 (threshold 15). Drivers by points: if/else 8 (16 pts), loops 3 (4 pts), boolean chains 1, error handling 1 (nesting depth added 9). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/agent-designer/tool_schema_generator.py"},"region":{"startLine":852}}}],"partialFingerprints":{"codehealthFindingId/v1":"ff5b1e37aff67a54f21b669b7ef2d6ceee416900a51fc3d173d4202f8d47347e"}},{"ruleId":"D2","level":"warning","message":{"text":"APIScoringEngine._check_endpoint_documentation (cognitive 22): APIScoringEngine._check_endpoint_documentation has cognitive complexity 22 (threshold 15). Drivers by points: if/else 6 (17 pts), loops 2 (3 pts), boolean chains 1, ternaries 1 (nesting depth added 12). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/api-design-reviewer/scripts/api_scorecard.py"},"region":{"startLine":620}}}],"partialFingerprints":{"codehealthFindingId/v1":"28df87d79cb006a6017f6b1e24d5f9ae9004eb33c4f465b0dc0dc4c75bd462a7"}},{"ruleId":"D2","level":"warning","message":{"text":"APIScoringEngine._check_schema_documentation (cognitive 22): APIScoringEngine._check_schema_documentation has cognitive complexity 22 (threshold 15). Drivers by points: if/else 8 (17 pts), boolean chains 3, loops 1, 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":"engineering/skills/api-design-reviewer/scripts/api_scorecard.py"},"region":{"startLine":651}}}],"partialFingerprints":{"codehealthFindingId/v1":"34a133606fcec209ce14384e1971dcebe7789330ab7621b679db0aafc08de277"}},{"ruleId":"D2","level":"warning","message":{"text":"APIScoringEngine._check_batch_operations (cognitive 22): APIScoringEngine._check_batch_operations has cognitive complexity 22 (threshold 15). Drivers by points: if/else 5 (13 pts), loops 4 (8 pts), boolean chains 1 (nesting depth added 12). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/api-design-reviewer/scripts/api_scorecard.py"},"region":{"startLine":1411}}}],"partialFingerprints":{"codehealthFindingId/v1":"3438752aae86a016b47a74802a8cecf4cad5f5547f9ca9e3de3a21be71926872"}},{"ruleId":"D2","level":"warning","message":{"text":"stack_detector.detect (cognitive 22): stack_detector.detect has cognitive complexity 22 (threshold 15). Drivers by points: if/else 14 (15 pts), boolean chains 5, 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":"engineering/skills/ci-cd-pipeline-builder/scripts/stack_detector.py"},"region":{"startLine":75}}}],"partialFingerprints":{"codehealthFindingId/v1":"3802829ec35666d09ce5357e7950bd6ab29a224210e74e4c9f0db44f4034f81f"}},{"ruleId":"D2","level":"warning","message":{"text":"SchemaAnalyzer._parse_table_definition (cognitive 22): SchemaAnalyzer._parse_table_definition has cognitive complexity 22 (threshold 15). Drivers by points: if/else 8 (21 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":"engineering/skills/database-designer/schema_analyzer.py"},"region":{"startLine":145}}}],"partialFingerprints":{"codehealthFindingId/v1":"d19232d842170064822f125c451ce804031d6402c4dec6036b71dbdb68d8aade"}},{"ruleId":"D2","level":"warning","message":{"text":"LicenseChecker._scan_package_directory (cognitive 22): LicenseChecker._scan_package_directory has cognitive complexity 22 (threshold 15). Drivers by points: if/else 5 (14 pts), error handling 2 (7 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":"engineering/skills/dependency-auditor/scripts/license_checker.py"},"region":{"startLine":561}}}],"partialFingerprints":{"codehealthFindingId/v1":"67236fdfebbb2cca5f48d9428b258640cc20247c848d52d88b3ffd7ecbb528f3"}},{"ruleId":"D2","level":"warning","message":{"text":"LicenseChecker._detect_license_conflicts (cognitive 22): LicenseChecker._detect_license_conflicts has cognitive complexity 22 (threshold 15). Drivers by points: if/else 7 (14 pts), loops 3 (5 pts), boolean chains 3 (nesting depth added 9). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/dependency-auditor/scripts/license_checker.py"},"region":{"startLine":624}}}],"partialFingerprints":{"codehealthFindingId/v1":"b97eba82fdd0a0b8c4abd5284c265e22fcb7293da928e493f9f37699977069a2"}},{"ruleId":"D2","level":"warning","message":{"text":"MigrationPlanner.generate_human_readable_plan (cognitive 22): MigrationPlanner.generate_human_readable_plan has cognitive complexity 22 (threshold 15). Drivers by points: loops 11 (16 pts), if/else 3 (6 pts) (nesting depth added 8). To reduce it, break up the iteration: give each loop body a named function, and split a multi-phase loop into one function per phase so no single body carries the whole pipeline."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/migration-architect/scripts/migration_planner.py"},"region":{"startLine":509}}}],"partialFingerprints":{"codehealthFindingId/v1":"06651ededa53f6336e0b85941a46a29fced39a631709e67f39f5fcb71fd640a9"}},{"ruleId":"D2","level":"warning","message":{"text":"performance_profiler.count_dependencies (cognitive 22): performance_profiler.count_dependencies has cognitive complexity 22 (threshold 15). Drivers by points: if/else 7 (14 pts), boolean chains 4, error handling 1 (2 pts), loops 1 (2 pts) (nesting depth added 9). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/performance-profiler/scripts/performance_profiler.py"},"region":{"startLine":40}}}],"partialFingerprints":{"codehealthFindingId/v1":"0e9c1146246842f56b2bab177e043ab5bc5129c3a068faaf22c6076e38282a23"}},{"ruleId":"D2","level":"warning","message":{"text":"hypothesis_tester._regularized_incomplete_beta (cognitive 22): hypothesis_tester._regularized_incomplete_beta has cognitive complexity 22 (threshold 15). Drivers by points: if/else 9 (17 pts), loops 2 (3 pts), boolean chains 2 (nesting depth added 9). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/statistical-analyst/skills/statistical-analyst/scripts/hypothesis_tester.py"},"region":{"startLine":62}}}],"partialFingerprints":{"codehealthFindingId/v1":"1eed27e1c69083876c6ecdffa045ec54aaff984f7be917f1ecc07f73d920edad"}},{"ruleId":"D2","level":"warning","message":{"text":"verify_data.check_source_tier (cognitive 22): verify_data.check_source_tier has cognitive complexity 22 (threshold 15). Drivers by points: if/else 8 (15 pts), boolean chains 4, ternaries 1 (2 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":"finance/skills/stock-analysis/scripts/verify_data.py"},"region":{"startLine":1285}}}],"partialFingerprints":{"codehealthFindingId/v1":"fc8b6f2a0e082c1cbb0a7f09d1b3b7cc2832f1962abeca0a02f12c9cf58b01ea"}},{"ruleId":"D2","level":"warning","message":{"text":"tracking_plan_generator.generate_tracking_plan (cognitive 22): tracking_plan_generator.generate_tracking_plan has cognitive complexity 22 (threshold 15). Drivers by points: if/else 6 (12 pts), loops 6 (10 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":"marketing-skill/skills/analytics-tracking/scripts/tracking_plan_generator.py"},"region":{"startLine":192}}}],"partialFingerprints":{"codehealthFindingId/v1":"ee09577b88f572ff58ac129dca412edbe8c331113fd24237a87483326c5d5da2"}},{"ruleId":"D2","level":"warning","message":{"text":"form_field_analyzer.format_report (cognitive 22): form_field_analyzer.format_report has cognitive complexity 22 (threshold 15). Drivers by points: loops 5 (12 pts), if/else 3 (6 pts), ternaries 1 (3 pts), boolean chains 1 (nesting depth added 12). To reduce it, break up the iteration: give each loop body a named function, and split a multi-phase loop into one function per phase so no single body carries the whole pipeline."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"marketing-skill/skills/form-cro/scripts/form_field_analyzer.py"},"region":{"startLine":182}}}],"partialFingerprints":{"codehealthFindingId/v1":"27f3d47d1d6a26daa9069606d9aa29c94f8ca68a85d9d83c358359b06dc9a9a1"}},{"ruleId":"D2","level":"warning","message":{"text":"ad_health_scorer.main (cognitive 22): ad_health_scorer.main has cognitive complexity 22 (threshold 15). Drivers by points: if/else 9 (12 pts), loops 4 (10 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":"marketing-skill/skills/paid-ads/scripts/ad_health_scorer.py"},"region":{"startLine":212}}}],"partialFingerprints":{"codehealthFindingId/v1":"8cf96d0a8cad2d8540f40b6efc8220c2762a9ccd6f98f73dc15e4ebb1ff1daef"}},{"ruleId":"D2","level":"warning","message":{"text":"roas_calculator.calculate (cognitive 22): roas_calculator.calculate has cognitive complexity 22 (threshold 15). Drivers by points: if/else 10 (13 pts), boolean chains 6, ternaries 1 (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":"marketing-skill/skills/paid-ads/scripts/roas_calculator.py"},"region":{"startLine":20}}}],"partialFingerprints":{"codehealthFindingId/v1":"1531e88be7ac7701076798299a33f6d773c743aca5d1e4c75abcedfa7ed3c527"}},{"ruleId":"D2","level":"warning","message":{"text":"sitemap_analyzer.parse_sitemap (cognitive 22): sitemap_analyzer.parse_sitemap has cognitive complexity 22 (threshold 15). Drivers by points: boolean chains 9, ternaries 2 (6 pts), if/else 2 (3 pts), 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":"marketing-skill/skills/site-architecture/scripts/sitemap_analyzer.py"},"region":{"startLine":147}}}],"partialFingerprints":{"codehealthFindingId/v1":"4881a1cfc15f016e3ab0ec0e9013f9fefa4913e933023129b85288e0f155c3af"}},{"ruleId":"D2","level":"warning","message":{"text":"positioning_brief.main (cognitive 22): positioning_brief.main has cognitive complexity 22 (threshold 15). Drivers by points: ternaries 3 (6 pts), error handling 2 (5 pts), if/else 4 (5 pts), loops 2 (5 pts), boolean chains 1 (nesting depth added 10). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"marketing/linkedin/skills/linkedin-strategy/scripts/positioning_brief.py"},"region":{"startLine":249}}}],"partialFingerprints":{"codehealthFindingId/v1":"f7ad143f4338656e64b2c862272c338af0a53d52adb1e6b0e10e03a45d6a2e75"}},{"ruleId":"D2","level":"warning","message":{"text":"section_progress_tracker.main (cognitive 22): section_progress_tracker.main has cognitive complexity 22 (threshold 15). Drivers by points: if/else 11 (18 pts), boolean chains 3, error handling 1 (nesting depth added 7). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"productivity/email/skills/inbox-setup/scripts/section_progress_tracker.py"},"region":{"startLine":199}}}],"partialFingerprints":{"codehealthFindingId/v1":"b17f89f389e84cda6fb4723c08098d88c6fed164624f41bce6f50ff721ac00a2"}},{"ruleId":"D2","level":"warning","message":{"text":"delivery_loop_gate.main (cognitive 22): delivery_loop_gate.main has cognitive complexity 22 (threshold 15). Drivers by points: ternaries 5 (9 pts), if/else 6, loops 2 (4 pts), boolean chains 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":"project-management/skills/pm-skills/scripts/delivery_loop_gate.py"},"region":{"startLine":106}}}],"partialFingerprints":{"codehealthFindingId/v1":"38696869f22aff91adc5e6e6f7b2b1a926ae1538bf202f0bc40365cd8ef5a280"}},{"ruleId":"D2","level":"warning","message":{"text":"jira_snapshot_bridge.sprint_export (cognitive 22): jira_snapshot_bridge.sprint_export has cognitive complexity 22 (threshold 15). Drivers by points: ternaries 4 (8 pts), if/else 4 (7 pts), boolean chains 5, 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":"project-management/skills/pm-skills/scripts/jira_snapshot_bridge.py"},"region":{"startLine":186}}}],"partialFingerprints":{"codehealthFindingId/v1":"18e43986e12c30cb80ab0484c621a7b6e7b869194892b1b32a0b97e5badff271"}},{"ruleId":"D2","level":"warning","message":{"text":"retrospective_analyzer.analyze_recurring_themes (cognitive 22): retrospective_analyzer.analyze_recurring_themes has cognitive complexity 22 (threshold 15). Drivers by points: if/else 4 (9 pts), loops 6 (8 pts), ternaries 2 (4 pts), boolean chains 1 (nesting depth added 9). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"project-management/skills/scrum-master/scripts/retrospective_analyzer.py"},"region":{"startLine":306}}}],"partialFingerprints":{"codehealthFindingId/v1":"94ca7ae16402e707c8d0bbe0f208b448ba2e6cba0c804e2eb2bc115d091fca91"}},{"ruleId":"D2","level":"warning","message":{"text":"framework_recommender.recommend (cognitive 22): framework_recommender.recommend has cognitive complexity 22 (threshold 15). Drivers by points: ternaries 5 (10 pts), if/else 5 (8 pts), boolean chains 4 (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":"research/litreview/skills/litreview/scripts/framework_recommender.py"},"region":{"startLine":70}}}],"partialFingerprints":{"codehealthFindingId/v1":"ee67ff350baea2b344c9ba3c63cd0a9c7fda2678883e144218106b8820c9dd2e"}},{"ruleId":"D2","level":"warning","message":{"text":"check_frontmatter.check_file (cognitive 22): check_frontmatter.check_file has cognitive complexity 22 (threshold 15). Drivers by points: if/else 10 (14 pts), boolean chains 5, error handling 1, 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":"scripts/check_frontmatter.py"},"region":{"startLine":109}}}],"partialFingerprints":{"codehealthFindingId/v1":"93041d3e421d2d54c173ebe5bbe9727d46cfda9bfcddf8f47ff1c432bb50da1e"}},{"ruleId":"D2","level":"warning","message":{"text":"poc_planner.format_text (cognitive 21): poc_planner.format_text has cognitive complexity 21 (threshold 15). Drivers by points: loops 11 (14 pts), ternaries 3 (6 pts), if/else 1 (nesting depth added 6). To reduce it, break up the iteration: give each loop body a named function, and split a multi-phase loop into one function per phase so no single body carries the whole pipeline."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"business-growth/skills/sales-engineer/scripts/poc_planner.py"},"region":{"startLine":581}}}],"partialFingerprints":{"codehealthFindingId/v1":"78f45da7e5bd2055ab94a2d31e7bf1cc641a06b36ccb6145b2528680f540e495"}},{"ruleId":"D2","level":"warning","message":{"text":"kb_ingester.walk_vault (cognitive 21): kb_ingester.walk_vault has cognitive complexity 21 (threshold 15). Drivers by points: if/else 4 (11 pts), error handling 2 (4 pts), loops 3 (4 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":"business-operations/skills/knowledge-ops/scripts/kb_ingester.py"},"region":{"startLine":126}}}],"partialFingerprints":{"codehealthFindingId/v1":"3cfab820f3f1aaac7bc90261c9de22da2d862245f7a431caac80604c99dd9166"}},{"ruleId":"D2","level":"warning","message":{"text":"growth_model_simulator.print_channel_mix_impact (cognitive 21): growth_model_simulator.print_channel_mix_impact has cognitive complexity 21 (threshold 15). Drivers by points: ternaries 7 (14 pts), if/else 4 (6 pts), loops 1 (nesting depth added 9). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"c-level-advisor/skills/cmo-advisor/scripts/growth_model_simulator.py"},"region":{"startLine":335}}}],"partialFingerprints":{"codehealthFindingId/v1":"f4467e7ad62fccd828eecdbbe1fcb420ca2f4169b834bc1f855482b6d06275a5"}},{"ruleId":"D2","level":"warning","message":{"text":"okr_tracker.calculate_kr_score (cognitive 21): okr_tracker.calculate_kr_score has cognitive complexity 21 (threshold 15). Drivers by points: if/else 8 (14 pts), ternaries 3 (7 pts) (nesting depth added 10). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"c-level-advisor/skills/coo-advisor/scripts/okr_tracker.py"},"region":{"startLine":51}}}],"partialFingerprints":{"codehealthFindingId/v1":"5f7cf02a49238aaad1236d74d068bf36e6b23ef2aa900b1a3f5a85a08b707a37"}},{"ruleId":"D2","level":"warning","message":{"text":"gws_recipe_runner.run_recipe (cognitive 21): gws_recipe_runner.run_recipe has cognitive complexity 21 (threshold 15). Drivers by points: if/else 7 (11 pts), error handling 3 (6 pts), loops 2 (3 pts), boolean chains 1 (nesting depth added 8). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/google-workspace-cli/skills/google-workspace-cli/scripts/gws_recipe_runner.py"},"region":{"startLine":313}}}],"partialFingerprints":{"codehealthFindingId/v1":"1197391b3a0e758b413d96e8814d9f960ecd1eec0ecbc31ce6772f685faf0d10"}},{"ruleId":"D2","level":"warning","message":{"text":"workspace_audit.main (cognitive 21): workspace_audit.main has cognitive complexity 21 (threshold 15). Drivers by points: if/else 9 (16 pts), boolean chains 3, 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":"engineering-team/google-workspace-cli/skills/google-workspace-cli/scripts/workspace_audit.py"},"region":{"startLine":255}}}],"partialFingerprints":{"codehealthFindingId/v1":"240e2b2d8bc6278c1c481298fc2fc5be7a1aa886b97fd66397f85e813399015c"}},{"ruleId":"D2","level":"warning","message":{"text":"PIRGenerator._identify_category_factors (cognitive 21): PIRGenerator._identify_category_factors has cognitive complexity 21 (threshold 15). Drivers by points: if/else 9 (17 pts), boolean chains 4 (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":"engineering-team/skills/incident-commander/scripts/pir_generator.py"},"region":{"startLine":664}}}],"partialFingerprints":{"codehealthFindingId/v1":"313920ce7ff3fe95ce27b96212c524a3c656572b2fa03770b5064d19971e0dff"}},{"ruleId":"D2","level":"warning","message":{"text":"DatabaseMigrationTool._suggest_indexes (cognitive 21): DatabaseMigrationTool._suggest_indexes has cognitive complexity 21 (threshold 15). Drivers by points: if/else 4 (10 pts), loops 6 (10 pts), boolean chains 1 (nesting depth added 10). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/skills/senior-backend/scripts/database_migration_tool.py"},"region":{"startLine":697}}}],"partialFingerprints":{"codehealthFindingId/v1":"b7e8650eaeef230db3cbf29b1f95f13058d007cb836004f97ab1ce1cbf8eb49f"}},{"ruleId":"D2","level":"warning","message":{"text":"InferenceOptimizer._benchmark_pytorch (cognitive 21): InferenceOptimizer._benchmark_pytorch has cognitive complexity 21 (threshold 15). Drivers by points: if/else 5 (10 pts), loops 3 (5 pts), ternaries 2 (3 pts), error handling 2, boolean chains 1 (nesting depth added 8). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/skills/senior-computer-vision/scripts/inference_optimizer.py"},"region":{"startLine":292}}}],"partialFingerprints":{"codehealthFindingId/v1":"f9139276eb00ca9b3f2b1c1982c8f00e389ce485245bca0a9ac294c78f19b162"}},{"ruleId":"D2","level":"warning","message":{"text":"VisionModelTrainer.analyze_dataset (cognitive 21): VisionModelTrainer.analyze_dataset has cognitive complexity 21 (threshold 15). Drivers by points: if/else 9 (17 pts), loops 2 (4 pts) (nesting depth added 10). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/skills/senior-computer-vision/scripts/vision_model_trainer.py"},"region":{"startLine":75}}}],"partialFingerprints":{"codehealthFindingId/v1":"8df501bb45d871fcad52826aaec5cf2ce204f14622af291623781bd877d4f23b"}},{"ruleId":"D2","level":"warning","message":{"text":"agent_orchestrator.validate_agent (cognitive 21): agent_orchestrator.validate_agent has cognitive complexity 21 (threshold 15). Drivers by points: if/else 11 (19 pts), loops 1, ternaries 1 (nesting depth added 8). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/skills/senior-prompt-engineer/scripts/agent_orchestrator.py"},"region":{"startLine":184}}}],"partialFingerprints":{"codehealthFindingId/v1":"eed0362cdb43648d8a68ea1b896cfa902bdf6a576fa2ac1520fde7cecb76d507"}},{"ruleId":"D2","level":"warning","message":{"text":"FrameworkAdapter.generate_setup_teardown (cognitive 21): FrameworkAdapter.generate_setup_teardown has cognitive complexity 21 (threshold 15). Drivers by points: if/else 9 (17 pts), ternaries 2 (4 pts) (nesting depth added 10). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/skills/tdd-guide/scripts/framework_adapter.py"},"region":{"startLine":319}}}],"partialFingerprints":{"codehealthFindingId/v1":"531f31070fc846c1fabea2a766b18478582d81a5d2c66bfc5d425bba953c9ef1"}},{"ruleId":"D2","level":"warning","message":{"text":"OutputFormatter._format_recommendations_markdown (cognitive 21): OutputFormatter._format_recommendations_markdown has cognitive complexity 21 (threshold 15). Drivers by points: if/else 4 (6 pts), loops 3 (6 pts), ternaries 3 (6 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":"engineering-team/skills/tdd-guide/scripts/output_formatter.py"},"region":{"startLine":137}}}],"partialFingerprints":{"codehealthFindingId/v1":"ce9b30ba773cc93fb60010b09fcf841107d9510267540f9ad26ac108caa3178a"}},{"ruleId":"D2","level":"warning","message":{"text":"init_vault.init_vault (cognitive 21): init_vault.init_vault has cognitive complexity 21 (threshold 15). Drivers by points: if/else 6 (10 pts), error handling 2 (5 pts), loops 4 (5 pts), boolean chains 1 (nesting depth added 8). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/llm-wiki/skills/llm-wiki/scripts/init_vault.py"},"region":{"startLine":84}}}],"partialFingerprints":{"codehealthFindingId/v1":"df55cbd6dd0ce9969372d378afebda0ebf39bbfb59926237ed54030fab86fe80"}},{"ruleId":"D2","level":"warning","message":{"text":"memory_density_auditor.audit (cognitive 21): memory_density_auditor.audit has cognitive complexity 21 (threshold 15). Drivers by points: if/else 11 (15 pts), ternaries 3 (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":"engineering/memory-engineering/skills/memory-engineering/scripts/memory_density_auditor.py"},"region":{"startLine":365}}}],"partialFingerprints":{"codehealthFindingId/v1":"74ce73c17905d03942f0c146536805d60c47073fbf26ae8b84ca5607b9789029"}},{"ruleId":"D2","level":"warning","message":{"text":"ToolSchemaGenerator._generate_example_value (cognitive 21): ToolSchemaGenerator._generate_example_value has cognitive complexity 21 (threshold 15). Drivers by points: if/else 10 (19 pts), boolean chains 2 (nesting depth added 9). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/agent-designer/tool_schema_generator.py"},"region":{"startLine":699}}}],"partialFingerprints":{"codehealthFindingId/v1":"6c823efc9f8654dac600f6abb5004a51aa2ddddb64cd0685d5b31390f6d3915b"}},{"ruleId":"D2","level":"warning","message":{"text":"IndexOptimizer._find_unused_indexes (cognitive 21): IndexOptimizer._find_unused_indexes has cognitive complexity 21 (threshold 15). Drivers by points: if/else 6 (13 pts), loops 5 (8 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":"engineering/skills/database-designer/index_optimizer.py"},"region":{"startLine":663}}}],"partialFingerprints":{"codehealthFindingId/v1":"d3d7df231b19088524f8dfd18576e7bf81bbdb430829a616f27988f5540891d5"}},{"ruleId":"D2","level":"warning","message":{"text":"SchemaCompatibilityChecker.generate_human_readable_report (cognitive 21): SchemaCompatibilityChecker.generate_human_readable_report has cognitive complexity 21 (threshold 15). Drivers by points: loops 7 (12 pts), if/else 4 (9 pts) (nesting depth added 10). To reduce it, break up the iteration: give each loop body a named function, and split a multi-phase loop into one function per phase so no single body carries the whole pipeline."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/migration-architect/scripts/compatibility_checker.py"},"region":{"startLine":744}}}],"partialFingerprints":{"codehealthFindingId/v1":"55173fd2f2cf6dd833c294ff50a7e85a56f4daa99bf1ff2acaa469344d6b95b5"}},{"ruleId":"D2","level":"warning","message":{"text":"AlertOptimizer._analyze_service_coverage (cognitive 21): AlertOptimizer._analyze_service_coverage has cognitive complexity 21 (threshold 15). Drivers by points: if/else 6 (16 pts), loops 2 (3 pts), boolean chains 2 (nesting depth added 11). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/observability-designer/scripts/alert_optimizer.py"},"region":{"startLine":302}}}],"partialFingerprints":{"codehealthFindingId/v1":"898692408500238df5dbe1b5194bbb8c516bc6222b0a7f58c0e3242c6e2ac4f4"}},{"ruleId":"D2","level":"warning","message":{"text":"ScriptTester._test_argparse_implementation (cognitive 21): ScriptTester._test_argparse_implementation has cognitive complexity 21 (threshold 15). Drivers by points: if/else 7 (15 pts), boolean chains 4, error handling 1, loops 1 (nesting depth added 8). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/skill-tester/scripts/script_tester.py"},"region":{"startLine":316}}}],"partialFingerprints":{"codehealthFindingId/v1":"3d832c47073f41994a71329dfbfc71f61583d436cd90866e1635f8abae7c691e"}},{"ruleId":"D2","level":"warning","message":{"text":"deck_html_renderer.main (cognitive 21): deck_html_renderer.main has cognitive complexity 21 (threshold 15). Drivers by points: if/else 10 (13 pts), ternaries 3 (6 pts), boolean chains 2 (nesting depth added 6). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"markdown-html/skills/md-slides/scripts/deck_html_renderer.py"},"region":{"startLine":530}}}],"partialFingerprints":{"codehealthFindingId/v1":"fdfd68f4fbf7d543a1a25d152ad5cacc5e02c70716ae3caa691648998f951729"}},{"ruleId":"D2","level":"warning","message":{"text":"topic_cluster_mapper.build_clusters (cognitive 21): topic_cluster_mapper.build_clusters has cognitive complexity 21 (threshold 15). Drivers by points: if/else 6 (14 pts), loops 4 (6 pts), boolean chains 1 (nesting depth added 10). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"marketing-skill/skills/content-strategy/scripts/topic_cluster_mapper.py"},"region":{"startLine":68}}}],"partialFingerprints":{"codehealthFindingId/v1":"011fb9c608bf584abbfe5528a36ff3254731f07ffe7619045353b03fdca5de39"}},{"ruleId":"D2","level":"warning","message":{"text":"tool_roi_estimator.print_report (cognitive 21): tool_roi_estimator.print_report has cognitive complexity 21 (threshold 15). Drivers by points: if/else 10 (11 pts), ternaries 4 (8 pts), boolean chains 1, loops 1 (nesting depth added 5). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"marketing-skill/skills/free-tool-strategy/scripts/tool_roi_estimator.py"},"region":{"startLine":218}}}],"partialFingerprints":{"codehealthFindingId/v1":"915b2b88e8d20ea733c6389654dc5755198cafc7d623f24df86cd9e648e5e8a6"}},{"ruleId":"D2","level":"warning","message":{"text":"social_calendar_generator.build_calendar (cognitive 21): social_calendar_generator.build_calendar has cognitive complexity 21 (threshold 15). Drivers by points: loops 6 (11 pts), if/else 4 (10 pts) (nesting depth added 11). To reduce it, break up the iteration: give each loop body a named function, and split a multi-phase loop into one function per phase so no single body carries the whole pipeline."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"marketing-skill/skills/social-media-manager/scripts/social_calendar_generator.py"},"region":{"startLine":124}}}],"partialFingerprints":{"codehealthFindingId/v1":"ba74be313953b86a1593b5d35625a167a2f106bfe24a4999ea3db920024a46b7"}},{"ruleId":"D2","level":"warning","message":{"text":"pattern_miner.prepare (cognitive 21): pattern_miner.prepare has cognitive complexity 21 (threshold 15). Drivers by points: ternaries 4 (10 pts), if/else 3 (5 pts), boolean chains 3, error handling 1 (2 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":"marketing/linkedin/skills/linkedin-analytics/scripts/pattern_miner.py"},"region":{"startLine":107}}}],"partialFingerprints":{"codehealthFindingId/v1":"8066ac5942e780a45bab8d29ab33043f1a566c3f1c667f3a5408c1e2c4a4a415"}},{"ruleId":"D2","level":"warning","message":{"text":"outreach_message_builder.validate (cognitive 21): outreach_message_builder.validate has cognitive complexity 21 (threshold 15). Drivers by points: if/else 9 (11 pts), boolean chains 7, ternaries 2 (3 pts) (nesting depth added 3). To reduce it, split the body: most of this score is breadth rather than depth \u2014 checks laid out side by side rather than stacked \u2014 so group the statements between the checks into named steps and move each step into its own function. Some of it IS depth: where a check sits inside another whose only job is to reach it, merge the two into one condition."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"marketing/linkedin/skills/linkedin-engagement/scripts/outreach_message_builder.py"},"region":{"startLine":92}}}],"partialFingerprints":{"codehealthFindingId/v1":"1b214973e213a3c4eadbd7678f1c5f2ebb4c27b8d3fca931481cd74c325b9311"}},{"ruleId":"D2","level":"warning","message":{"text":"codebase_analyzer.extract_apis_from_file (cognitive 21): codebase_analyzer.extract_apis_from_file has cognitive complexity 21 (threshold 15). Drivers by points: if/else 2 (8 pts), loops 3 (7 pts), ternaries 1 (3 pts), boolean chains 2, error handling 1 (nesting depth added 12). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"product-team/code-to-prd/skills/code-to-prd/scripts/codebase_analyzer.py"},"region":{"startLine":294}}}],"partialFingerprints":{"codehealthFindingId/v1":"cd39ae38f078c226fa7045adf51d7c36698531c4700e97acc869e2494180922b"}},{"ruleId":"D2","level":"warning","message":{"text":"workspace_inventory.main (cognitive 21): workspace_inventory.main has cognitive complexity 21 (threshold 15). Drivers by points: if/else 10 (15 pts), ternaries 2 (5 pts), boolean chains 1 (nesting depth added 8). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"productivity/capture/skills/capture/scripts/workspace_inventory.py"},"region":{"startLine":178}}}],"partialFingerprints":{"codehealthFindingId/v1":"0432f1e7f12cc5f738557637ce2591f772f16c16056a82cc4a9d67a4faf86842"}},{"ruleId":"D2","level":"warning","message":{"text":"delivery_loop_gate.check_plan (cognitive 21): delivery_loop_gate.check_plan has cognitive complexity 21 (threshold 15). Drivers by points: if/else 7 (13 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":"project-management/skills/pm-skills/scripts/delivery_loop_gate.py"},"region":{"startLine":57}}}],"partialFingerprints":{"codehealthFindingId/v1":"04bb0dd86df012c79a864445e758e6badcfdc7f2f73502eab662ac51580297ca"}},{"ruleId":"D2","level":"warning","message":{"text":"retrospective_analyzer.analyze_improvement_trends (cognitive 21): retrospective_analyzer.analyze_improvement_trends has cognitive complexity 21 (threshold 15). Drivers by points: if/else 6 (13 pts), ternaries 2 (5 pts), loops 2, boolean chains 1 (nesting depth added 10). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"project-management/skills/scrum-master/scripts/retrospective_analyzer.py"},"region":{"startLine":371}}}],"partialFingerprints":{"codehealthFindingId/v1":"1d5b752354551eead4f81270f802c8c1e3281dd5ee5ce99bbed877082ccc5a9e"}},{"ruleId":"D2","level":"warning","message":{"text":"hipaa_risk_assessment.scan_documentation (cognitive 21): hipaa_risk_assessment.scan_documentation has cognitive complexity 21 (threshold 15). Drivers by points: loops 4 (10 pts), if/else 2 (7 pts), error handling 1 (4 pts) (nesting depth added 14). To reduce it, break up the iteration: give each loop body a named function, and split a multi-phase loop into one function per phase so no single body carries the whole pipeline."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"ra-qm-team/skills/fda-consultant-specialist/scripts/hipaa_risk_assessment.py"},"region":{"startLine":224}}}],"partialFingerprints":{"codehealthFindingId/v1":"a9c23765653b46857636880c00a1529020cf22381caf0423eaba919b25cbfac4"}},{"ruleId":"D2","level":"warning","message":{"text":"hipaa_risk_assessment.generate_recommendations (cognitive 21): hipaa_risk_assessment.generate_recommendations has cognitive complexity 21 (threshold 15). Drivers by points: if/else 4 (12 pts), loops 5 (9 pts) (nesting depth added 12). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"ra-qm-team/skills/fda-consultant-specialist/scripts/hipaa_risk_assessment.py"},"region":{"startLine":453}}}],"partialFingerprints":{"codehealthFindingId/v1":"2eee82502df6a83ea822e116606b3a1764fc52487d5a20016284cc0e9fca9048"}},{"ruleId":"D2","level":"warning","message":{"text":"document_version_control.main (cognitive 21): document_version_control.main has cognitive complexity 21 (threshold 15). Drivers by points: if/else 5 (7 pts), boolean chains 5, loops 2 (5 pts), ternaries 2 (4 pts) (nesting depth added 7). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"ra-qm-team/skills/quality-documentation-manager/scripts/document_version_control.py"},"region":{"startLine":375}}}],"partialFingerprints":{"codehealthFindingId/v1":"ee88d4ee445313d125af3cccbd9ec9a894c8130c83da763aac01c010180993fe"}},{"ruleId":"D2","level":"warning","message":{"text":"QMSEffectivenessMonitor.predict_failures (cognitive 21): QMSEffectivenessMonitor.predict_failures has cognitive complexity 21 (threshold 15). Drivers by points: if/else 4 (9 pts), ternaries 2 (6 pts), boolean chains 4, loops 2 (nesting depth added 9). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"ra-qm-team/skills/quality-manager-qmr/scripts/quality_effectiveness_monitor.py"},"region":{"startLine":196}}}],"partialFingerprints":{"codehealthFindingId/v1":"e2b13da336c8b1ee9a411d55eb0d56aa39a11777df45ae83d39b456f56abc9ac"}},{"ruleId":"D2","level":"warning","message":{"text":"qms_audit_checklist.main (cognitive 21): qms_audit_checklist.main has cognitive complexity 21 (threshold 15). Drivers by points: if/else 12 (15 pts), loops 2 (6 pts) (nesting depth added 7). To reduce it, split the body: most of this score is breadth rather than depth \u2014 checks laid out side by side rather than stacked \u2014 so group the statements between the checks into named steps and move each step into its own function. Some of it IS depth: where a check sits inside another whose only job is to reach it, merge the two into one condition, 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":"ra-qm-team/skills/quality-manager-qms-iso13485/scripts/qms_audit_checklist.py"},"region":{"startLine":785}}}],"partialFingerprints":{"codehealthFindingId/v1":"e39c2b78d50bc5cec095c648e437358ac8bf91c9880a1a17212a59e2d253d60c"}},{"ruleId":"D2","level":"warning","message":{"text":"phase_gate_scorer.score_plan (cognitive 21): phase_gate_scorer.score_plan has cognitive complexity 21 (threshold 15). Drivers by points: ternaries 8 (10 pts), if/else 6 (7 pts), boolean chains 4 (nesting depth added 3). To reduce it, split the body: most of this score is breadth rather than depth \u2014 checks laid out side by side rather than stacked \u2014 so group the statements between the checks into named steps and move each step into its own function. Some of it IS depth: where a check sits inside another whose only job is to reach it, merge the two into one condition, and where an else follows a branch that already returns, drop the trailing else and let the rest of the body continue at one level."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"research-ops/skills/clinical-research/scripts/phase_gate_scorer.py"},"region":{"startLine":88}}}],"partialFingerprints":{"codehealthFindingId/v1":"1877525118cb069ce81fc66ea4ed24f65bdaa793e640eaedaa16271e6bd603c8"}},{"ruleId":"D2","level":"warning","message":{"text":"classifier.classify (cognitive 21): classifier.classify has cognitive complexity 21 (threshold 15). Drivers by points: if/else 10 (16 pts), ternaries 2 (3 pts), boolean chains 1, loops 1 (nesting depth added 7). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"research/research/skills/research/scripts/classifier.py"},"region":{"startLine":66}}}],"partialFingerprints":{"codehealthFindingId/v1":"d4b36a2383d797b49b724a12d537beff51b24dde8c170d248f0d6b0b69a9aa35"}},{"ruleId":"D2","level":"warning","message":{"text":"sync-vibe-skills.main (cognitive 21): sync-vibe-skills.main has cognitive complexity 21 (threshold 15). Drivers by points: if/else 11 (12 pts), ternaries 7 (8 pts), 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, and where an else follows a branch that already returns, drop the trailing else and let the rest of the body continue at one level."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"scripts/sync-vibe-skills.py"},"region":{"startLine":246}}}],"partialFingerprints":{"codehealthFindingId/v1":"b30d59758cb8f854f6ae749c5e3dff14a83a4e488c6d05a1ab5e625ccb5972e6"}},{"ruleId":"D2","level":"warning","message":{"text":"full-page-screenshot.waitForLoad (cognitive 21): full-page-screenshot.waitForLoad has cognitive complexity 21 (threshold 15). Drivers by points: if/else 5 (11 pts), error handling 2 (5 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":"engineering/skills/full-page-screenshot/scripts/full-page-screenshot.mjs"},"region":{"startLine":168}}}],"partialFingerprints":{"codehealthFindingId/v1":"dd0e0ce872cca1b866a7c5a21005a8d8416b2bb0e61afbddefc562d437bc862d"}},{"ruleId":"D2","level":"warning","message":{"text":"interview_planner.plan (cognitive 20): interview_planner.plan has cognitive complexity 20 (threshold 15). Drivers by points: if/else 7 (11 pts), ternaries 4, boolean chains 3, 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":"agent-launcher/skills/interview/scripts/interview_planner.py"},"region":{"startLine":38}}}],"partialFingerprints":{"codehealthFindingId/v1":"5597b7cafd7ef11a2f95b4f3d4a433ae45baa5f50477a9f4e1037cd368dd11f3"}},{"ruleId":"D2","level":"warning","message":{"text":"ai_risk_classifier.render_text (cognitive 20): ai_risk_classifier.render_text has cognitive complexity 20 (threshold 15). Drivers by points: loops 7 (14 pts), if/else 5, ternaries 1 (nesting depth added 7). To reduce it, break up the iteration: give each loop body a named function, and split a multi-phase loop into one function per phase so no single body carries the whole pipeline."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"c-level-advisor/chief-ai-officer-advisor/skills/chief-ai-officer-advisor/scripts/ai_risk_classifier.py"},"region":{"startLine":358}}}],"partialFingerprints":{"codehealthFindingId/v1":"9803a3015491afac1ffa50afcb40fabe8a917a23e16d0f40bb6b0207915cd4f9"}},{"ruleId":"D2","level":"warning","message":{"text":"unit_economics_analyzer.print_cohort_analysis (cognitive 20): unit_economics_analyzer.print_cohort_analysis has cognitive complexity 20 (threshold 15). Drivers by points: ternaries 6 (13 pts), if/else 4 (6 pts), loops 1 (nesting depth added 9). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"c-level-advisor/skills/cfo-advisor/scripts/unit_economics_analyzer.py"},"region":{"startLine":253}}}],"partialFingerprints":{"codehealthFindingId/v1":"36a1851d66399e58a41c3495a301a1b11aa01375e479a72d9e1ea6c6fc43b4c4"}},{"ruleId":"D2","level":"warning","message":{"text":"ai_risk_classifier.render_text (cognitive 20): ai_risk_classifier.render_text has cognitive complexity 20 (threshold 15). Drivers by points: loops 7 (14 pts), if/else 5, ternaries 1 (nesting depth added 7). To reduce it, break up the iteration: give each loop body a named function, and split a multi-phase loop into one function per phase so no single body carries the whole pipeline."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"c-level-advisor/skills/chief-ai-officer-advisor/scripts/ai_risk_classifier.py"},"region":{"startLine":358}}}],"partialFingerprints":{"codehealthFindingId/v1":"ffd9eaaa3fe27d56cfeb4f075fc98b0aeb0bba5972233393d563cdf092822178"}},{"ruleId":"D2","level":"warning","message":{"text":"pmf_scorer.score_engagement (cognitive 20): pmf_scorer.score_engagement has cognitive complexity 20 (threshold 15). Drivers by points: if/else 16 (20 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, 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":"c-level-advisor/skills/cpo-advisor/scripts/pmf_scorer.py"},"region":{"startLine":215}}}],"partialFingerprints":{"codehealthFindingId/v1":"a8755c10a3cce5ce4afcab5133dde2fd5aecfdb447bf60b20a8ad97c17e14556"}},{"ruleId":"D2","level":"warning","message":{"text":"output_analyzer.read_input (cognitive 20): output_analyzer.read_input has cognitive complexity 20 (threshold 15). Drivers by points: if/else 8 (12 pts), error handling 2 (4 pts), loops 2 (3 pts), boolean chains 1 (nesting depth added 7). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/google-workspace-cli/skills/google-workspace-cli/scripts/output_analyzer.py"},"region":{"startLine":52}}}],"partialFingerprints":{"codehealthFindingId/v1":"1d72e679476a8f3da5e46d6fa3e44902ab6b88467883eca3f76eed0b8cf74396"}},{"ruleId":"D2","level":"warning","message":{"text":"TimelineReconstructor._calculate_metrics (cognitive 20): TimelineReconstructor._calculate_metrics has cognitive complexity 20 (threshold 15). Drivers by points: if/else 6 (8 pts), ternaries 5, boolean chains 4, loops 3 (nesting depth added 2). To reduce it, split the body: most of this score is breadth rather than depth \u2014 checks laid out side by side rather than stacked \u2014 so group the statements between the checks into named steps and move each step into its own function. Some of it IS depth: where a check sits inside another whose only job is to reach it, merge the two into one condition."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/skills/incident-commander/scripts/timeline_reconstructor.py"},"region":{"startLine":423}}}],"partialFingerprints":{"codehealthFindingId/v1":"439e0fbcf5c80ef6f171025c1283ef6d1135944a06b39c77b6c5052f10ba96a5"}},{"ruleId":"D2","level":"warning","message":{"text":"TimelineReconstructor._analyze_gaps (cognitive 20): TimelineReconstructor._analyze_gaps has cognitive complexity 20 (threshold 15). Drivers by points: if/else 7 (10 pts), ternaries 2 (6 pts), loops 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":"engineering-team/skills/incident-commander/scripts/timeline_reconstructor.py"},"region":{"startLine":492}}}],"partialFingerprints":{"codehealthFindingId/v1":"13a91ecf57a9d8121c45c16b24e7b151a0fd09a12c6c5f70975d4f790810ad5f"}},{"ruleId":"D2","level":"warning","message":{"text":"AnomalyDetector._detect_numeric_anomalies (cognitive 20): AnomalyDetector._detect_numeric_anomalies has cognitive complexity 20 (threshold 15). Drivers by points: if/else 7 (11 pts), error handling 1 (3 pts), loops 2 (3 pts), boolean chains 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":"engineering-team/skills/senior-data-engineer/scripts/data_quality_validator.py"},"region":{"startLine":532}}}],"partialFingerprints":{"codehealthFindingId/v1":"1cee79c23303360b681f1055b390f454b894bc2c648861d792aadf9c1da4aff3"}},{"ruleId":"D2","level":"warning","message":{"text":"bundle_analyzer.analyze_dependencies (cognitive 20): bundle_analyzer.analyze_dependencies has cognitive complexity 20 (threshold 15). Drivers by points: if/else 6 (11 pts), loops 5 (7 pts), boolean chains 2 (nesting depth added 7). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/skills/senior-frontend/scripts/bundle_analyzer.py"},"region":{"startLine":114}}}],"partialFingerprints":{"codehealthFindingId/v1":"0c779ef478e99e113f77d23bef1878b162f42702f3640cb42f56ea500c8d938f"}},{"ruleId":"D2","level":"warning","message":{"text":"code_quality_analyzer.analyze_dependencies (cognitive 20): code_quality_analyzer.analyze_dependencies has cognitive complexity 20 (threshold 15). Drivers by points: if/else 6 (12 pts), error handling 2 (4 pts), boolean chains 2, loops 1 (2 pts) (nesting depth added 9). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/skills/senior-fullstack/scripts/code_quality_analyzer.py"},"region":{"startLine":197}}}],"partialFingerprints":{"codehealthFindingId/v1":"8d3bef361367b330ff8b809cd9e6da386c2f5d4c8018cef343044dc5d75ef34b"}},{"ruleId":"D2","level":"warning","message":{"text":"agent_orchestrator.main (cognitive 20): agent_orchestrator.main has cognitive complexity 20 (threshold 15). Drivers by points: if/else 14 (19 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":"engineering-team/skills/senior-prompt-engineer/scripts/agent_orchestrator.py"},"region":{"startLine":462}}}],"partialFingerprints":{"codehealthFindingId/v1":"60c50c223d3dcc006e00e7b6c30ad904a04a2253159cc4ee6dfe763e38867891"}},{"ruleId":"D2","level":"warning","message":{"text":"ReportGenerator.generate_text_report (cognitive 20): ReportGenerator.generate_text_report has cognitive complexity 20 (threshold 15). Drivers by points: if/else 6 (9 pts), loops 4 (7 pts), ternaries 2 (4 pts) (nesting depth added 8). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/skills/senior-qa/scripts/coverage_analyzer.py"},"region":{"startLine":454}}}],"partialFingerprints":{"codehealthFindingId/v1":"de5e17368e854f2adc33e6d89f7828aa439772ead2074ac310c52a6eca2854a4"}},{"ruleId":"D2","level":"warning","message":{"text":"secret_scanner.scan_file (cognitive 20): secret_scanner.scan_file has cognitive complexity 20 (threshold 15). Drivers by points: if/else 5 (13 pts), error handling 2 (3 pts), loops 2 (3 pts), boolean chains 1 (nesting depth added 10). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/skills/senior-security/scripts/secret_scanner.py"},"region":{"startLine":249}}}],"partialFingerprints":{"codehealthFindingId/v1":"f07dd01003357522320b08aef6af7d67a5357471be206766186156cb60559252"}},{"ruleId":"D2","level":"warning","message":{"text":"log_results.export_dashboard_csv (cognitive 20): log_results.export_dashboard_csv has cognitive complexity 20 (threshold 15). Drivers by points: if/else 3 (7 pts), ternaries 2 (6 pts), loops 3 (4 pts), boolean chains 3 (nesting depth added 9). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/autoresearch-agent/skills/autoresearch-agent/scripts/log_results.py"},"region":{"startLine":219}}}],"partialFingerprints":{"codehealthFindingId/v1":"9e1716dca763faaee1dba9952217c81dfc5cfa38405453f3fe200a9254924495"}},{"ruleId":"D2","level":"warning","message":{"text":"book_skill_validator._collect_skill_files (cognitive 20): book_skill_validator._collect_skill_files has cognitive complexity 20 (threshold 15). Drivers by points: if/else 10 (15 pts), boolean chains 3, error handling 1, loops 1 (nesting depth added 5). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/book-to-skill/skills/book-to-skill/scripts/book_skill_validator.py"},"region":{"startLine":166}}}],"partialFingerprints":{"codehealthFindingId/v1":"2ff5e9ff9266aa3dab22c2949bbc3c691a3ff513eb9fcf4879ba06ec2eeb8a5a"}},{"ruleId":"D2","level":"warning","message":{"text":"skill_plugin_emitter.emit (cognitive 20): skill_plugin_emitter.emit has cognitive complexity 20 (threshold 15). Drivers by points: if/else 13 (15 pts), boolean chains 2, error handling 1 (2 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."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/book-to-skill/skills/book-to-skill/scripts/skill_plugin_emitter.py"},"region":{"startLine":375}}}],"partialFingerprints":{"codehealthFindingId/v1":"a57f46aea3033ff21c023248ade29e3c4afe183de8a454b00bcd3db05f63ea40"}},{"ruleId":"D2","level":"warning","message":{"text":"cheat_code_filter.parse_glossary (cognitive 20): cheat_code_filter.parse_glossary has cognitive complexity 20 (threshold 15). Drivers by points: if/else 9 (18 pts), boolean chains 1, loops 1 (nesting depth added 9). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/claude-coach/skills/claude-coach/scripts/cheat_code_filter.py"},"region":{"startLine":49}}}],"partialFingerprints":{"codehealthFindingId/v1":"eb5cabe3dea621e87b24696c6f9dec633b99d95619c0be9961fa8f570359093d"}},{"ruleId":"D2","level":"warning","message":{"text":"glossary_code_consistency.main (cognitive 20): glossary_code_consistency.main has cognitive complexity 20 (threshold 15). Drivers by points: if/else 8 (11 pts), error handling 1 (3 pts), ternaries 1 (3 pts), loops 1 (2 pts), boolean chains 1 (nesting depth added 8). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/grill-with-docs/skills/grill-with-docs/scripts/glossary_code_consistency.py"},"region":{"startLine":248}}}],"partialFingerprints":{"codehealthFindingId/v1":"51c6004c55036ab2bcca81086e2a2ec829b2772c1d4c2f05f822aaea8f0f20bf"}},{"ruleId":"D2","level":"warning","message":{"text":"chart_analyzer.analyze_chart (cognitive 20): chart_analyzer.analyze_chart has cognitive complexity 20 (threshold 15). Drivers by points: if/else 12 (16 pts), loops 2, boolean chains 1, ternaries 1 (nesting depth added 4). To reduce it, split the body: most of this score is breadth rather than depth \u2014 checks laid out side by side rather than stacked \u2014 so group the statements between the checks into named steps and move each step into its own function. Some of it IS depth: where a check sits inside another whose only job is to reach it, merge the two into one condition, and where an else follows a branch that already returns, drop the trailing else and let the rest of the body continue at one level."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/helm-chart-builder/skills/helm-chart-builder/scripts/chart_analyzer.py"},"region":{"startLine":400}}}],"partialFingerprints":{"codehealthFindingId/v1":"ce68e9a253bf966d768ee039891b65111839e50cbba73c9bc487d047a6fcd5d5"}},{"ruleId":"D2","level":"warning","message":{"text":"review_page_builder.sanitize_attrs (cognitive 20): review_page_builder.sanitize_attrs 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":"engineering/human-gate/skills/human-gate/scripts/review_page_builder.py"},"region":{"startLine":292}}}],"partialFingerprints":{"codehealthFindingId/v1":"46bd97e8ee0b9f7745e321cd31574dcd1d5b06ddf5b4bb3d6834d335874b121a"}},{"ruleId":"D2","level":"warning","message":{"text":"complexity_checker.main (cognitive 20): complexity_checker.main has cognitive complexity 20 (threshold 15). Drivers by points: if/else 7 (10 pts), ternaries 4 (6 pts), 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":"engineering/karpathy-coder/skills/karpathy-coder/scripts/complexity_checker.py"},"region":{"startLine":245}}}],"partialFingerprints":{"codehealthFindingId/v1":"c37d34ce52de545d8d002e78aeb8e884fc4079bb7726c7501b53e26811eba713"}},{"ruleId":"D2","level":"warning","message":{"text":"AgentPlanner.select_architecture_pattern (cognitive 20): AgentPlanner.select_architecture_pattern has cognitive complexity 20 (threshold 15). Drivers by points: if/else 5 (10 pts), boolean chains 9, 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":"engineering/skills/agent-designer/agent_planner.py"},"region":{"startLine":207}}}],"partialFingerprints":{"codehealthFindingId/v1":"f561cdf0649962a1ec0862c91f6e047712eab8e20ecd74b29a50ddadb07f9900"}},{"ruleId":"D2","level":"warning","message":{"text":"APIScoringEngine._check_response_documentation (cognitive 20): APIScoringEngine._check_response_documentation has cognitive complexity 20 (threshold 15). Drivers by points: if/else 4 (13 pts), loops 3 (6 pts), ternaries 1 (nesting depth added 12). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/api-design-reviewer/scripts/api_scorecard.py"},"region":{"startLine":724}}}],"partialFingerprints":{"codehealthFindingId/v1":"d644d021a4fb621c8c3519e4fffaaa1ce35c0d33fa96c0eda8f3d926d8d2b5b2"}},{"ruleId":"D2","level":"warning","message":{"text":"APIScoringEngine._check_authentication_patterns (cognitive 20): APIScoringEngine._check_authentication_patterns has cognitive complexity 20 (threshold 15). Drivers by points: if/else 10 (18 pts), loops 1, ternaries 1 (nesting depth added 8). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/api-design-reviewer/scripts/api_scorecard.py"},"region":{"startLine":927}}}],"partialFingerprints":{"codehealthFindingId/v1":"785ecb3b24f9130a45f70a3ee3ad74b5c88a23b4fd02f400f4705db08ef2ea0d"}},{"ruleId":"D2","level":"warning","message":{"text":"pipeline_generator.gitlab_yaml (cognitive 20): pipeline_generator.gitlab_yaml has cognitive complexity 20 (threshold 15). Drivers by points: loops 5 (11 pts), if/else 4, boolean chains 3, ternaries 1 (2 pts) (nesting depth added 7). To reduce it, break up the iteration: give each loop body a named function, and split a multi-phase loop into one function per phase so no single body carries the whole pipeline."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/ci-cd-pipeline-builder/scripts/pipeline_generator.py"},"region":{"startLine":189}}}],"partialFingerprints":{"codehealthFindingId/v1":"dbfa03e5f95544ee39be1e88e955e207e63a5c1e9d75d48008b5c9a144bc22dc"}},{"ruleId":"D2","level":"warning","message":{"text":"SelectivityEstimator.estimate_selectivity (cognitive 20): SelectivityEstimator.estimate_selectivity has cognitive complexity 20 (threshold 15). Drivers by points: if/else 9 (14 pts), loops 4, boolean chains 2 (nesting depth added 5). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/database-designer/index_optimizer.py"},"region":{"startLine":113}}}],"partialFingerprints":{"codehealthFindingId/v1":"fe4103c32dda56264e4152347d13fd36aaa2ef1f043000c84464d18a0136e29e"}},{"ruleId":"D2","level":"warning","message":{"text":"DependencyScanner.scan_project (cognitive 20): DependencyScanner.scan_project has cognitive complexity 20 (threshold 15). Drivers by points: loops 4 (10 pts), if/else 3 (7 pts), error handling 1 (3 pts) (nesting depth added 12). To reduce it, break up the iteration: give each loop body a named function, and split a multi-phase loop into one function per phase so no single body carries the whole pipeline."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/dependency-auditor/scripts/dep_scanner.py"},"region":{"startLine":196}}}],"partialFingerprints":{"codehealthFindingId/v1":"babd808c3c35fa90d8d4e465d076ae0ff4248b25fadba5246ae52bfc81d4cf48"}},{"ruleId":"D2","level":"warning","message":{"text":"tc_validator.validate_registry (cognitive 20): tc_validator.validate_registry has cognitive complexity 20 (threshold 15). Drivers by points: if/else 8 (17 pts), loops 1 (2 pts), boolean chains 1 (nesting depth added 10). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/tc-tracker/scripts/tc_validator.py"},"region":{"startLine":251}}}],"partialFingerprints":{"codehealthFindingId/v1":"9511c949de585539da1439a48f13f4f609195df7bbf425351b5f0947d355ae98"}},{"ruleId":"D2","level":"warning","message":{"text":"hypothesis_tester._regularized_gamma (cognitive 20): hypothesis_tester._regularized_gamma has cognitive complexity 20 (threshold 15). Drivers by points: if/else 8 (16 pts), loops 2 (4 pts) (nesting depth added 10). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/statistical-analyst/skills/statistical-analyst/scripts/hypothesis_tester.py"},"region":{"startLine":291}}}],"partialFingerprints":{"codehealthFindingId/v1":"3dc4b0f7e3aafd093fc76d1c9dba96aa0857062bac61eecdc49efe9c4798ddd4"}},{"ruleId":"D2","level":"warning","message":{"text":"tf_security_scanner.check_encryption (cognitive 20): tf_security_scanner.check_encryption has cognitive complexity 20 (threshold 15). Drivers by points: if/else 6 (13 pts), loops 3 (4 pts), boolean chains 3 (nesting depth added 8). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/terraform-patterns/skills/terraform-patterns/scripts/tf_security_scanner.py"},"region":{"startLine":340}}}],"partialFingerprints":{"codehealthFindingId/v1":"1c3ce5dbf2f2105c4065bf1db28505f4d7586a8ef80f1d345068bf7d45cc3a7d"}},{"ruleId":"D2","level":"warning","message":{"text":"verify_data.check_basis_mixing (cognitive 20): verify_data.check_basis_mixing has cognitive complexity 20 (threshold 15). Drivers by points: if/else 7 (11 pts), ternaries 2 (5 pts), boolean chains 3, loops 1 (nesting depth added 7). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"finance/skills/stock-analysis/scripts/verify_data.py"},"region":{"startLine":919}}}],"partialFingerprints":{"codehealthFindingId/v1":"05a626367a81ebb3cd4aca8aa36d9468377d36700be546a96f0d854f198af26b"}},{"ruleId":"D2","level":"warning","message":{"text":"verify_data.check_recency (cognitive 20): verify_data.check_recency has cognitive complexity 20 (threshold 15). Drivers by points: if/else 8 (11 pts), ternaries 3 (5 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":"finance/skills/stock-analysis/scripts/verify_data.py"},"region":{"startLine":1173}}}],"partialFingerprints":{"codehealthFindingId/v1":"d1a62e5f0232bb7ba0544a442ef7d307d2c0ad8e3d5bca5afc12642d25f4bd53"}},{"ruleId":"D2","level":"warning","message":{"text":"extract_citations.run_extraction (cognitive 20): extract_citations.run_extraction has cognitive complexity 20 (threshold 15). Drivers by points: if/else 6 (11 pts), loops 4 (9 pts) (nesting depth added 10). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"product-team/research-summarizer/skills/research-summarizer/scripts/extract_citations.py"},"region":{"startLine":219}}}],"partialFingerprints":{"codehealthFindingId/v1":"785ef1d396cd19c602c49c51c098941c1b017b47966d87f03e0c09ef201488ea"}},{"ruleId":"D2","level":"warning","message":{"text":"competitive_matrix_builder.format_text (cognitive 20): competitive_matrix_builder.format_text has cognitive complexity 20 (threshold 15). Drivers by points: loops 5 (10 pts), if/else 5 (8 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":"product-team/skills/competitive-teardown/scripts/competitive_matrix_builder.py"},"region":{"startLine":152}}}],"partialFingerprints":{"codehealthFindingId/v1":"89602ad0c2d7c06cd4f2446c2a8a588a1d008fbeed158bb3745371d103c7fb9c"}},{"ruleId":"D2","level":"warning","message":{"text":"handoff_template_generator._find_latest_handoff (cognitive 20): handoff_template_generator._find_latest_handoff has cognitive complexity 20 (threshold 15). Drivers by points: if/else 3 (9 pts), error handling 2 (5 pts), loops 2 (3 pts), boolean chains 2, ternaries 1 (nesting depth added 10). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"productivity/handoff/skills/handoff/scripts/handoff_template_generator.py"},"region":{"startLine":83}}}],"partialFingerprints":{"codehealthFindingId/v1":"1f8975108e7a8b5e3dd8cbb25417dcfcf507d2b724765f73b1505110b8665e15"}},{"ruleId":"D2","level":"warning","message":{"text":"action_item_extractor.render_markdown (cognitive 20): action_item_extractor.render_markdown has cognitive complexity 20 (threshold 15). Drivers by points: if/else 6 (8 pts), ternaries 2 (7 pts), loops 3 (5 pts) (nesting depth added 9). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"productivity/meetings/skills/meetings/scripts/action_item_extractor.py"},"region":{"startLine":160}}}],"partialFingerprints":{"codehealthFindingId/v1":"b2706f2e94443cf9fdd171024b32589c39ad6e4fe4c55d086d864a9ba871dd6b"}},{"ruleId":"D2","level":"warning","message":{"text":"permission_audit_tool.check_compliance_gaps (cognitive 20): permission_audit_tool.check_compliance_gaps has cognitive complexity 20 (threshold 15). Drivers by points: if/else 5 (13 pts), loops 3 (5 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":"project-management/skills/atlassian-admin/scripts/permission_audit_tool.py"},"region":{"startLine":222}}}],"partialFingerprints":{"codehealthFindingId/v1":"951b25267447890c7d9747d95390e85be0513af363f7a94aa9b085cd3a734ff5"}},{"ruleId":"D2","level":"warning","message":{"text":"jira_snapshot_bridge.normalize (cognitive 20): jira_snapshot_bridge.normalize has cognitive complexity 20 (threshold 15). Drivers by points: if/else 5 (8 pts), boolean chains 5, ternaries 2 (4 pts), loops 2 (3 pts) (nesting depth added 6). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"project-management/skills/pm-skills/scripts/jira_snapshot_bridge.py"},"region":{"startLine":75}}}],"partialFingerprints":{"codehealthFindingId/v1":"69b393e20c220722170663307f0adabb4a1aab2f85b7464c69ae5cc51db78cd5"}},{"ruleId":"D2","level":"warning","message":{"text":"resource_capacity_planner.analyze_project_capacity_requirements (cognitive 20): resource_capacity_planner.analyze_project_capacity_requirements has cognitive complexity 20 (threshold 15). Drivers by points: if/else 8 (14 pts), loops 3 (5 pts), boolean chains 1 (nesting depth added 8). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"project-management/skills/senior-pm/scripts/resource_capacity_planner.py"},"region":{"startLine":313}}}],"partialFingerprints":{"codehealthFindingId/v1":"89fa433bec4365072cb63a8546c961ae32b031216c9c61857348b49ff9d0c98e"}},{"ruleId":"D2","level":"warning","message":{"text":"RootCauseAnalyzer.full_analysis (cognitive 20): RootCauseAnalyzer.full_analysis has cognitive complexity 20 (threshold 15). Drivers by points: if/else 6 (11 pts), ternaries 1 (4 pts), boolean chains 3, loops 1 (2 pts) (nesting depth added 9). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"ra-qm-team/skills/capa-officer/scripts/root_cause_analyzer.py"},"region":{"startLine":305}}}],"partialFingerprints":{"codehealthFindingId/v1":"4e0c60cdd7e95db5cfa0637432f6aa17b292f062739a0f6ae70c241671fa682f"}},{"ruleId":"D2","level":"warning","message":{"text":"fda_submission_tracker.calculate_submission_readiness (cognitive 20): fda_submission_tracker.calculate_submission_readiness has cognitive complexity 20 (threshold 15). Drivers by points: if/else 5 (12 pts), loops 3 (6 pts), boolean chains 1, ternaries 1 (nesting depth added 10). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"ra-qm-team/skills/fda-consultant-specialist/scripts/fda_submission_tracker.py"},"region":{"startLine":201}}}],"partialFingerprints":{"codehealthFindingId/v1":"0d58652ac296701a0ad6ada956b13dca825fe93f73ab9d01ed88c20bf13e141e"}},{"ruleId":"D2","level":"warning","message":{"text":"citation_tracker.main (cognitive 20): citation_tracker.main has cognitive complexity 20 (threshold 15). Drivers by points: if/else 10 (16 pts), boolean chains 3, 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":"research/litreview/skills/litreview/scripts/citation_tracker.py"},"region":{"startLine":200}}}],"partialFingerprints":{"codehealthFindingId/v1":"b5ec333468fd2116f2c3bfd3188cd4e43846a9ac6ca01f2976e6b168868e0511"}},{"ruleId":"D2","level":"warning","message":{"text":"discussion_question_validator.classify_question (cognitive 20): discussion_question_validator.classify_question has cognitive complexity 20 (threshold 15). Drivers by points: if/else 7 (16 pts), 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":"research/syllabus/skills/syllabus/scripts/discussion_question_validator.py"},"region":{"startLine":54}}}],"partialFingerprints":{"codehealthFindingId/v1":"4f0a14a8b3396ccb6c49717df21b3040f50cb3a41fb8480f5fdb3537176519e0"}},{"ruleId":"D2","level":"warning","message":{"text":"smoke_scripts.main (cognitive 20): smoke_scripts.main has cognitive complexity 20 (threshold 15). Drivers by points: if/else 8 (11 pts), loops 3 (7 pts), boolean chains 1, error handling 1 (nesting depth added 7). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"scripts/smoke_scripts.py"},"region":{"startLine":97}}}],"partialFingerprints":{"codehealthFindingId/v1":"aaa3e57de0034fdab6ddb4a6d78c77f76fb2516412e2a94168f60d3f37e7e13a"}},{"ruleId":"D2","level":"warning","message":{"text":"sync-gemini-skills.create_symlinks (cognitive 20): sync-gemini-skills.create_symlinks has cognitive complexity 20 (threshold 15). Drivers by points: if/else 8 (17 pts), error handling 1 (2 pts), loops 1 (nesting depth added 10). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"scripts/sync-gemini-skills.py"},"region":{"startLine":187}}}],"partialFingerprints":{"codehealthFindingId/v1":"656a2ee19e5e496976b34418b6b1d6c12a92c913efc9b22692d0da33a7d3eda2"}},{"ruleId":"D2","level":"warning","message":{"text":"bottleneck_detector.detect (cognitive 19): bottleneck_detector.detect has cognitive complexity 19 (threshold 15). Drivers by points: if/else 10 (15 pts), loops 1 (2 pts), boolean chains 1, ternaries 1 (nesting depth added 6). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"business-operations/skills/process-mapper/scripts/bottleneck_detector.py"},"region":{"startLine":81}}}],"partialFingerprints":{"codehealthFindingId/v1":"e24e63b7fa63396bbc334a10417d8d1c22231b48e1c3c940ddfb83afa9ba261a"}},{"ruleId":"D2","level":"warning","message":{"text":"decision_matrix_scorer.sensitivity_analysis (cognitive 19): decision_matrix_scorer.sensitivity_analysis has cognitive complexity 19 (threshold 15). Drivers by points: if/else 5 (12 pts), loops 3 (7 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":"c-level-advisor/executive-mentor/skills/executive-mentor/scripts/decision_matrix_scorer.py"},"region":{"startLine":70}}}],"partialFingerprints":{"codehealthFindingId/v1":"af30b3564af270eddef9cbf8f1d7fd484d9d371af01af1ca16ccca8307e9caeb"}},{"ruleId":"D2","level":"warning","message":{"text":"unit_economics_analyzer.analyze_cohort (cognitive 19): unit_economics_analyzer.analyze_cohort has cognitive complexity 19 (threshold 15). Drivers by points: if/else 7 (9 pts), ternaries 6, boolean chains 4 (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":"c-level-advisor/skills/cfo-advisor/scripts/unit_economics_analyzer.py"},"region":{"startLine":98}}}],"partialFingerprints":{"codehealthFindingId/v1":"b5f5243a23f762bef8aa2236854985594c5890c745cfe3c125769bf363c46197"}},{"ruleId":"D2","level":"warning","message":{"text":"marketing_budget_modeler.print_recommendations (cognitive 19): marketing_budget_modeler.print_recommendations has cognitive complexity 19 (threshold 15). Drivers by points: if/else 8, loops 3 (6 pts), boolean chains 5 (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":"c-level-advisor/skills/cmo-advisor/scripts/marketing_budget_modeler.py"},"region":{"startLine":355}}}],"partialFingerprints":{"codehealthFindingId/v1":"0259925b530ffaf2a0df128e4f7ec8eae00ef2240f1f272d3b4dbf62d5f14f46"}},{"ruleId":"D2","level":"warning","message":{"text":"okr_tracker._generate_recommendations (cognitive 19): okr_tracker._generate_recommendations has cognitive complexity 19 (threshold 15). Drivers by points: if/else 11 (15 pts), loops 2 (3 pts), boolean chains 1 (nesting depth added 5). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"c-level-advisor/skills/coo-advisor/scripts/okr_tracker.py"},"region":{"startLine":594}}}],"partialFingerprints":{"codehealthFindingId/v1":"64fd8e3ee93aa663b1423aec869e5536ba35d05aa31c412a96d1711cb9de6c62"}},{"ruleId":"D2","level":"warning","message":{"text":"portfolio_analyzer.render_report (cognitive 19): portfolio_analyzer.render_report has cognitive complexity 19 (threshold 15). Drivers by points: ternaries 4 (9 pts), if/else 3 (5 pts), 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":"c-level-advisor/skills/cpo-advisor/scripts/portfolio_analyzer.py"},"region":{"startLine":416}}}],"partialFingerprints":{"codehealthFindingId/v1":"b2aa368607cc5a7f750fd916269034e803c3635aa4a6d4ed7c70bba04ab146ed"}},{"ruleId":"D2","level":"warning","message":{"text":"inspect-assets.analyse_image (cognitive 19): inspect-assets.analyse_image has cognitive complexity 19 (threshold 15). Drivers by points: if/else 10 (12 pts), error handling 3 (4 pts), boolean chains 2, 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":"engineering-team/skills/epic-design/scripts/inspect-assets.py"},"region":{"startLine":24}}}],"partialFingerprints":{"codehealthFindingId/v1":"3304ed0bd0398736b84acbaa4e241779aa26fbd68de454e3eda6948cb423732d"}},{"ruleId":"D2","level":"warning","message":{"text":"project_architect.print_human_report (cognitive 19): project_architect.print_human_report has cognitive complexity 19 (threshold 15). Drivers by points: if/else 7 (11 pts), loops 4 (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":"engineering-team/skills/senior-architect/scripts/project_architect.py"},"region":{"startLine":591}}}],"partialFingerprints":{"codehealthFindingId/v1":"d58191d37bc464f17923a9212aa750b5164a553e4daef54c8b9fc9e90f3b8828"}},{"ruleId":"D2","level":"warning","message":{"text":"TypeDetector.detect_type (cognitive 19): TypeDetector.detect_type has cognitive complexity 19 (threshold 15). Drivers by points: if/else 8 (11 pts), error handling 2 (5 pts), loops 2, boolean chains 1 (nesting depth added 6). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/skills/senior-data-engineer/scripts/data_quality_validator.py"},"region":{"startLine":156}}}],"partialFingerprints":{"codehealthFindingId/v1":"79c84648f6247daa2987470a1c142058775bd88b4d01d786fa9eccd7ba8d92aa"}},{"ruleId":"D2","level":"warning","message":{"text":"threat_signal_analyzer.hunt_mode (cognitive 19): threat_signal_analyzer.hunt_mode has cognitive complexity 19 (threshold 15). Drivers by points: if/else 3 (8 pts), loops 6 (8 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":"engineering-team/skills/threat-detection/scripts/threat_signal_analyzer.py"},"region":{"startLine":84}}}],"partialFingerprints":{"codehealthFindingId/v1":"1a39c6f28b0fd33b16187120b0a5eb0c547294e5b1ddb24b875c3516b30cef7e"}},{"ruleId":"D2","level":"warning","message":{"text":"loop_controller.cmd_record (cognitive 19): loop_controller.cmd_record has cognitive complexity 19 (threshold 15). Drivers by points: if/else 13 (18 pts), ternaries 1 (nesting depth added 5). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/agent-harness/skills/agent-harness/scripts/loop_controller.py"},"region":{"startLine":140}}}],"partialFingerprints":{"codehealthFindingId/v1":"0e2e72d828a1e01f7e3dceffcf0eee9a5e16750fc16130057e8c8b5cd17fc352"}},{"ruleId":"D2","level":"warning","message":{"text":"token_budget_estimator.audit_skill_dir (cognitive 19): token_budget_estimator.audit_skill_dir has cognitive complexity 19 (threshold 15). Drivers by points: if/else 7 (10 pts), ternaries 4 (6 pts), loops 2, boolean chains 1 (nesting depth added 5). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/book-to-skill/skills/book-to-skill/scripts/token_budget_estimator.py"},"region":{"startLine":111}}}],"partialFingerprints":{"codehealthFindingId/v1":"d975a890f811d854955aa61b588eba84cc6cc783a57c54bbec6f803a04d57e15"}},{"ruleId":"D2","level":"warning","message":{"text":"collect_sessions.sample_and_write (cognitive 19): collect_sessions.sample_and_write has cognitive complexity 19 (threshold 15). Drivers by points: if/else 5 (11 pts), loops 5 (6 pts), boolean chains 2 (nesting depth added 7). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skill-doctor/skills/skill-doctor/scripts/collect_sessions.py"},"region":{"startLine":589}}}],"partialFingerprints":{"codehealthFindingId/v1":"23664c41e72400fee86f552525c9d40d263c0a376d77d83bdf1b3aae61f66b3d"}},{"ruleId":"D2","level":"warning","message":{"text":"AgentEvaluator.identify_bottlenecks (cognitive 19): AgentEvaluator.identify_bottlenecks has cognitive complexity 19 (threshold 15). Drivers by points: ternaries 3 (9 pts), if/else 5 (8 pts), loops 2 (nesting depth added 9). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/agent-designer/agent_evaluator.py"},"region":{"startLine":473}}}],"partialFingerprints":{"codehealthFindingId/v1":"0d1dd4bb7a116ae026c9a4f98432f4295800036acb06aacca4f1bdc8812d0fee"}},{"ruleId":"D2","level":"warning","message":{"text":"api_linter.main (cognitive 19): api_linter.main has cognitive complexity 19 (threshold 15). Drivers by points: if/else 10 (11 pts), error handling 4 (7 pts), ternaries 1 (nesting depth added 4). To reduce it, split the body: this score is breadth rather than depth \u2014 many checks laid out side by side rather than nested inside one another, so inverting conditions into early returns has nothing left to flatten. Group the statements between the checks into named steps and move each step into its own function, so the body reads as a short sequence of named stages."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/api-design-reviewer/scripts/api_linter.py"},"region":{"startLine":867}}}],"partialFingerprints":{"codehealthFindingId/v1":"5ae04819100704ae52652c115556acfa1bb0e7e50939e6562c5012e2a661b3a9"}},{"ruleId":"D2","level":"warning","message":{"text":"pipeline_generator.main (cognitive 19): pipeline_generator.main has cognitive complexity 19 (threshold 15). Drivers by points: if/else 9 (11 pts), ternaries 3 (6 pts), boolean chains 2 (nesting depth added 5). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/ci-cd-pipeline-builder/scripts/pipeline_generator.py"},"region":{"startLine":288}}}],"partialFingerprints":{"codehealthFindingId/v1":"2c65e8f1c273eccf2951976cb1e394a260326249cf7cf0216cb6af7b7ca70add"}},{"ruleId":"D2","level":"warning","message":{"text":"HiringCalibrator._analyze_trends_over_time (cognitive 19): HiringCalibrator._analyze_trends_over_time has cognitive complexity 19 (threshold 15). Drivers by points: ternaries 7 (9 pts), if/else 6 (8 pts), loops 2 (nesting depth added 4). To reduce it, split the body: most of this score is breadth rather than depth \u2014 checks laid out side by side rather than stacked \u2014 so group the statements between the checks into named steps and move each step into its own function. Some of it IS depth: where a check sits inside another whose only job is to reach it, merge the two into one condition, 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":"engineering/skills/interview-system-designer/hiring_calibrator.py"},"region":{"startLine":604}}}],"partialFingerprints":{"codehealthFindingId/v1":"09f102746f2a1bf11e96e555c9f49ce76af25ab5b9f16090f09adf994575f307"}},{"ruleId":"D2","level":"warning","message":{"text":"audit_log_analyzer.print_human (cognitive 19): audit_log_analyzer.print_human has cognitive complexity 19 (threshold 15). Drivers by points: ternaries 3 (8 pts), loops 3 (6 pts), if/else 4, boolean chains 1 (nesting depth added 8). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/secrets-vault-manager/scripts/audit_log_analyzer.py"},"region":{"startLine":235}}}],"partialFingerprints":{"codehealthFindingId/v1":"5c1420306b7011519473625753e9b607aed090a81268cdffc0061f50a9d3edef"}},{"ruleId":"D2","level":"warning","message":{"text":"QualityScorer._score_usage_clarity (cognitive 19): QualityScorer._score_usage_clarity has cognitive complexity 19 (threshold 15). Drivers by points: if/else 6 (10 pts), error handling 2 (5 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":"engineering/skills/skill-tester/scripts/quality_scorer.py"},"region":{"startLine":875}}}],"partialFingerprints":{"codehealthFindingId/v1":"dc005d9ec47e40b087d88c9421751f425f86469999f0a5fa6bcb7f9983f77e0d"}},{"ruleId":"D2","level":"warning","message":{"text":"Analysis._warn_tax_rate_anomalies (cognitive 19): Analysis._warn_tax_rate_anomalies has cognitive complexity 19 (threshold 15). Drivers by points: if/else 10 (14 pts), boolean chains 3, 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":"finance/skills/stock-analysis/scripts/ratios.py"},"region":{"startLine":2158}}}],"partialFingerprints":{"codehealthFindingId/v1":"b03234d2b3d1f65101adf561905c240cd790f67d87234fde8052e9af2a988818"}},{"ruleId":"D2","level":"warning","message":{"text":"verify_data.classify_period (cognitive 19): verify_data.classify_period has cognitive complexity 19 (threshold 15). Drivers by points: if/else 9 (11 pts), boolean chains 4, ternaries 2 (4 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":"finance/skills/stock-analysis/scripts/verify_data.py"},"region":{"startLine":530}}}],"partialFingerprints":{"codehealthFindingId/v1":"73184173b1c383bda27f9a50e94f3ea3fe1c27cb3d2f62ae1168dc6f47ca7610"}},{"ruleId":"D2","level":"warning","message":{"text":"review_html_renderer.main (cognitive 19): review_html_renderer.main has cognitive complexity 19 (threshold 15). Drivers by points: if/else 9 (10 pts), boolean chains 5, ternaries 2 (4 pts) (nesting depth added 3). To reduce it, split the body: most of this score is breadth rather than depth \u2014 checks laid out side by side rather than stacked \u2014 so group the statements between the checks into named steps and move each step into its own function. Some of it IS depth: where a check sits inside another whose only job is to reach it, merge the two into one condition, and where an else follows a branch that already returns, drop the trailing else and let the rest of the body continue at one level."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"markdown-html/skills/md-review/scripts/review_html_renderer.py"},"region":{"startLine":538}}}],"partialFingerprints":{"codehealthFindingId/v1":"6316bd8c31429b2cb820128e53c983781b3e472e2efa3f7d3a8e92727de1f4a8"}},{"ruleId":"D2","level":"warning","message":{"text":"ad_copy_validator.validate_meta_feed (cognitive 19): ad_copy_validator.validate_meta_feed has cognitive complexity 19 (threshold 15). Drivers by points: if/else 5 (9 pts), ternaries 3 (8 pts), loops 1 (2 pts) (nesting depth added 10). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body. This shape REPEATS in the file: one other method here (ad_copy_validator.validate_linkedin) has the same decision points, in the same order, at the same nesting depths \u2014 so this is one pattern written twice rather than two separate problems. Splitting this body alone leaves the other exactly as it is. Where these are variations on one operation, the change that clears both is the shared one: lift the common shape into a single routine the variants call, parameterised by whatever genuinely differs between them, and keep in each method only the part that is not shared."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"marketing-skill/skills/ad-creative/scripts/ad_copy_validator.py"},"region":{"startLine":212}}}],"partialFingerprints":{"codehealthFindingId/v1":"bdbbf8a516a2b0cdbf42327417f7320987e1bb159458df7a272aae23eb5cb238"}},{"ruleId":"D2","level":"warning","message":{"text":"ad_copy_validator.validate_linkedin (cognitive 19): ad_copy_validator.validate_linkedin has cognitive complexity 19 (threshold 15). Drivers by points: if/else 5 (9 pts), ternaries 3 (8 pts), loops 1 (2 pts) (nesting depth added 10). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body. This shape REPEATS in the file: one other method here (ad_copy_validator.validate_meta_feed) has the same decision points, in the same order, at the same nesting depths \u2014 so this is one pattern written twice rather than two separate problems. Splitting this body alone leaves the other exactly as it is. Where these are variations on one operation, the change that clears both is the shared one: lift the common shape into a single routine the variants call, parameterised by whatever genuinely differs between them, and keep in each method only the part that is not shared."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"marketing-skill/skills/ad-creative/scripts/ad_copy_validator.py"},"region":{"startLine":248}}}],"partialFingerprints":{"codehealthFindingId/v1":"60667101a98e51f53f5089b5854146e22a93455928fd702e0ebb9f10b48a557e"}},{"ruleId":"D2","level":"warning","message":{"text":"ad_copy_validator.main (cognitive 19): ad_copy_validator.main has cognitive complexity 19 (threshold 15). Drivers by points: if/else 5 (6 pts), ternaries 3 (6 pts), error handling 2 (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":"marketing-skill/skills/ad-creative/scripts/ad_copy_validator.py"},"region":{"startLine":418}}}],"partialFingerprints":{"codehealthFindingId/v1":"6ae8f13d5940e53026149f218ea57d3a73fc0f1ead5bee96e31fb55b090b1cad"}},{"ruleId":"D2","level":"warning","message":{"text":"citation_tracker.render_human (cognitive 19): citation_tracker.render_human has cognitive complexity 19 (threshold 15). Drivers by points: if/else 7 (11 pts), loops 3 (6 pts), boolean chains 2 (nesting depth added 7). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"marketing-skill/skills/aeo/scripts/citation_tracker.py"},"region":{"startLine":175}}}],"partialFingerprints":{"codehealthFindingId/v1":"4a65f2338e7a8568ca55fb831a9176d6c7924ea88700b6d1d40387b6fc24ffba"}},{"ruleId":"D2","level":"warning","message":{"text":"email_sequence_analyzer.print_report (cognitive 19): email_sequence_analyzer.print_report has cognitive complexity 19 (threshold 15). Drivers by points: if/else 5 (8 pts), loops 4 (8 pts), ternaries 2 (3 pts) (nesting depth added 8). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"marketing-skill/skills/cold-email/scripts/email_sequence_analyzer.py"},"region":{"startLine":316}}}],"partialFingerprints":{"codehealthFindingId/v1":"ba00f179bb44cc01d0be354c304863c54b78caf590caf29a876871068735e1a8"}},{"ruleId":"D2","level":"warning","message":{"text":"humanizer_scorer.print_report (cognitive 19): humanizer_scorer.print_report has cognitive complexity 19 (threshold 15). Drivers by points: if/else 18, loops 1. To reduce it, split the body: this score is breadth rather than depth \u2014 many checks laid out side by side rather than nested inside one another, so inverting conditions into early returns has nothing left to flatten. Group the statements between the checks into named steps and move each step into its own function, so the body reads as a short sequence of named stages."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"marketing-skill/skills/content-humanizer/scripts/humanizer_scorer.py"},"region":{"startLine":360}}}],"partialFingerprints":{"codehealthFindingId/v1":"37f4b1deef3ca896c5c8bc98476e1e19eca0fd2266dc24179d30c5cc60b45885"}},{"ruleId":"D2","level":"warning","message":{"text":"competitor_analyzer.analyze_competitors (cognitive 19): competitor_analyzer.analyze_competitors has cognitive complexity 19 (threshold 15). Drivers by points: if/else 11 (15 pts), loops 3, boolean chains 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":"marketing-skill/skills/x-twitter-growth/scripts/competitor_analyzer.py"},"region":{"startLine":53}}}],"partialFingerprints":{"codehealthFindingId/v1":"ad739eefb995bd3623a6c702537f497c99f92fef49e315b31597f47d962b53ce"}},{"ruleId":"D2","level":"warning","message":{"text":"growth_tracker.main (cognitive 19): growth_tracker.main has cognitive complexity 19 (threshold 15). Drivers by points: if/else 12 (18 pts), boolean chains 1 (nesting depth added 6). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"marketing-skill/skills/x-twitter-growth/scripts/growth_tracker.py"},"region":{"startLine":185}}}],"partialFingerprints":{"codehealthFindingId/v1":"5438e326e650bacda24ba361de5943784e7adfe7490ca92a6bc36f54b0d04529"}},{"ruleId":"D2","level":"warning","message":{"text":"user_story_generator.main (cognitive 19): user_story_generator.main has cognitive complexity 19 (threshold 15). Drivers by points: if/else 5 (10 pts), loops 4 (9 pts) (nesting depth added 10). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"product-team/agile-product-owner/skills/agile-product-owner/scripts/user_story_generator.py"},"region":{"startLine":328}}}],"partialFingerprints":{"codehealthFindingId/v1":"5820b6de0209921ff81eb740ffcf23989de093fa967f974b439b8bcc63b9139e"}},{"ruleId":"D2","level":"warning","message":{"text":"setup._prompt_choice (cognitive 19): setup._prompt_choice has cognitive complexity 19 (threshold 15). Drivers by points: if/else 4 (9 pts), error handling 2 (4 pts), boolean chains 2, loops 2, ternaries 1 (2 pts) (nesting depth added 8). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"productivity/handoff/skills/handoff/scripts/setup.py"},"region":{"startLine":66}}}],"partialFingerprints":{"codehealthFindingId/v1":"0278e831e0d7523aa098b4a9eeda4575bfaac39007ebebeb6ca5ad37764cab28"}},{"ruleId":"D2","level":"warning","message":{"text":"permission_audit_tool.check_over_permissioned_groups (cognitive 19): permission_audit_tool.check_over_permissioned_groups has cognitive complexity 19 (threshold 15). Drivers by points: if/else 4 (13 pts), loops 3 (5 pts), boolean chains 1 (nesting depth added 11). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"project-management/skills/atlassian-admin/scripts/permission_audit_tool.py"},"region":{"startLine":62}}}],"partialFingerprints":{"codehealthFindingId/v1":"64e3a89fcec0804da7eb71d465b76821011a92c82637f8cd29a0108746fbfef5"}},{"ruleId":"D2","level":"warning","message":{"text":"ManagementReviewTracker.assess_metrics (cognitive 19): ManagementReviewTracker.assess_metrics has cognitive complexity 19 (threshold 15). Drivers by points: if/else 6 (10 pts), ternaries 2 (6 pts), boolean chains 2, loops 1 (nesting depth added 8). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"ra-qm-team/skills/quality-manager-qmr/scripts/management_review_tracker.py"},"region":{"startLine":201}}}],"partialFingerprints":{"codehealthFindingId/v1":"bc678e4bbf42b63a78a063955a6fea7840d06b4537e79c2a21daf1afe4d51009"}},{"ruleId":"D2","level":"warning","message":{"text":"regulatory_pathway_analyzer.format_analysis_text (cognitive 19): regulatory_pathway_analyzer.format_analysis_text has cognitive complexity 19 (threshold 15). Drivers by points: loops 7 (11 pts), ternaries 6, boolean chains 1, if/else 1 (nesting depth added 4). 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":"ra-qm-team/skills/regulatory-affairs-head/scripts/regulatory_pathway_analyzer.py"},"region":{"startLine":385}}}],"partialFingerprints":{"codehealthFindingId/v1":"ce55c99deddbc40b2e6ecbed3f53748eb129ffce1aad9ada9f68f43d5d8ae851"}},{"ruleId":"D2","level":"warning","message":{"text":"risk_matrix_calculator.main (cognitive 19): risk_matrix_calculator.main has cognitive complexity 19 (threshold 15). Drivers by points: if/else 13 (19 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":"ra-qm-team/skills/risk-management-specialist/scripts/risk_matrix_calculator.py"},"region":{"startLine":340}}}],"partialFingerprints":{"codehealthFindingId/v1":"a9e0f3f9ff994bbd184ca8e7a81bad01cab861381e11d080d020c2919bd1aa49"}},{"ruleId":"D2","level":"warning","message":{"text":"onboard.main (cognitive 19): onboard.main has cognitive complexity 19 (threshold 15). Drivers by points: if/else 8 (12 pts), error handling 1 (3 pts), loops 1 (2 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":"research-ops/skills/product-research/scripts/onboard.py"},"region":{"startLine":74}}}],"partialFingerprints":{"codehealthFindingId/v1":"152704a586af5c22fc5db21e9acd4be0bf19b72b4bd8a13d788642c6db04b517"}},{"ruleId":"D2","level":"warning","message":{"text":"audit_skills.main (cognitive 19): audit_skills.main has cognitive complexity 19 (threshold 15). Drivers by points: if/else 7 (11 pts), loops 6 (8 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":"scripts/audit_skills.py"},"region":{"startLine":41}}}],"partialFingerprints":{"codehealthFindingId/v1":"61501a56468753f0da38e219d1ad85b1b599d92e431ae6ebf96cd0d2e1ae126a"}},{"ruleId":"D2","level":"warning","message":{"text":"sync-vibe-skills.sync_skill (cognitive 19): sync-vibe-skills.sync_skill has cognitive complexity 19 (threshold 15). Drivers by points: if/else 9 (11 pts), ternaries 2 (5 pts), error handling 1 (2 pts), boolean chains 1 (nesting depth added 6). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"scripts/sync-vibe-skills.py"},"region":{"startLine":184}}}],"partialFingerprints":{"codehealthFindingId/v1":"1ba7929c2012c947a090440643dc4e9a70db271a2d6681a51842ed4f57c5f984"}},{"ruleId":"D2","level":"warning","message":{"text":"rfp_response_analyzer.determine_bid_recommendation (cognitive 18): rfp_response_analyzer.determine_bid_recommendation has cognitive complexity 18 (threshold 15). Drivers by points: if/else 7 (11 pts), boolean chains 5, 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":"business-growth/skills/sales-engineer/scripts/rfp_response_analyzer.py"},"region":{"startLine":207}}}],"partialFingerprints":{"codehealthFindingId/v1":"089b5a89fe10e5030acc8d84f73b91e90c731c56a8a323687f12562b86156769"}},{"ruleId":"D2","level":"warning","message":{"text":"capacity_modeler.model_capacity (cognitive 18): capacity_modeler.model_capacity has cognitive complexity 18 (threshold 15). Drivers by points: if/else 8 (10 pts), ternaries 3 (5 pts), loops 2, boolean chains 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":"business-operations/skills/capacity-planner/scripts/capacity_modeler.py"},"region":{"startLine":159}}}],"partialFingerprints":{"codehealthFindingId/v1":"73179c9a1bc6303182ec95dc0bb1e70f37494e8c22fe6c913c96fd0f47a16fd8"}},{"ruleId":"D2","level":"warning","message":{"text":"runbook_validator._parse_markdown (cognitive 18): runbook_validator._parse_markdown has cognitive complexity 18 (threshold 15). Drivers by points: if/else 6 (15 pts), boolean chains 1, loops 1, 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":"business-operations/skills/knowledge-ops/scripts/runbook_validator.py"},"region":{"startLine":262}}}],"partialFingerprints":{"codehealthFindingId/v1":"e704b34eaa6f8ce9958ddf75fc8d58bbdceed427a37580ab9b42c0b45b8b674d"}},{"ruleId":"D2","level":"warning","message":{"text":"process_documenter.render_markdown (cognitive 18): process_documenter.render_markdown has cognitive complexity 18 (threshold 15). Drivers by points: loops 6 (9 pts), if/else 3 (6 pts), ternaries 1 (3 pts) (nesting depth added 8). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"business-operations/skills/process-mapper/scripts/process_documenter.py"},"region":{"startLine":112}}}],"partialFingerprints":{"codehealthFindingId/v1":"b18ffc79708bb2cbfccc2e43fcc5f24edc3325a89669dc8a0e33cd3673a77e50"}},{"ruleId":"D2","level":"warning","message":{"text":"unit_economics_analyzer.export_csv_results (cognitive 18): unit_economics_analyzer.export_csv_results has cognitive complexity 18 (threshold 15). Drivers by points: ternaries 8 (16 pts), loops 2 (nesting depth added 8). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"c-level-advisor/skills/cfo-advisor/scripts/unit_economics_analyzer.py"},"region":{"startLine":337}}}],"partialFingerprints":{"codehealthFindingId/v1":"2906fb5ae3de53b1e16eb769d50836ecfe0cadbc70636e8994257b7ef82c09ed"}},{"ruleId":"D2","level":"warning","message":{"text":"ops_efficiency_analyzer.analyze_bottlenecks (cognitive 18): ops_efficiency_analyzer.analyze_bottlenecks has cognitive complexity 18 (threshold 15). Drivers by points: if/else 3 (7 pts), ternaries 2 (6 pts), loops 3 (4 pts), boolean chains 1 (nesting depth added 9). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"c-level-advisor/skills/coo-advisor/scripts/ops_efficiency_analyzer.py"},"region":{"startLine":207}}}],"partialFingerprints":{"codehealthFindingId/v1":"d9adce9cafc4221bae49525dc537ff9d9e7600f0bdbbb007a1b2b89f2b16992d"}},{"ruleId":"D2","level":"warning","message":{"text":"discount_approval_router.route_discount (cognitive 18): discount_approval_router.route_discount has cognitive complexity 18 (threshold 15). Drivers by points: if/else 8 (12 pts), boolean chains 3, loops 3 (nesting depth added 4). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"commercial/skills/deal-desk/scripts/discount_approval_router.py"},"region":{"startLine":131}}}],"partialFingerprints":{"codehealthFindingId/v1":"455c4cab4645fd355ed2050a9985799205549de64a32e1e76f09f7024e8f999d"}},{"ruleId":"D2","level":"warning","message":{"text":"a11y_scanner.scan_file (cognitive 18): a11y_scanner.scan_file has cognitive complexity 18 (threshold 15). Drivers by points: loops 4 (9 pts), if/else 2 (8 pts), error handling 1 (nesting depth added 11). To reduce it, break up the iteration: give each loop body a named function, and split a multi-phase loop into one function per phase so no single body carries the whole pipeline."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/a11y-audit/skills/a11y-audit/scripts/a11y_scanner.py"},"region":{"startLine":476}}}],"partialFingerprints":{"codehealthFindingId/v1":"7694965c83ca61fd26e93dfaf1289dd0d9ce17dcb67dd465ce344f08bdd460d9"}},{"ruleId":"D2","level":"warning","message":{"text":"code_quality_checker.check_csharp_specific_smells (cognitive 18): code_quality_checker.check_csharp_specific_smells has cognitive complexity 18 (threshold 15). Drivers by points: if/else 4 (9 pts), loops 7, boolean chains 2 (nesting depth added 5). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/skills/code-reviewer/scripts/code_quality_checker.py"},"region":{"startLine":417}}}],"partialFingerprints":{"codehealthFindingId/v1":"576393790e64ae19b4bebd3717622ebf86f31ccb24ab414a2be154c4d1147d57"}},{"ruleId":"D2","level":"warning","message":{"text":"incident_classifier.main (cognitive 18): incident_classifier.main has cognitive complexity 18 (threshold 15). Drivers by points: if/else 10 (11 pts), error handling 4 (5 pts), boolean chains 2 (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":"engineering-team/skills/incident-commander/scripts/incident_classifier.py"},"region":{"startLine":804}}}],"partialFingerprints":{"codehealthFindingId/v1":"33afeb5976a088890396565b7d7b97068538717bcc8de937b30330fc2b239e5c"}},{"ruleId":"D2","level":"warning","message":{"text":"incident_triage.classify_incident (cognitive 18): incident_triage.classify_incident has cognitive complexity 18 (threshold 15). Drivers by points: if/else 6 (12 pts), loops 3 (5 pts), boolean chains 1 (nesting depth added 8). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/skills/incident-response/scripts/incident_triage.py"},"region":{"startLine":349}}}],"partialFingerprints":{"codehealthFindingId/v1":"78fc2a09d372eae056a71d3c0f5e3de4385be5b437d3623693f6f04d43338382"}},{"ruleId":"D2","level":"warning","message":{"text":"DependencyAnalyzer._detect_circular_dependencies (cognitive 18): DependencyAnalyzer._detect_circular_dependencies has cognitive complexity 18 (threshold 15). Drivers by points: loops 5 (9 pts), if/else 4 (8 pts), boolean chains 1 (nesting depth added 8). To reduce it, break up the iteration: give each loop body a named function, and split a multi-phase loop into one function per phase so no single body carries the whole pipeline."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/skills/senior-architect/scripts/dependency_analyzer.py"},"region":{"startLine":331}}}],"partialFingerprints":{"codehealthFindingId/v1":"2a95294fc191380214d2e0f325ca999a95d5ec4a75ebf71a42ede9f4c782b379"}},{"ruleId":"D2","level":"warning","message":{"text":"dependency_analyzer.main (cognitive 18): dependency_analyzer.main has cognitive complexity 18 (threshold 15). Drivers by points: if/else 11 (15 pts), loops 1 (3 pts) (nesting depth added 6). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/skills/senior-architect/scripts/dependency_analyzer.py"},"region":{"startLine":520}}}],"partialFingerprints":{"codehealthFindingId/v1":"50f745bbdd51fad73d860f6092401c27e6ac7d9a597fca3d05fbc15aa87f4cb1"}},{"ruleId":"D2","level":"warning","message":{"text":"DatasetSplitter._stratified_split (cognitive 18): DatasetSplitter._stratified_split has cognitive complexity 18 (threshold 15). Drivers by points: if/else 6 (14 pts), loops 4 (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":"engineering-team/skills/senior-computer-vision/scripts/dataset_pipeline_builder.py"},"region":{"startLine":943}}}],"partialFingerprints":{"codehealthFindingId/v1":"8780e8441d91068b17f53cc520d086c893b819891baa95df9d51dc04b27c2331"}},{"ruleId":"D2","level":"warning","message":{"text":"DataProfiler._profile_column (cognitive 18): DataProfiler._profile_column has cognitive complexity 18 (threshold 15). Drivers by points: if/else 6 (10 pts), error handling 1 (3 pts), loops 1 (2 pts), ternaries 2, boolean chains 1 (nesting depth added 7). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/skills/senior-data-engineer/scripts/data_quality_validator.py"},"region":{"startLine":645}}}],"partialFingerprints":{"codehealthFindingId/v1":"ae49ade74fc8e83140dd773d9cbf5e09af9e739d70065f257d6c82b50e7c64a8"}},{"ruleId":"D2","level":"warning","message":{"text":"etl_performance_optimizer.cmd_optimize_partition (cognitive 18): etl_performance_optimizer.cmd_optimize_partition has cognitive complexity 18 (threshold 15). Drivers by points: if/else 7 (11 pts), loops 2 (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":"engineering-team/skills/senior-data-engineer/scripts/etl_performance_optimizer.py"},"region":{"startLine":1445}}}],"partialFingerprints":{"codehealthFindingId/v1":"0718edf68851a9283bdc3e6a498a0961763e9eb39b74925dc75657494bf09033"}},{"ruleId":"D2","level":"warning","message":{"text":"ComplianceChecker._search_files (cognitive 18): ComplianceChecker._search_files has cognitive complexity 18 (threshold 15). Drivers by points: if/else 3 (9 pts), error handling 2 (5 pts), loops 2 (3 pts), ternaries 1 (nesting depth added 10). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/skills/senior-secops/scripts/compliance_checker.py"},"region":{"startLine":948}}}],"partialFingerprints":{"codehealthFindingId/v1":"7c4090fcd9f873eb1c2768ab8a5fedd4b5a9fc1480060d2f3ce14a81f3b0f129"}},{"ruleId":"D2","level":"warning","message":{"text":"harness_manifest_builder.main (cognitive 18): harness_manifest_builder.main has cognitive complexity 18 (threshold 15). Drivers by points: if/else 7 (11 pts), loops 2 (3 pts), 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":"engineering/agent-harness/skills/agent-harness/scripts/harness_manifest_builder.py"},"region":{"startLine":199}}}],"partialFingerprints":{"codehealthFindingId/v1":"ad9b09ddd8251534f93bbad8af0028f40cf491dd093f6d668b35ee706910051a"}},{"ruleId":"D2","level":"warning","message":{"text":"memory_core.mark_contradictions (cognitive 18): memory_core.mark_contradictions has cognitive complexity 18 (threshold 15). Drivers by points: if/else 3 (10 pts), loops 4 (7 pts), boolean chains 1 (nesting depth added 10). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/agent-memory/skills/agent-memory/scripts/memory_core.py"},"region":{"startLine":340}}}],"partialFingerprints":{"codehealthFindingId/v1":"c0f09272f4d166a3b44f0e1c74e8d1492fe92b929ac353a0a96ad6ee46a1362a"}},{"ruleId":"D2","level":"warning","message":{"text":"memory_extract._iter_messages (cognitive 18): memory_extract._iter_messages has cognitive complexity 18 (threshold 15). Drivers by points: if/else 5 (11 pts), boolean chains 3, error handling 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":"engineering/agent-memory/skills/agent-memory/scripts/memory_extract.py"},"region":{"startLine":59}}}],"partialFingerprints":{"codehealthFindingId/v1":"ea68d18188acfcc3a22ce7211d89961386d9de020b799b0cbe37736994556d41"}},{"ruleId":"D2","level":"warning","message":{"text":"missing_value_analyzer.classify_mechanism (cognitive 18): missing_value_analyzer.classify_mechanism has cognitive complexity 18 (threshold 15). Drivers by points: if/else 11 (15 pts), 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":"engineering/data-quality-auditor/skills/data-quality-auditor/scripts/missing_value_analyzer.py"},"region":{"startLine":43}}}],"partialFingerprints":{"codehealthFindingId/v1":"d53e9fec58e472f79f79cca6278515d088c7a6f4b937b44a06214aa0b2fc7151"}},{"ruleId":"D2","level":"warning","message":{"text":"missing_value_analyzer.print_report (cognitive 18): missing_value_analyzer.print_report has cognitive complexity 18 (threshold 15). Drivers by points: if/else 5 (6 pts), ternaries 2 (6 pts), loops 3 (5 pts), boolean chains 1 (nesting depth added 7). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/data-quality-auditor/skills/data-quality-auditor/scripts/missing_value_analyzer.py"},"region":{"startLine":144}}}],"partialFingerprints":{"codehealthFindingId/v1":"379742066f0d73bf5df181c18837aaaf9165e26a934d5d46db42bd2f6555a756"}},{"ruleId":"D2","level":"warning","message":{"text":"training_diagnostics.diagnose (cognitive 18): training_diagnostics.diagnose has cognitive complexity 18 (threshold 15). Drivers by points: if/else 9 (12 pts), boolean chains 6 (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":"engineering/deep-learning-book/skills/deep-learning-book/scripts/training_diagnostics.py"},"region":{"startLine":70}}}],"partialFingerprints":{"codehealthFindingId/v1":"488d767996e7908c6d00f5ae8f0960bbc337c3444089e659dcc1d7184f680ee0"}},{"ruleId":"D2","level":"warning","message":{"text":"dockerfile_analyzer.run_pattern_checks (cognitive 18): dockerfile_analyzer.run_pattern_checks has cognitive complexity 18 (threshold 15). Drivers by points: if/else 8 (12 pts), loops 2 (4 pts), boolean chains 2 (nesting depth added 6). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/docker-development/skills/docker-development/scripts/dockerfile_analyzer.py"},"region":{"startLine":254}}}],"partialFingerprints":{"codehealthFindingId/v1":"5bf7687d1364754ef24d0b8da5f341bbebc19b2d37b34f53753d8e1ca5c0da74"}},{"ruleId":"D2","level":"warning","message":{"text":"graph_analyzer.build_graph (cognitive 18): graph_analyzer.build_graph has cognitive complexity 18 (threshold 15). Drivers by points: if/else 6 (13 pts), loops 3 (4 pts), boolean chains 1 (nesting depth added 8). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/llm-wiki/skills/llm-wiki/scripts/graph_analyzer.py"},"region":{"startLine":24}}}],"partialFingerprints":{"codehealthFindingId/v1":"9e88e2b78b1eb8fc231fe28e533b9d33b360aa65d97917334e7c872d68057d09"}},{"ruleId":"D2","level":"warning","message":{"text":"APILinter._validate_parameters (cognitive 18): APILinter._validate_parameters has cognitive complexity 18 (threshold 15). Drivers by points: if/else 6 (15 pts), boolean chains 2, loops 1 (nesting depth added 9). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/api-design-reviewer/scripts/api_linter.py"},"region":{"startLine":544}}}],"partialFingerprints":{"codehealthFindingId/v1":"d298c1dfdf2442e90a56be174de9f23bee797bd8fa71c7b6421f9f730a74d180"}},{"ruleId":"D2","level":"warning","message":{"text":"APILinter.generate_text_report (cognitive 18): APILinter.generate_text_report has cognitive complexity 18 (threshold 15). Drivers by points: if/else 6 (11 pts), loops 3 (7 pts) (nesting depth added 9). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/api-design-reviewer/scripts/api_linter.py"},"region":{"startLine":758}}}],"partialFingerprints":{"codehealthFindingId/v1":"2dc3f7955b89865a389dc18b4eae0ed6f560b87c4b5ae79959f38c7aee577774"}},{"ruleId":"D2","level":"warning","message":{"text":"APIScoringEngine._check_caching_headers (cognitive 18): APIScoringEngine._check_caching_headers has cognitive complexity 18 (threshold 15). Drivers by points: if/else 4 (12 pts), loops 2 (4 pts), boolean chains 1, ternaries 1 (nesting depth added 10). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/api-design-reviewer/scripts/api_scorecard.py"},"region":{"startLine":1298}}}],"partialFingerprints":{"codehealthFindingId/v1":"8dd52e6e239335ba826d2c8ad104d2968e53f33e78c3b1d614b387d6709e3526"}},{"ruleId":"D2","level":"warning","message":{"text":"SchemaComparator._detect_renamed_tables (cognitive 18): SchemaComparator._detect_renamed_tables has cognitive complexity 18 (threshold 15). Drivers by points: if/else 5 (12 pts), loops 3 (4 pts), boolean chains 2 (nesting depth added 8). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/database-designer/migration_generator.py"},"region":{"startLine":192}}}],"partialFingerprints":{"codehealthFindingId/v1":"960d77df58d108e3080898f3b10a9684693c88a5c2d0c082f162f6e1552b472c"}},{"ruleId":"D2","level":"warning","message":{"text":"hiring_calibrator.main (cognitive 18): hiring_calibrator.main has cognitive complexity 18 (threshold 15). Drivers by points: if/else 8 (9 pts), ternaries 3 (5 pts), error handling 4 (nesting depth added 3). To reduce it, split the body: most of this score is breadth rather than depth \u2014 checks laid out side by side rather than stacked \u2014 so group the statements between the checks into named steps and move each step into its own function. Some of it IS depth: where a check sits inside another whose only job is to reach it, merge the two into one condition, and where an else follows a branch that already returns, drop the trailing else and let the rest of the body continue at one level."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/interview-system-designer/hiring_calibrator.py"},"region":{"startLine":1216}}}],"partialFingerprints":{"codehealthFindingId/v1":"95f8a37fff6c7eef59d3bd99f7230dc4bd2135e322fe121244ef48a8ce1d4279"}},{"ruleId":"D2","level":"warning","message":{"text":"monorepo_analyzer.main (cognitive 18): monorepo_analyzer.main has cognitive complexity 18 (threshold 15). Drivers by points: ternaries 3 (7 pts), if/else 5 (6 pts), loops 2 (4 pts), boolean chains 1 (nesting depth added 7). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/monorepo-navigator/scripts/monorepo_analyzer.py"},"region":{"startLine":122}}}],"partialFingerprints":{"codehealthFindingId/v1":"749dc6cfbb23d263bed6b8c4c7e6a068ea7234c402aa800dd6cdb15c116467f9"}},{"ruleId":"D2","level":"warning","message":{"text":"skill_security_auditor.scan_file_code (cognitive 18): skill_security_auditor.scan_file_code has cognitive complexity 18 (threshold 15). Drivers by points: if/else 6 (11 pts), boolean chains 3, 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":"engineering/skills/skill-security-auditor/scripts/skill_security_auditor.py"},"region":{"startLine":609}}}],"partialFingerprints":{"codehealthFindingId/v1":"1118a32bc87730c74ff8f39cb6e689a0e1d89502ba869516ae891d6b325894c8"}},{"ruleId":"D2","level":"warning","message":{"text":"migration_generator.main (cognitive 18): migration_generator.main has cognitive complexity 18 (threshold 15). Drivers by points: if/else 9 (15 pts), loops 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":"engineering/skills/sql-database-assistant/scripts/migration_generator.py"},"region":{"startLine":362}}}],"partialFingerprints":{"codehealthFindingId/v1":"06bce34a45b0157b98320bac0a36964075070b1d7443f26fa970d57f06ceca8b"}},{"ruleId":"D2","level":"warning","message":{"text":"tc_status.main (cognitive 18): tc_status.main has cognitive complexity 18 (threshold 15). Drivers by points: if/else 7 (8 pts), ternaries 4 (8 pts), error handling 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":"engineering/skills/tc-tracker/scripts/tc_status.py"},"region":{"startLine":140}}}],"partialFingerprints":{"codehealthFindingId/v1":"f3110c74d97f7cfd959adc666c8f464ec7bbc1b150b4cd9efb079f2f2bdebcb5"}},{"ruleId":"D2","level":"warning","message":{"text":"DebtDashboard._generate_strategic_recommendations (cognitive 18): DebtDashboard._generate_strategic_recommendations has cognitive complexity 18 (threshold 15). Drivers by points: if/else 9 (11 pts), ternaries 3 (5 pts), boolean chains 2 (nesting depth added 4). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/tech-debt-tracker/scripts/debt_dashboard.py"},"region":{"startLine":665}}}],"partialFingerprints":{"codehealthFindingId/v1":"44c8f98e5a92190ab9795d6a8331268622eaedb0bd828fa95fc24a9108dd11fa"}},{"ruleId":"D2","level":"warning","message":{"text":"debt_dashboard.main (cognitive 18): debt_dashboard.main has cognitive complexity 18 (threshold 15). Drivers by points: if/else 9 (11 pts), ternaries 2 (6 pts), error handling 1 (nesting depth added 6). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/tech-debt-tracker/scripts/debt_dashboard.py"},"region":{"startLine":907}}}],"partialFingerprints":{"codehealthFindingId/v1":"a5305ab4ef93b47265ac7b9a6b99f0fb2a5f86f1f099d9e4677396b068e6f111"}},{"ruleId":"D2","level":"warning","message":{"text":"DebtScanner._detect_duplicates (cognitive 18): DebtScanner._detect_duplicates has cognitive complexity 18 (threshold 15). Drivers by points: if/else 3 (9 pts), loops 4 (7 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":"engineering/skills/tech-debt-tracker/scripts/debt_scanner.py"},"region":{"startLine":278}}}],"partialFingerprints":{"codehealthFindingId/v1":"08dd2dc4679c09fbad748ba9a2048700f6990267e76a6c2f447810b3fcf484dc"}},{"ruleId":"D2","level":"warning","message":{"text":"debt_scanner.main (cognitive 18): debt_scanner.main has cognitive complexity 18 (threshold 15). Drivers by points: if/else 7 (9 pts), ternaries 2 (6 pts), error handling 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":"engineering/skills/tech-debt-tracker/scripts/debt_scanner.py"},"region":{"startLine":628}}}],"partialFingerprints":{"codehealthFindingId/v1":"05267f4ecaf46ba45acc0cb07d57a2a83d0ccb4fddadb7d661c78154735c3a51"}},{"ruleId":"D2","level":"warning","message":{"text":"hypothesis_tester.main (cognitive 18): hypothesis_tester.main has cognitive complexity 18 (threshold 15). Drivers by points: if/else 7 (13 pts), loops 2 (4 pts), boolean chains 1 (nesting depth added 8). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/statistical-analyst/skills/statistical-analyst/scripts/hypothesis_tester.py"},"region":{"startLine":409}}}],"partialFingerprints":{"codehealthFindingId/v1":"2ecdd4ba68557df908860612315c6e22b9d5ac773fa8585c700295543a2b8263"}},{"ruleId":"D2","level":"warning","message":{"text":"sample_size_calculator.main (cognitive 18): sample_size_calculator.main has cognitive complexity 18 (threshold 15). Drivers by points: if/else 9 (13 pts), boolean chains 2, ternaries 1 (2 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":"engineering/statistical-analyst/skills/statistical-analyst/scripts/sample_size_calculator.py"},"region":{"startLine":185}}}],"partialFingerprints":{"codehealthFindingId/v1":"8e05f72981a3a93bdf5119eb8cf8d95255f6b789b8a646433babb833fb54ba9a"}},{"ruleId":"D2","level":"warning","message":{"text":"lint_report.check_template_sections (cognitive 18): lint_report.check_template_sections has cognitive complexity 18 (threshold 15). Drivers by points: if/else 9 (17 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":"finance/skills/stock-analysis/scripts/lint_report.py"},"region":{"startLine":751}}}],"partialFingerprints":{"codehealthFindingId/v1":"bf27cdf266af582558e986ae056d8b534cdccd84a757a8f5069100e0b815d49a"}},{"ruleId":"D2","level":"warning","message":{"text":"score.build_anchor_points (cognitive 18): score.build_anchor_points has cognitive complexity 18 (threshold 15). Drivers by points: if/else 8 (15 pts), error handling 1 (2 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":"finance/skills/stock-analysis/scripts/score.py"},"region":{"startLine":245}}}],"partialFingerprints":{"codehealthFindingId/v1":"ae16909ca118e44c9bec78e1037486369db1fe236cdcfdcb0552f91213f45851"}},{"ruleId":"D2","level":"warning","message":{"text":"score.resolve_segment_weights (cognitive 18): score.resolve_segment_weights has cognitive complexity 18 (threshold 15). Drivers by points: if/else 6 (11 pts), boolean chains 3, ternaries 1 (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":"finance/skills/stock-analysis/scripts/score.py"},"region":{"startLine":829}}}],"partialFingerprints":{"codehealthFindingId/v1":"d74804447051a699f05e0f140af13fbdf7d32fcf2e0a7992bb6e9b8702dd3506"}},{"ruleId":"D2","level":"warning","message":{"text":"valuation.compute_scenarios (cognitive 18): valuation.compute_scenarios has cognitive complexity 18 (threshold 15). Drivers by points: if/else 6 (9 pts), boolean chains 4, ternaries 3 (4 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":"finance/skills/stock-analysis/scripts/valuation.py"},"region":{"startLine":545}}}],"partialFingerprints":{"codehealthFindingId/v1":"01b45611a1bb953ef57d1b7a054977ac5bf890747c7eecb34fdb06c70c00e172"}},{"ruleId":"D2","level":"warning","message":{"text":"brand_palette_validator.validate (cognitive 18): brand_palette_validator.validate has cognitive complexity 18 (threshold 15). Drivers by points: error handling 4 (7 pts), ternaries 5, boolean chains 3, if/else 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":"marketing/landing/skills/landing/scripts/brand_palette_validator.py"},"region":{"startLine":127}}}],"partialFingerprints":{"codehealthFindingId/v1":"57afff4c292b3faf67d4626d47d691c729507c548ce1902255dc51f16065b3b0"}},{"ruleId":"D2","level":"warning","message":{"text":"positioning_brief.render_human (cognitive 18): positioning_brief.render_human has cognitive complexity 18 (threshold 15). Drivers by points: loops 4 (8 pts), if/else 6, ternaries 1 (3 pts), boolean chains 1 (nesting depth added 6). To reduce it, split the body: this score is breadth rather than depth \u2014 many checks laid out side by side rather than nested inside one another, so inverting conditions into early returns has nothing left to flatten. Group the statements between the checks into named steps and move each step into its own function, so the body reads as a short sequence of named stages."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"marketing/linkedin/skills/linkedin-strategy/scripts/positioning_brief.py"},"region":{"startLine":219}}}],"partialFingerprints":{"codehealthFindingId/v1":"8921a2a7a98f8b7073f9869ecb8dc47acd6d2dadaea1136f8a25249be42a1714"}},{"ruleId":"D2","level":"warning","message":{"text":"verdict_synthesizer.synthesize (cognitive 18): verdict_synthesizer.synthesize has cognitive complexity 18 (threshold 15). Drivers by points: if/else 14, boolean chains 4. To reduce it, split the body: this score is breadth rather than depth \u2014 many checks laid out side by side rather than nested inside one another, so inverting conditions into early returns has nothing left to flatten. Group the statements between the checks into named steps and move each step into its own function, so the body reads as a short sequence of named stages."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"productivity/roast/skills/roast/scripts/verdict_synthesizer.py"},"region":{"startLine":60}}}],"partialFingerprints":{"codehealthFindingId/v1":"4c5a6e4373e15ef93b121dc33139dec69119a4f33a3e59ae8479fe0cf6e27481"}},{"ruleId":"D2","level":"warning","message":{"text":"weekly_review_gate.evaluate (cognitive 18): weekly_review_gate.evaluate has cognitive complexity 18 (threshold 15). Drivers by points: if/else 9 (12 pts), loops 3, ternaries 3 (nesting depth added 3). To reduce it, split the body: most of this score is breadth rather than depth \u2014 checks laid out side by side rather than stacked \u2014 so group the statements between the checks into named steps and move each step into its own function. Some of it IS depth: where a check sits inside another whose only job is to reach it, merge the two into one condition, 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":"productivity/weekly-review/skills/weekly-review/scripts/weekly_review_gate.py"},"region":{"startLine":86}}}],"partialFingerprints":{"codehealthFindingId/v1":"d04af97b01404c19fe639b2eae2b36a32acb2b49015ff38b186e512dc38c672b"}},{"ruleId":"D2","level":"warning","message":{"text":"retrospective_analyzer._calculate_improvement_velocity (cognitive 18): retrospective_analyzer._calculate_improvement_velocity has cognitive complexity 18 (threshold 15). Drivers by points: if/else 10 (14 pts), loops 3 (4 pts) (nesting depth added 5). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"project-management/skills/scrum-master/scripts/retrospective_analyzer.py"},"region":{"startLine":594}}}],"partialFingerprints":{"codehealthFindingId/v1":"049a43b2fd8a29838ea3f0e38fd76eddbe2ec118f76db519bd1dd0524d4623cd"}},{"ruleId":"D2","level":"warning","message":{"text":"sprint_health_scorer.format_text_output (cognitive 18): sprint_health_scorer.format_text_output has cognitive complexity 18 (threshold 15). Drivers by points: if/else 7 (11 pts), boolean chains 4, loops 2 (3 pts) (nesting depth added 5). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"project-management/skills/scrum-master/scripts/sprint_health_scorer.py"},"region":{"startLine":615}}}],"partialFingerprints":{"codehealthFindingId/v1":"b4c94f20fecbdf5af0c6324946e7caeb8bcbdc15b5eb4798700c2ddd28edd5de"}},{"ruleId":"D2","level":"warning","message":{"text":"hipaa_risk_assessment.detect_phi_handling (cognitive 18): hipaa_risk_assessment.detect_phi_handling has cognitive complexity 18 (threshold 15). Drivers by points: if/else 2 (7 pts), loops 3 (6 pts), error handling 2 (5 pts) (nesting depth added 11). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body. This shape REPEATS in the file: one other method here (hipaa_risk_assessment.detect_security_vulnerabilities) has the same decision points, in the same order, at the same nesting depths \u2014 so this is one pattern written twice rather than two separate problems. Splitting this body alone leaves the other exactly as it is. Where these are variations on one operation, the change that clears both is the shared one: lift the common shape into a single routine the variants call, parameterised by whatever genuinely differs between them, and keep in each method only the part that is not shared."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"ra-qm-team/skills/fda-consultant-specialist/scripts/hipaa_risk_assessment.py"},"region":{"startLine":294}}}],"partialFingerprints":{"codehealthFindingId/v1":"317335a2d60d1d2d3c732360ceb77aeb8716c407f1db7410041b059de93ca214"}},{"ruleId":"D2","level":"warning","message":{"text":"hipaa_risk_assessment.detect_security_vulnerabilities (cognitive 18): hipaa_risk_assessment.detect_security_vulnerabilities has cognitive complexity 18 (threshold 15). Drivers by points: if/else 2 (7 pts), loops 3 (6 pts), error handling 2 (5 pts) (nesting depth added 11). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body. This shape REPEATS in the file: one other method here (hipaa_risk_assessment.detect_phi_handling) has the same decision points, in the same order, at the same nesting depths \u2014 so this is one pattern written twice rather than two separate problems. Splitting this body alone leaves the other exactly as it is. Where these are variations on one operation, the change that clears both is the shared one: lift the common shape into a single routine the variants call, parameterised by whatever genuinely differs between them, and keep in each method only the part that is not shared."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"ra-qm-team/skills/fda-consultant-specialist/scripts/hipaa_risk_assessment.py"},"region":{"startLine":328}}}],"partialFingerprints":{"codehealthFindingId/v1":"0cafd54106ebf6dc290a8c0180cc7eaafb60b4ff357130021c2d01619e07b094"}},{"ruleId":"D2","level":"warning","message":{"text":"hipaa_risk_assessment.print_text_report (cognitive 18): hipaa_risk_assessment.print_text_report has cognitive complexity 18 (threshold 15). Drivers by points: loops 5 (8 pts), if/else 5 (7 pts), ternaries 2 (3 pts) (nesting depth added 6). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"ra-qm-team/skills/fda-consultant-specialist/scripts/hipaa_risk_assessment.py"},"region":{"startLine":480}}}],"partialFingerprints":{"codehealthFindingId/v1":"10ae5ec2ded52515c9b24df365f3f5a563ee08deb9e87640806626044711f669"}},{"ruleId":"D2","level":"warning","message":{"text":"FMEAAnalyzer.analyze_entries (cognitive 18): FMEAAnalyzer.analyze_entries has cognitive complexity 18 (threshold 15). Drivers by points: ternaries 7 (10 pts), if/else 6, loops 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."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"ra-qm-team/skills/risk-management-specialist/scripts/fmea_analyzer.py"},"region":{"startLine":130}}}],"partialFingerprints":{"codehealthFindingId/v1":"5bb5f662fb721d49b7aed2091a1f4e423f9b9002183ef29533e69cf0bc136f9d"}},{"ruleId":"D2","level":"warning","message":{"text":"fmea_analyzer.format_fmea_text (cognitive 18): fmea_analyzer.format_fmea_text has cognitive complexity 18 (threshold 15). Drivers by points: loops 5 (10 pts), if/else 4 (6 pts), ternaries 1 (2 pts) (nesting depth added 8). To reduce it, break up the iteration: give each loop body a named function, and split a multi-phase loop into one function per phase so no single body carries the whole pipeline."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"ra-qm-team/skills/risk-management-specialist/scripts/fmea_analyzer.py"},"region":{"startLine":274}}}],"partialFingerprints":{"codehealthFindingId/v1":"e7d9cb8ee52e6b7208d77a9644477ee5b401184f67fb732943182aa30bf2c3aa"}},{"ruleId":"D2","level":"warning","message":{"text":"citation_tracker.extract_rows (cognitive 18): citation_tracker.extract_rows has cognitive complexity 18 (threshold 15). Drivers by points: if/else 9 (18 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":"research/pulse/skills/pulse/scripts/citation_tracker.py"},"region":{"startLine":140}}}],"partialFingerprints":{"codehealthFindingId/v1":"4c7fe90880fad9d8a45e546682ef60f408ea0346bbd002679094648eae61c276"}},{"ruleId":"D2","level":"warning","message":{"text":"derive_counters.derive (cognitive 18): derive_counters.derive has cognitive complexity 18 (threshold 15). Drivers by points: if/else 5 (12 pts), boolean chains 3, error handling 1 (2 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":"scripts/derive_counters.py"},"region":{"startLine":79}}}],"partialFingerprints":{"codehealthFindingId/v1":"121c5e9aaf655e8214855647ce282927962ad6e77598dc7c665d9e69f6d7da0b"}},{"ruleId":"D2","level":"warning","message":{"text":"generate-docs.extract_subtitle (cognitive 18): generate-docs.extract_subtitle has cognitive complexity 18 (threshold 15). Drivers by points: if/else 4 (10 pts), loops 2 (4 pts), boolean chains 3, error handling 1 (nesting depth added 8). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"scripts/generate-docs.py"},"region":{"startLine":125}}}],"partialFingerprints":{"codehealthFindingId/v1":"8dd5e17f380f79878aec441311425aabe6db1bf622ff7fc8f7f4e73f850f7e34"}},{"ruleId":"D2","level":"warning","message":{"text":"competitive_matrix_builder.format_text (cognitive 17): competitive_matrix_builder.format_text has cognitive complexity 17 (threshold 15). Drivers by points: loops 5 (7 pts), ternaries 3 (6 pts), if/else 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":"business-growth/skills/sales-engineer/scripts/competitive_matrix_builder.py"},"region":{"startLine":369}}}],"partialFingerprints":{"codehealthFindingId/v1":"115431a87e84e936d6946b08d6b91eba03d2d1ed7f8799ed123192aa9fa0bdfe"}},{"ruleId":"D2","level":"warning","message":{"text":"rfp_response_analyzer.generate_gap_analysis (cognitive 17): rfp_response_analyzer.generate_gap_analysis has cognitive complexity 17 (threshold 15). Drivers by points: if/else 4 (10 pts), ternaries 2 (6 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":"business-growth/skills/sales-engineer/scripts/rfp_response_analyzer.py"},"region":{"startLine":114}}}],"partialFingerprints":{"codehealthFindingId/v1":"c1c5af7d39f3fc2765fc9fa200a83fa649721681af5a7e1030ff82d8ab37e96d"}},{"ruleId":"D2","level":"warning","message":{"text":"ai_risk_classifier.classify_eu (cognitive 17): ai_risk_classifier.classify_eu 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":"c-level-advisor/chief-ai-officer-advisor/skills/chief-ai-officer-advisor/scripts/ai_risk_classifier.py"},"region":{"startLine":78}}}],"partialFingerprints":{"codehealthFindingId/v1":"d3792334d3902965d25047ffe3e414ac51da5a500a92cc8d6715fc4df9297e8a"}},{"ruleId":"D2","level":"warning","message":{"text":"RunwayCalculator.run (cognitive 17): RunwayCalculator.run has cognitive complexity 17 (threshold 15). Drivers by points: if/else 4 (7 pts), loops 4 (6 pts), ternaries 2 (4 pts) (nesting depth added 7). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"c-level-advisor/skills/cfo-advisor/scripts/burn_rate_calculator.py"},"region":{"startLine":91}}}],"partialFingerprints":{"codehealthFindingId/v1":"ebc455fa4bc2377ff09a3e10e434cff6193c4f75865446643eb39e0d04079355"}},{"ruleId":"D2","level":"warning","message":{"text":"ai_risk_classifier.classify_eu (cognitive 17): ai_risk_classifier.classify_eu 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":"c-level-advisor/skills/chief-ai-officer-advisor/scripts/ai_risk_classifier.py"},"region":{"startLine":78}}}],"partialFingerprints":{"codehealthFindingId/v1":"4a7860704dc5da0b7f7595c04d5225dfa0fd986148a223ca76c0d311eb4714ea"}},{"ruleId":"D2","level":"warning","message":{"text":"ops_efficiency_analyzer.generate_improvement_plan (cognitive 17): ops_efficiency_analyzer.generate_improvement_plan has cognitive complexity 17 (threshold 15). Drivers by points: loops 6 (7 pts), if/else 5 (6 pts), boolean chains 2, ternaries 1 (2 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":"c-level-advisor/skills/coo-advisor/scripts/ops_efficiency_analyzer.py"},"region":{"startLine":476}}}],"partialFingerprints":{"codehealthFindingId/v1":"1d3dcfbbd013d1ca58aef6cc98e1b67112129195656d0cbe07be8849b1b3f8d1"}},{"ruleId":"D2","level":"warning","message":{"text":"pmf_scorer.score_satisfaction (cognitive 17): pmf_scorer.score_satisfaction has cognitive complexity 17 (threshold 15). Drivers by points: if/else 12 (17 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":"c-level-advisor/skills/cpo-advisor/scripts/pmf_scorer.py"},"region":{"startLine":273}}}],"partialFingerprints":{"codehealthFindingId/v1":"9e5073e073a3bba1660dc4d45defe193dab6faf3a8edd41a5c289257c1aaa836"}},{"ruleId":"D2","level":"warning","message":{"text":"framework_selector.render_text (cognitive 17): framework_selector.render_text has cognitive complexity 17 (threshold 15). Drivers by points: if/else 5 (11 pts), loops 3 (4 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":"compliance-os/skills/compliance-os/scripts/framework_selector.py"},"region":{"startLine":230}}}],"partialFingerprints":{"codehealthFindingId/v1":"3621c4561d98c7d2868158f59330e7cd9c869fad3791d5fca1a361ba1d6d0056"}},{"ruleId":"D2","level":"warning","message":{"text":"pir_generator.main (cognitive 17): pir_generator.main has cognitive complexity 17 (threshold 15). Drivers by points: if/else 10 (11 pts), boolean chains 3, error handling 3 (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":"engineering-team/skills/incident-commander/scripts/pir_generator.py"},"region":{"startLine":1501}}}],"partialFingerprints":{"codehealthFindingId/v1":"17edb5e70167254fb4cf9f077b3c773632552bc46f8f3950d459ec0f91b5a72f"}},{"ruleId":"D2","level":"warning","message":{"text":"DependencyAnalyzer._parse_cargo (cognitive 17): DependencyAnalyzer._parse_cargo has cognitive complexity 17 (threshold 15). Drivers by points: if/else 6 (13 pts), boolean chains 2, error handling 1, loops 1 (nesting depth added 7). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/skills/senior-architect/scripts/dependency_analyzer.py"},"region":{"startLine":228}}}],"partialFingerprints":{"codehealthFindingId/v1":"43bb971e5cfa7a501d321561874d32d08f6084038f3067cd50f17c83d9965d5d"}},{"ruleId":"D2","level":"warning","message":{"text":"APIScaffolder.generate_types (cognitive 17): APIScaffolder.generate_types has cognitive complexity 17 (threshold 15). Drivers by points: if/else 6 (13 pts), boolean chains 2, 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":"engineering-team/skills/senior-backend/scripts/api_scaffolder.py"},"region":{"startLine":342}}}],"partialFingerprints":{"codehealthFindingId/v1":"862bc85f06f09787c1273a3870a693284bd515fbd1f129a8624577289f8fc012"}},{"ruleId":"D2","level":"warning","message":{"text":"SchemaAnalyzer._check_data_types (cognitive 17): SchemaAnalyzer._check_data_types has cognitive complexity 17 (threshold 15). Drivers by points: if/else 5 (12 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":"engineering-team/skills/senior-backend/scripts/database_migration_tool.py"},"region":{"startLine":390}}}],"partialFingerprints":{"codehealthFindingId/v1":"2f712886b691e2f6f31b59706714b28cdbbbb923e9f5bc9c6a8c6e6fa16cd92d"}},{"ruleId":"D2","level":"warning","message":{"text":"DatasetAnalyzer._analyze_voc (cognitive 17): DatasetAnalyzer._analyze_voc has cognitive complexity 17 (threshold 15). Drivers by points: if/else 5 (11 pts), loops 2 (3 pts), error handling 1 (2 pts), boolean chains 1 (nesting depth added 8). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/skills/senior-computer-vision/scripts/dataset_pipeline_builder.py"},"region":{"startLine":422}}}],"partialFingerprints":{"codehealthFindingId/v1":"44082dc3c06b35cb139c1e800f3ea2f78ecd9c1afb51e8ab84942b83ce831276"}},{"ruleId":"D2","level":"warning","message":{"text":"vision_model_trainer.main (cognitive 17): vision_model_trainer.main has cognitive complexity 17 (threshold 15). Drivers by points: if/else 8 (12 pts), loops 1 (4 pts), error handling 1 (nesting depth added 7). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/skills/senior-computer-vision/scripts/vision_model_trainer.py"},"region":{"startLine":492}}}],"partialFingerprints":{"codehealthFindingId/v1":"37e3984809d2a22dafade838b47e072a29751b28883779d72c5b87fa2fba5cfe"}},{"ruleId":"D2","level":"warning","message":{"text":"deployment_manager.cmd_deploy (cognitive 17): deployment_manager.cmd_deploy has cognitive complexity 17 (threshold 15). Drivers by points: if/else 8 (13 pts), ternaries 1 (3 pts), boolean chains 1 (nesting depth added 7). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/skills/senior-devops/scripts/deployment_manager.py"},"region":{"startLine":91}}}],"partialFingerprints":{"codehealthFindingId/v1":"bdec1ff8f19dbd6206a44c0b8862e5d33b5fb6b004278e088e2f513dffd2d64b"}},{"ruleId":"D2","level":"warning","message":{"text":"agent_orchestrator.generate_ascii_diagram (cognitive 17): agent_orchestrator.generate_ascii_diagram has cognitive complexity 17 (threshold 15). Drivers by points: if/else 7 (14 pts), loops 1 (3 pts) (nesting depth added 9). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/skills/senior-prompt-engineer/scripts/agent_orchestrator.py"},"region":{"startLine":245}}}],"partialFingerprints":{"codehealthFindingId/v1":"34d324754b2a9630cccf7e2536621fa3d565c64de2799611c61f2e59e4fdca17"}},{"ruleId":"D2","level":"warning","message":{"text":"prompt_optimizer.extract_sections (cognitive 17): prompt_optimizer.extract_sections has cognitive complexity 17 (threshold 15). Drivers by points: if/else 4 (10 pts), ternaries 1 (4 pts), loops 2 (3 pts) (nesting depth added 10). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/skills/senior-prompt-engineer/scripts/prompt_optimizer.py"},"region":{"startLine":163}}}],"partialFingerprints":{"codehealthFindingId/v1":"18d268d6e9be84126cea4401a5d7e4ae8f5ecf174f4de1a3907657cef2356b38"}},{"ruleId":"D2","level":"warning","message":{"text":"prompt_optimizer.format_report (cognitive 17): prompt_optimizer.format_report has cognitive complexity 17 (threshold 15). Drivers by points: if/else 6 (7 pts), loops 3 (6 pts), ternaries 4 (nesting depth added 4). To reduce it, split the body: this score is breadth rather than depth \u2014 many checks laid out side by side rather than nested inside one another, so inverting conditions into early returns has nothing left to flatten. Group the statements between the checks into named steps and move each step into its own function, so the body reads as a short sequence of named stages."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/skills/senior-prompt-engineer/scripts/prompt_optimizer.py"},"region":{"startLine":362}}}],"partialFingerprints":{"codehealthFindingId/v1":"1c0c37114e539dca9035a6c6d25db1b5dc6e90776b8c7fb4cd32ba20ec6a640a"}},{"ruleId":"D2","level":"warning","message":{"text":"rag_evaluator.evaluate_answer_faithfulness (cognitive 17): rag_evaluator.evaluate_answer_faithfulness has cognitive complexity 17 (threshold 15). Drivers by points: if/else 4 (10 pts), ternaries 3 (4 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":"engineering-team/skills/senior-prompt-engineer/scripts/rag_evaluator.py"},"region":{"startLine":206}}}],"partialFingerprints":{"codehealthFindingId/v1":"0f2ed437ccd926f3cd26c4c11bba8843fd91052f2e8ee11e6c1e2f6654d0a363"}},{"ruleId":"D2","level":"warning","message":{"text":"FormatDetector._parse_yaml (cognitive 17): FormatDetector._parse_yaml has cognitive complexity 17 (threshold 15). Drivers by points: if/else 6 (15 pts), boolean chains 1, loops 1 (nesting depth added 9). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/skills/tech-stack-evaluator/scripts/format_detector.py"},"region":{"startLine":129}}}],"partialFingerprints":{"codehealthFindingId/v1":"c3b7ddaa6cfabcd05b984fca230d307ccb8cf4a13ce87348285e25c7b83dc111"}},{"ruleId":"D2","level":"warning","message":{"text":"loop_controller.cmd_verify (cognitive 17): loop_controller.cmd_verify has cognitive complexity 17 (threshold 15). Drivers by points: if/else 9 (11 pts), boolean chains 2, error handling 1 (2 pts), loops 1, ternaries 1 (nesting depth added 3). To reduce it, split the body: most of this score is breadth rather than depth \u2014 checks laid out side by side rather than stacked \u2014 so group the statements between the checks into named steps and move each step into its own function. Some of it IS depth: where a check sits inside another whose only job is to reach it, merge the two into one condition, 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":"engineering/agent-harness/skills/agent-harness/scripts/loop_controller.py"},"region":{"startLine":204}}}],"partialFingerprints":{"codehealthFindingId/v1":"95130a580daba4f9d19fc9952fc1f0c9d1b9c21fde986b7388a4b482ce8767c0"}},{"ruleId":"D2","level":"warning","message":{"text":"dry_run.check_frontmatter (cognitive 17): dry_run.check_frontmatter has cognitive complexity 17 (threshold 15). Drivers by points: if/else 5 (11 pts), loops 4 (6 pts) (nesting depth added 8). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/agenthub/skills/agenthub/scripts/dry_run.py"},"region":{"startLine":118}}}],"partialFingerprints":{"codehealthFindingId/v1":"736f16889100ec01d166d19e3934ea9c0c984fd58130180d621b4aceff22ae17"}},{"ruleId":"D2","level":"warning","message":{"text":"session_manager.cleanup_session (cognitive 17): session_manager.cleanup_session has cognitive complexity 17 (threshold 15). Drivers by points: if/else 5 (14 pts), loops 1 (2 pts), boolean chains 1 (nesting depth added 10). To reduce it, flatten the nesting: this score is depth rather than breadth \u2014 most of its points come from checks stacked inside one another, so the work sits several levels in. Invert each enclosing check into an early exit (a return, or the language\u0027s equivalent) so the happy path stays at one level, and where a level cannot be exited early, lift the block it encloses into its own named function."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/agenthub/skills/agenthub/scripts/session_manager.py"},"region":{"startLine":183}}}],"partialFingerprints":{"codehealthFindingId/v1":"51becd2dbe25b2d8444a1c2a766bdce0664aa7bd6ad08b1d4ceb3c4e3b13d43a"}},{"ruleId":"D2","level":"warning","message":{"text":"setup_experiment.list_evaluators (cognitive 17): setup_experiment.list_evaluators has cognitive complexity 17 (threshold 15). Drivers by points: if/else 4 (11 pts), boolean chains 3, loops 2 (3 pts) (nesting depth added 8). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/autoresearch-agent/skills/autoresearch-agent/scripts/setup_experiment.py"},"region":{"startLine":225}}}],"partialFingerprints":{"codehealthFindingId/v1":"454cdbd71f2e43123ae263897f458bfdc7f20e85579a32a474d2be5c1b812086"}},{"ruleId":"D2","level":"warning","message":{"text":"book_skill_validator.scalar_value (cognitive 17): book_skill_validator.scalar_value has cognitive complexity 17 (threshold 15). Drivers by points: if/else 5 (12 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":"engineering/book-to-skill/skills/book-to-skill/scripts/book_skill_validator.py"},"region":{"startLine":241}}}],"partialFingerprints":{"codehealthFindingId/v1":"1e89eefeb411c321568e200fc56016d4de16ea5194d81355c975a52392500e95"}},{"ruleId":"D2","level":"warning","message":{"text":"values_validator.generate_report (cognitive 17): values_validator.generate_report has cognitive complexity 17 (threshold 15). Drivers by points: if/else 10 (13 pts), loops 2 (3 pts), ternaries 1 (nesting depth added 4). To reduce it, split the body: most of this score is breadth rather than depth \u2014 checks laid out side by side rather than stacked \u2014 so group the statements between the checks into named steps and move each step into its own function. Some of it IS depth: where a check sits inside another whose only job is to reach it, merge the two into one condition."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/helm-chart-builder/skills/helm-chart-builder/scripts/values_validator.py"},"region":{"startLine":331}}}],"partialFingerprints":{"codehealthFindingId/v1":"891ab80c69f39890e83f5ea93f6ff6e3640f7deb0e3aa64c4edcdd9836becf0e"}},{"ruleId":"D2","level":"warning","message":{"text":"human_gate.cmd_close (cognitive 17): human_gate.cmd_close has cognitive complexity 17 (threshold 15). Drivers by points: if/else 7 (8 pts), loops 3 (6 pts), boolean chains 3 (nesting depth added 4). To reduce it, split the body: this score is breadth rather than depth \u2014 many checks laid out side by side rather than nested inside one another, so inverting conditions into early returns has nothing left to flatten. Group the statements between the checks into named steps and move each step into its own function, so the body reads as a short sequence of named stages."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/human-gate/skills/human-gate/scripts/human_gate.py"},"region":{"startLine":431}}}],"partialFingerprints":{"codehealthFindingId/v1":"655bdd872ff9a54f434d9b213a2e529693372da02d50cbdcc595d00cec8fabfe"}},{"ruleId":"D2","level":"warning","message":{"text":"assumption_linter.lint_text (cognitive 17): assumption_linter.lint_text has cognitive complexity 17 (threshold 15). Drivers by points: loops 5 (9 pts), if/else 3 (7 pts), boolean chains 1 (nesting depth added 8). To reduce it, break up the iteration: give each loop body a named function, and split a multi-phase loop into one function per phase so no single body carries the whole pipeline."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/karpathy-coder/skills/karpathy-coder/scripts/assumption_linter.py"},"region":{"startLine":65}}}],"partialFingerprints":{"codehealthFindingId/v1":"965feacd745135f033d24dfcf0eab9368c7f7dfebb53f778ba610c21c183b312"}},{"ruleId":"D2","level":"warning","message":{"text":"operator_capability_audit.render_text (cognitive 17): operator_capability_audit.render_text has cognitive complexity 17 (threshold 15). Drivers by points: if/else 6 (9 pts), loops 4 (6 pts), 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":"engineering/kubernetes-operator/skills/kubernetes-operator/scripts/operator_capability_audit.py"},"region":{"startLine":101}}}],"partialFingerprints":{"codehealthFindingId/v1":"e6682253c1ecf1dd226572736c5199e1c9d7a6fc1cb3976ca89f0fe1244339e1"}},{"ruleId":"D2","level":"warning","message":{"text":"update_index.render_index (cognitive 17): update_index.render_index has cognitive complexity 17 (threshold 15). Drivers by points: if/else 3 (8 pts), ternaries 2 (6 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":"engineering/llm-wiki/skills/llm-wiki/scripts/update_index.py"},"region":{"startLine":104}}}],"partialFingerprints":{"codehealthFindingId/v1":"672059ba4fec92fe46722d5e089b70094338cb159d04df94eeb76b7253976bdb"}},{"ruleId":"D2","level":"warning","message":{"text":"render_report.main (cognitive 17): render_report.main has cognitive complexity 17 (threshold 15). Drivers by points: if/else 7 (10 pts), ternaries 2 (4 pts), error handling 2 (3 pts) (nesting depth added 6). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skill-doctor/skills/skill-doctor/scripts/render_report.py"},"region":{"startLine":214}}}],"partialFingerprints":{"codehealthFindingId/v1":"6e0dffe3a2ddc6b9f58b9b7e269d06f9c4cb141d1c9d39758e258b38fccc5976"}},{"ruleId":"D2","level":"warning","message":{"text":"APILinter._validate_paths_section (cognitive 17): APILinter._validate_paths_section has cognitive complexity 17 (threshold 15). Drivers by points: if/else 8 (14 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":"engineering/skills/api-design-reviewer/scripts/api_linter.py"},"region":{"startLine":236}}}],"partialFingerprints":{"codehealthFindingId/v1":"b86d64c5a6ea4e651a4931cd9f8e29d984866948e1c4353961abc475b709b1d3"}},{"ruleId":"D2","level":"warning","message":{"text":"APIScoringEngine._check_url_structure_consistency (cognitive 17): APIScoringEngine._check_url_structure_consistency has cognitive complexity 17 (threshold 15). Drivers by points: if/else 8 (12 pts), loops 3, boolean chains 2 (nesting depth added 4). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/api-design-reviewer/scripts/api_scorecard.py"},"region":{"startLine":401}}}],"partialFingerprints":{"codehealthFindingId/v1":"2fe181a42bf35cac1aadadfadf4a3e682094de29580c4e12176c78d6f079a5bc"}},{"ruleId":"D2","level":"warning","message":{"text":"APIScoringEngine._check_http_method_consistency (cognitive 17): APIScoringEngine._check_http_method_consistency has cognitive complexity 17 (threshold 15). Drivers by points: if/else 5 (14 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":"engineering/skills/api-design-reviewer/scripts/api_scorecard.py"},"region":{"startLine":453}}}],"partialFingerprints":{"codehealthFindingId/v1":"b21eb5e20c8c3a19c425419212a95e0b2468a92c0850c2aa635990502805ec67"}},{"ruleId":"D2","level":"warning","message":{"text":"SchemaComparator._compare_constraints (cognitive 17): SchemaComparator._compare_constraints has cognitive complexity 17 (threshold 15). Drivers by points: loops 5 (9 pts), if/else 3 (8 pts) (nesting depth added 9). To reduce it, break up the iteration: give each loop body a named function, and split a multi-phase loop into one function per phase so no single body carries the whole pipeline."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/database-designer/migration_generator.py"},"region":{"startLine":312}}}],"partialFingerprints":{"codehealthFindingId/v1":"0f71fc9109b69a71f05b59c226cc6aa5bfcb4fa25e8cac3ab75fddd6b17db9e1"}},{"ruleId":"D2","level":"warning","message":{"text":"LicenseChecker.generate_report (cognitive 17): LicenseChecker.generate_report has cognitive complexity 17 (threshold 15). Drivers by points: loops 5 (8 pts), if/else 5, boolean chains 2, ternaries 1 (2 pts) (nesting depth added 4). 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":"engineering/skills/dependency-auditor/scripts/license_checker.py"},"region":{"startLine":859}}}],"partialFingerprints":{"codehealthFindingId/v1":"5c535c44c802bb15e7dee2847cb1d54a07bdd679376f820cf402e2826618bac8"}},{"ruleId":"D2","level":"warning","message":{"text":"HiringCalibrator._generate_recommendations (cognitive 17): HiringCalibrator._generate_recommendations has cognitive complexity 17 (threshold 15). Drivers by points: if/else 8 (13 pts), loops 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":"engineering/skills/interview-system-designer/hiring_calibrator.py"},"region":{"startLine":870}}}],"partialFingerprints":{"codehealthFindingId/v1":"c9ce393e7c2fe1d54d31bfc84371bed09531c975afb7b19a31291e2bf6c28059"}},{"ruleId":"D2","level":"warning","message":{"text":"loop_designer.format_human_readable (cognitive 17): loop_designer.format_human_readable has cognitive complexity 17 (threshold 15). Drivers by points: loops 9 (12 pts), if/else 3 (5 pts) (nesting depth added 5). To reduce it, break up the iteration: give each loop body a named function, and split a multi-phase loop into one function per phase so no single body carries the whole pipeline."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/interview-system-designer/loop_designer.py"},"region":{"startLine":737}}}],"partialFingerprints":{"codehealthFindingId/v1":"0725bb3279e8718dae1ae971e278c2bbd58d6180cd0b1b0bb8c56109d40086de"}},{"ruleId":"D2","level":"warning","message":{"text":"operator_capability_audit.render_text (cognitive 17): operator_capability_audit.render_text has cognitive complexity 17 (threshold 15). Drivers by points: if/else 6 (9 pts), loops 4 (6 pts), 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":"engineering/skills/kubernetes-operator/scripts/operator_capability_audit.py"},"region":{"startLine":101}}}],"partialFingerprints":{"codehealthFindingId/v1":"c49d7e24eb9194c2d0d4762d15fda950f4c407aabc5c696ca1a42465c7966139"}},{"ruleId":"D2","level":"warning","message":{"text":"SchemaCompatibilityChecker._build_compatibility_report (cognitive 17): SchemaCompatibilityChecker._build_compatibility_report has cognitive complexity 17 (threshold 15). Drivers by points: if/else 9, ternaries 8. 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":"engineering/skills/migration-architect/scripts/compatibility_checker.py"},"region":{"startLine":667}}}],"partialFingerprints":{"codehealthFindingId/v1":"0f7020cde98d62906e2f9c38181e09f60443a7849d87fea64b34c3f8b412c8fd"}},{"ruleId":"D2","level":"warning","message":{"text":"compatibility_checker.main (cognitive 17): compatibility_checker.main has cognitive complexity 17 (threshold 15). Drivers by points: if/else 10 (12 pts), error handling 3, ternaries 1 (2 pts) (nesting depth added 3). To reduce it, split the body: most of this score is breadth rather than depth \u2014 checks laid out side by side rather than stacked \u2014 so group the statements between the checks into named steps and move each step into its own function. Some of it IS depth: where a check sits inside another whose only job is to reach it, merge the two into one condition, and where an else follows a branch that already returns, drop the trailing else and let the rest of the body continue at one level."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/migration-architect/scripts/compatibility_checker.py"},"region":{"startLine":813}}}],"partialFingerprints":{"codehealthFindingId/v1":"214ffc48a8bdac353276d96e39f541b1d80dd6a20dbfd4a238fb3f496957abbe"}},{"ruleId":"D2","level":"warning","message":{"text":"migration_planner.main (cognitive 17): migration_planner.main has cognitive complexity 17 (threshold 15). Drivers by points: if/else 8 (11 pts), error handling 3, 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":"engineering/skills/migration-architect/scripts/migration_planner.py"},"region":{"startLine":593}}}],"partialFingerprints":{"codehealthFindingId/v1":"0eb707d8d9fbdb17d0c82e15a7f41b49bcfff00cd9cbfb37617766aa557269df"}},{"ruleId":"D2","level":"warning","message":{"text":"rotation_planner.print_human (cognitive 17): rotation_planner.print_human has cognitive complexity 17 (threshold 15). Drivers by points: if/else 7 (8 pts), loops 4 (6 pts), ternaries 1 (2 pts), boolean chains 1 (nesting depth added 4). To reduce it, split the body: most of this score is breadth rather than depth \u2014 checks laid out side by side rather than stacked \u2014 so group the statements between the checks into named steps and move each step into its own function. Some of it IS depth: where a check sits inside another whose only job is to reach it, merge the two into one condition."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/secrets-vault-manager/scripts/rotation_planner.py"},"region":{"startLine":181}}}],"partialFingerprints":{"codehealthFindingId/v1":"2df8aeee3086bb504f3aa3301f66930d3d3c4d5a843254b85bf537858d8b10a9"}},{"ruleId":"D2","level":"warning","message":{"text":"QualityReportFormatter.format_human_readable (cognitive 17): QualityReportFormatter.format_human_readable has cognitive complexity 17 (threshold 15). Drivers by points: loops 3 (6 pts), ternaries 2 (6 pts), if/else 3 (4 pts), boolean chains 1 (nesting depth added 8). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/skill-tester/scripts/quality_scorer.py"},"region":{"startLine":1055}}}],"partialFingerprints":{"codehealthFindingId/v1":"279d7ed5e9e1c2b3337dd7617b067cd584a877ec4226bdc395b4ae8fabba746c"}},{"ruleId":"D2","level":"warning","message":{"text":"tc_validator.main (cognitive 17): tc_validator.main has cognitive complexity 17 (threshold 15). Drivers by points: ternaries 6 (10 pts), if/else 3, loops 1 (2 pts), boolean chains 1, 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":"engineering/skills/tc-tracker/scripts/tc_validator.py"},"region":{"startLine":302}}}],"partialFingerprints":{"codehealthFindingId/v1":"c0191b7b9f0322f3693ee462c8b974a0c97ad21a3037eacb00645d7d4da879ba"}},{"ruleId":"D2","level":"warning","message":{"text":"hypothesis_tester.verdict (cognitive 17): hypothesis_tester.verdict has cognitive complexity 17 (threshold 15). Drivers by points: if/else 7 (8 pts), ternaries 4 (6 pts), boolean chains 3 (nesting depth added 3). To reduce it, split the body: most of this score is breadth rather than depth \u2014 checks laid out side by side rather than stacked \u2014 so group the statements between the checks into named steps and move each step into its own function. Some of it IS depth: where a check sits inside another whose only job is to reach it, merge the two into one condition, 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":"engineering/statistical-analyst/skills/statistical-analyst/scripts/hypothesis_tester.py"},"region":{"startLine":339}}}],"partialFingerprints":{"codehealthFindingId/v1":"fbfe3df30967ff4a37d948478ce926d8ccdc5139a74b3a0fdef47adc59e42b0b"}},{"ruleId":"D2","level":"warning","message":{"text":"validate_workflow.check_meta (cognitive 17): validate_workflow.check_meta has cognitive complexity 17 (threshold 15). Drivers by points: if/else 11 (15 pts), 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":"engineering/workflow-builder/skills/workflow-builder/scripts/validate_workflow.py"},"region":{"startLine":87}}}],"partialFingerprints":{"codehealthFindingId/v1":"fab7722a30922ea006171ac0d96d6a95ff3932bf83bd8cd0eba491f6c368fd9f"}},{"ruleId":"D2","level":"warning","message":{"text":"workflow_intake.classify (cognitive 17): workflow_intake.classify has cognitive complexity 17 (threshold 15). Drivers by points: if/else 10 (11 pts), ternaries 2 (4 pts), boolean chains 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":"engineering/workflow-builder/skills/workflow-builder/scripts/workflow_intake.py"},"region":{"startLine":40}}}],"partialFingerprints":{"codehealthFindingId/v1":"65ca267a2b67a8a5b19b8f09b316e51e2b145b889baa355237f38de4893a0039"}},{"ruleId":"D2","level":"warning","message":{"text":"skill_review_checklist_runner.extract_frontmatter_description (cognitive 17): skill_review_checklist_runner.extract_frontmatter_description has cognitive complexity 17 (threshold 15). Drivers by points: if/else 7 (11 pts), loops 2 (4 pts), boolean chains 2 (nesting depth added 6). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/write-a-skill/skills/write-a-skill/scripts/skill_review_checklist_runner.py"},"region":{"startLine":46}}}],"partialFingerprints":{"codehealthFindingId/v1":"d5bbf265b75e2c5afa38cde91e179b6a8376da3f22e8d794dbe24d91cf18e117"}},{"ruleId":"D2","level":"warning","message":{"text":"lint_report.render_text (cognitive 17): lint_report.render_text has cognitive complexity 17 (threshold 15). Drivers by points: if/else 4 (8 pts), loops 3 (6 pts), ternaries 1 (3 pts) (nesting depth added 9). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"finance/skills/stock-analysis/scripts/lint_report.py"},"region":{"startLine":988}}}],"partialFingerprints":{"codehealthFindingId/v1":"fc16f18d8c5856b0e2d7d88beb505b4e0713fa8dc31f8d0eca42c2e79490def3"}},{"ruleId":"D2","level":"warning","message":{"text":"Analysis.section_incremental (cognitive 17): Analysis.section_incremental has cognitive complexity 17 (threshold 15). Drivers by points: if/else 7 (9 pts), boolean chains 4, ternaries 2 (4 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":"finance/skills/stock-analysis/scripts/ratios.py"},"region":{"startLine":1222}}}],"partialFingerprints":{"codehealthFindingId/v1":"0a382b7423cd62e27bb0990a16612076c7460cbe617aceaca7be1f76e1d4b3ed"}},{"ruleId":"D2","level":"warning","message":{"text":"brand_palette_validator.derive_palette (cognitive 17): brand_palette_validator.derive_palette has cognitive complexity 17 (threshold 15). Drivers by points: if/else 7 (9 pts), ternaries 7 (8 pts) (nesting depth added 3). To reduce it, split the body: most of this score is breadth rather than depth \u2014 checks laid out side by side rather than stacked \u2014 so group the statements between the checks into named steps and move each step into its own function. Some of it IS depth: where a check sits inside another whose only job is to reach it, merge the two into one condition, and where an else follows a branch that already returns, drop the trailing else and let the rest of the body continue at one level."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"markdown-html/skills/design-system/scripts/brand_palette_validator.py"},"region":{"startLine":121}}}],"partialFingerprints":{"codehealthFindingId/v1":"18c273bb659dcc742ee7c6bb0c6b80453a96fbf86601e626827f280cab1a04a6"}},{"ruleId":"D2","level":"warning","message":{"text":"roas_calculator.main (cognitive 17): roas_calculator.main has cognitive complexity 17 (threshold 15). Drivers by points: if/else 10 (12 pts), error handling 1 (3 pts), loops 2 (nesting depth added 4). To reduce it, split the body: most of this score is breadth rather than depth \u2014 checks laid out side by side rather than stacked \u2014 so group the statements between the checks into named steps and move each step into its own function. Some of it IS depth: where a check sits inside another whose only job is to reach it, merge the two into one condition, 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":"marketing-skill/skills/paid-ads/scripts/roas_calculator.py"},"region":{"startLine":208}}}],"partialFingerprints":{"codehealthFindingId/v1":"985180b31753cc9e83694a331e8f9d23f96319268faa4830a261ccf578da2d5f"}},{"ruleId":"D2","level":"warning","message":{"text":"prompt_tester.load_payload (cognitive 17): prompt_tester.load_payload has cognitive complexity 17 (threshold 15). Drivers by points: if/else 7 (8 pts), error handling 3 (7 pts), boolean chains 2 (nesting depth added 5). To reduce it, split the body: this score is breadth rather than depth \u2014 many checks laid out side by side rather than nested inside one another, so inverting conditions into early returns has nothing left to flatten. Group the statements between the checks into named steps and move each step into its own function, so the body reads as a short sequence of named stages."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"marketing-skill/skills/prompt-engineer-toolkit/scripts/prompt_tester.py"},"region":{"startLine":66}}}],"partialFingerprints":{"codehealthFindingId/v1":"7faa207b778af0d69d000a2ed957f7eaccb1b6b5452b061473fa8711246bfa01"}},{"ruleId":"D2","level":"warning","message":{"text":"prompt_tester.main (cognitive 17): prompt_tester.main has cognitive complexity 17 (threshold 15). Drivers by points: if/else 5 (6 pts), ternaries 4 (6 pts), loops 2 (3 pts), boolean chains 2 (nesting depth added 4). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"marketing-skill/skills/prompt-engineer-toolkit/scripts/prompt_tester.py"},"region":{"startLine":171}}}],"partialFingerprints":{"codehealthFindingId/v1":"c931af631fe6a13718293cda531db7f94cd83acfe551b09206ce19e6f2db0690"}},{"ruleId":"D2","level":"warning","message":{"text":"social_calendar_generator.pretty_print (cognitive 17): social_calendar_generator.pretty_print has cognitive complexity 17 (threshold 15). Drivers by points: loops 7 (12 pts), if/else 2 (5 pts) (nesting depth added 8). To reduce it, break up the iteration: give each loop body a named function, and split a multi-phase loop into one function per phase so no single body carries the whole pipeline."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"marketing-skill/skills/social-media-manager/scripts/social_calendar_generator.py"},"region":{"startLine":290}}}],"partialFingerprints":{"codehealthFindingId/v1":"de624e8e8a109c0bd87c530e09086debe6c5f5183650ba271294b2d786e972c4"}},{"ruleId":"D2","level":"warning","message":{"text":"repurpose_splitter.split_units (cognitive 17): repurpose_splitter.split_units has cognitive complexity 17 (threshold 15). Drivers by points: if/else 8 (13 pts), loops 2 (3 pts), boolean chains 1 (nesting depth added 6). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"marketing/linkedin/skills/linkedin-content/scripts/repurpose_splitter.py"},"region":{"startLine":83}}}],"partialFingerprints":{"codehealthFindingId/v1":"cb4d7095789bdeba755614a124070c5f751cd405d9b3d66fc11f580985cbaeef"}},{"ruleId":"D2","level":"warning","message":{"text":"outreach_volume_guard.guard (cognitive 17): outreach_volume_guard.guard has cognitive complexity 17 (threshold 15). Drivers by points: if/else 10 (15 pts), boolean chains 1, ternaries 1 (nesting depth added 5). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"marketing/linkedin/skills/linkedin-engagement/scripts/outreach_volume_guard.py"},"region":{"startLine":40}}}],"partialFingerprints":{"codehealthFindingId/v1":"9d27ce135f645d84a1805730d331e5c6be17a4749d0b60e35b1d3a1f6c9b8aba"}},{"ruleId":"D2","level":"warning","message":{"text":"linkedin_goal_router.main (cognitive 17): linkedin_goal_router.main has cognitive complexity 17 (threshold 15). Drivers by points: if/else 11 (15 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":"marketing/linkedin/skills/linkedin-skills/scripts/linkedin_goal_router.py"},"region":{"startLine":113}}}],"partialFingerprints":{"codehealthFindingId/v1":"122093bd44f1e36cc2a4037a310dddc00c0b0aa5d619757b09bf3ca488406f5f"}},{"ruleId":"D2","level":"warning","message":{"text":"metrics_calculator.cohort (cognitive 17): metrics_calculator.cohort has cognitive complexity 17 (threshold 15). Drivers by points: if/else 5 (7 pts), loops 5 (7 pts), ternaries 1 (3 pts) (nesting depth added 6). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"product-team/skills/product-analytics/scripts/metrics_calculator.py"},"region":{"startLine":56}}}],"partialFingerprints":{"codehealthFindingId/v1":"01f46061d67879f3c18a3237249f1fadb7c8c9ca8bbc5f024ebf779dac354885"}},{"ruleId":"D2","level":"warning","message":{"text":"discovery_cadence_tracker.main (cognitive 17): discovery_cadence_tracker.main has cognitive complexity 17 (threshold 15). Drivers by points: if/else 8, ternaries 3 (4 pts), error handling 1 (2 pts), loops 1 (2 pts), boolean chains 1 (nesting depth added 3). To reduce it, split the body: this score is breadth rather than depth \u2014 many checks laid out side by side rather than nested inside one another, so inverting conditions into early returns has nothing left to flatten. Group the statements between the checks into named steps and move each step into its own function, so the body reads as a short sequence of named stages."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"product-team/skills/product-skills/scripts/discovery_cadence_tracker.py"},"region":{"startLine":135}}}],"partialFingerprints":{"codehealthFindingId/v1":"d6f61b6e16cc47e4b8222424935f56d57641ba382b4cfcd66630cac86806297a"}},{"ruleId":"D2","level":"warning","message":{"text":"kb_reader.read_kb (cognitive 17): kb_reader.read_kb has cognitive complexity 17 (threshold 15). Drivers by points: if/else 9 (14 pts), loops 2, ternaries 1 (nesting depth added 5). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"productivity/email/skills/inbox-triage/scripts/kb_reader.py"},"region":{"startLine":179}}}],"partialFingerprints":{"codehealthFindingId/v1":"c035431f10898ddbbf7ca015ecd13c10f5c5c2d3d269a2e2760adecef0c1266b"}},{"ruleId":"D2","level":"warning","message":{"text":"session_end._latest_mtime (cognitive 17): session_end._latest_mtime has cognitive complexity 17 (threshold 15). Drivers by points: if/else 3 (7 pts), error handling 2 (5 pts), loops 2 (3 pts), boolean chains 2 (nesting depth added 8). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"productivity/handoff/hooks/session_end.py"},"region":{"startLine":62}}}],"partialFingerprints":{"codehealthFindingId/v1":"07e62502b3aad4627a37f1229a118a6d818143fc2ef604bf0e0c2bbcbe34187e"}},{"ruleId":"D2","level":"warning","message":{"text":"handoff_self_check.main (cognitive 17): handoff_self_check.main has cognitive complexity 17 (threshold 15). Drivers by points: if/else 9 (10 pts), ternaries 3 (5 pts), boolean chains 1, 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, 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":"productivity/handoff/skills/handoff/scripts/handoff_self_check.py"},"region":{"startLine":290}}}],"partialFingerprints":{"codehealthFindingId/v1":"0b1580b9a77f3b739e581f0f6afa7f6c1024a71af73cdd9118085da1b1bfb906"}},{"ruleId":"D2","level":"warning","message":{"text":"CAPATracker._generate_recommendations (cognitive 17): CAPATracker._generate_recommendations has cognitive complexity 17 (threshold 15). Drivers by points: if/else 14 (16 pts), boolean chains 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, 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":"ra-qm-team/skills/capa-officer/scripts/capa_tracker.py"},"region":{"startLine":190}}}],"partialFingerprints":{"codehealthFindingId/v1":"6475d6a455946adcddce96862593bc52c6ea5c60388f10d1c72b1178d2438967"}},{"ruleId":"D2","level":"warning","message":{"text":"capa_tracker.main (cognitive 17): capa_tracker.main has cognitive complexity 17 (threshold 15). Drivers by points: error handling 3 (9 pts), if/else 6, loops 1 (2 pts) (nesting depth added 7). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"ra-qm-team/skills/capa-officer/scripts/capa_tracker.py"},"region":{"startLine":472}}}],"partialFingerprints":{"codehealthFindingId/v1":"d3be942f4738c253e70ea3cac14e79bafe35cc0e159a136baf2e06f1c662f126"}},{"ruleId":"D2","level":"warning","message":{"text":"gdpr_compliance_checker.generate_recommendations (cognitive 17): gdpr_compliance_checker.generate_recommendations has cognitive complexity 17 (threshold 15). Drivers by points: if/else 6 (13 pts), loops 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":"ra-qm-team/skills/gdpr-dsgvo-expert/scripts/gdpr_compliance_checker.py"},"region":{"startLine":296}}}],"partialFingerprints":{"codehealthFindingId/v1":"14d4d9648418118f633cab2436b961dd812c4d485f45f42d6751a73186599786"}},{"ruleId":"D2","level":"warning","message":{"text":"sync-hermes-skills.sync_skill (cognitive 17): sync-hermes-skills.sync_skill has cognitive complexity 17 (threshold 15). Drivers by points: if/else 7 (9 pts), ternaries 2 (5 pts), error handling 1 (2 pts), boolean chains 1 (nesting depth added 6). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"scripts/sync-hermes-skills.py"},"region":{"startLine":150}}}],"partialFingerprints":{"codehealthFindingId/v1":"db873c2babe819ede4279fcd59bd4dabe468e886d1b36afe36d3265235b8b803"}},{"ruleId":"D2","level":"warning","message":{"text":"generate_reading_list.buildAuditLogSection (cognitive 17): generate_reading_list.buildAuditLogSection has cognitive complexity 17 (threshold 15). Drivers by points: boolean chains 9, if/else 4, loops 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":"research/syllabus/skills/syllabus/scripts/generate_reading_list.js"},"region":{"startLine":263}}}],"partialFingerprints":{"codehealthFindingId/v1":"36eaa959fe7cefdf2977e9cc9b05d14c34fa497d045a7eb14ba881e424133a1c"}},{"ruleId":"D2","level":"warning","message":{"text":"change_announcement_builder.validate_tone (cognitive 16): change_announcement_builder.validate_tone has cognitive complexity 16 (threshold 15). Drivers by points: if/else 6 (10 pts), loops 2 (4 pts), boolean chains 2 (nesting depth added 6). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"business-operations/skills/internal-comms/scripts/change_announcement_builder.py"},"region":{"startLine":120}}}],"partialFingerprints":{"codehealthFindingId/v1":"464415d4d0bb06261cf932484f13c95beb62dcae70e1996cad1f42f3846c0ea0"}},{"ruleId":"D2","level":"warning","message":{"text":"hiring_plan_modeler.assess_risks (cognitive 16): hiring_plan_modeler.assess_risks has cognitive complexity 16 (threshold 15). Drivers by points: if/else 11 (12 pts), ternaries 2 (3 pts), boolean chains 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":"c-level-advisor/skills/chro-advisor/scripts/hiring_plan_modeler.py"},"region":{"startLine":175}}}],"partialFingerprints":{"codehealthFindingId/v1":"777c4b1ceb6ab387f5c7282fa56c6cdab2596905df14ec02e282dc90ff72ef50"}},{"ruleId":"D2","level":"warning","message":{"text":"portfolio_analyzer.investment_posture (cognitive 16): portfolio_analyzer.investment_posture has cognitive complexity 16 (threshold 15). Drivers by points: boolean chains 8, 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":"c-level-advisor/skills/cpo-advisor/scripts/portfolio_analyzer.py"},"region":{"startLine":132}}}],"partialFingerprints":{"codehealthFindingId/v1":"12f9beb6bd74239aa1989aa705e335f431adfc3d9415ae65f53fd19dbf038ad3"}},{"ruleId":"D2","level":"warning","message":{"text":"partner_tier_classifier.classify (cognitive 16): partner_tier_classifier.classify has cognitive complexity 16 (threshold 15). Drivers by points: if/else 5 (8 pts), ternaries 4, boolean chains 3, loops 1 (nesting depth added 3). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"commercial/skills/partnerships-architect/scripts/partner_tier_classifier.py"},"region":{"startLine":346}}}],"partialFingerprints":{"codehealthFindingId/v1":"c9aa4d59f10df18479e2bda805e6220842fec24dbd916eb4b036ab6b1ccc2d85"}},{"ruleId":"D2","level":"warning","message":{"text":"partner_tier_classifier._render_human (cognitive 16): partner_tier_classifier._render_human has cognitive complexity 16 (threshold 15). Drivers by points: loops 6 (10 pts), if/else 3 (4 pts), ternaries 1 (2 pts) (nesting depth added 6). To reduce it, break up the iteration: give each loop body a named function, and split a multi-phase loop into one function per phase so no single body carries the whole pipeline."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"commercial/skills/partnerships-architect/scripts/partner_tier_classifier.py"},"region":{"startLine":453}}}],"partialFingerprints":{"codehealthFindingId/v1":"9b9d8cfc1a48742bb86a583fc58dba8c168629fd31c92afbc6aed0b9f225e572"}},{"ruleId":"D2","level":"warning","message":{"text":"code_quality_checker.analyze_directory (cognitive 16): code_quality_checker.analyze_directory has cognitive complexity 16 (threshold 15). Drivers by points: if/else 5 (9 pts), loops 3 (5 pts), boolean chains 1, ternaries 1 (nesting depth added 6). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/skills/code-reviewer/scripts/code_quality_checker.py"},"region":{"startLine":877}}}],"partialFingerprints":{"codehealthFindingId/v1":"d229ec21e9d3ad0dc2a21c6c9b4cd80292002e970fc3e01c278d39a7cebe0fb2"}},{"ruleId":"D2","level":"warning","message":{"text":"dependency_analyzer.print_human_report (cognitive 16): dependency_analyzer.print_human_report has cognitive complexity 16 (threshold 15). Drivers by points: if/else 7 (8 pts), loops 4 (8 pts) (nesting depth added 5). To reduce it, split the body: this score is breadth rather than depth \u2014 many checks laid out side by side rather than nested inside one another, so inverting conditions into early returns has nothing left to flatten. Group the statements between the checks into named steps and move each step into its own function, so the body reads as a short sequence of named stages."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/skills/senior-architect/scripts/dependency_analyzer.py"},"region":{"startLine":470}}}],"partialFingerprints":{"codehealthFindingId/v1":"3313941ae5461c88b6ff6dc9c399545bf457a24b7e5ad4b7dc410efacfa1fc63"}},{"ruleId":"D2","level":"warning","message":{"text":"backend_decision_engine.score_profile (cognitive 16): backend_decision_engine.score_profile has cognitive complexity 16 (threshold 15). Drivers by points: if/else 10 (11 pts), boolean chains 2, loops 1 (2 pts), ternaries 1 (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":"engineering-team/skills/senior-backend/scripts/backend_decision_engine.py"},"region":{"startLine":109}}}],"partialFingerprints":{"codehealthFindingId/v1":"99a06832041494751640babe18c9692c1fcb2181f4092f69f1d07bd1e6bcd351"}},{"ruleId":"D2","level":"warning","message":{"text":"DatasetAnalyzer._analyze_yolo (cognitive 16): DatasetAnalyzer._analyze_yolo has cognitive complexity 16 (threshold 15). Drivers by points: if/else 5 (9 pts), loops 3 (5 pts), error handling 1 (2 pts) (nesting depth added 7). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/skills/senior-computer-vision/scripts/dataset_pipeline_builder.py"},"region":{"startLine":362}}}],"partialFingerprints":{"codehealthFindingId/v1":"845e5c1fc3aa383b6504907d13b5724d2f3397847d2ecb539a185b8c2ae0cee7"}},{"ruleId":"D2","level":"warning","message":{"text":"GreatExpectationsGenerator._generate_column_expectations (cognitive 16): GreatExpectationsGenerator._generate_column_expectations has cognitive complexity 16 (threshold 15). Drivers by points: if/else 9 (13 pts), ternaries 1 (2 pts), boolean chains 1 (nesting depth added 5). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/skills/senior-data-engineer/scripts/data_quality_validator.py"},"region":{"startLine":753}}}],"partialFingerprints":{"codehealthFindingId/v1":"538767c1421f1a847a661c3c9c67feb8b768262b71e252752577f99b5524e64a"}},{"ruleId":"D2","level":"warning","message":{"text":"pipeline_generator.main (cognitive 16): pipeline_generator.main has cognitive complexity 16 (threshold 15). Drivers by points: if/else 11 (12 pts), boolean chains 4 (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":"engineering-team/skills/senior-devops/scripts/pipeline_generator.py"},"region":{"startLine":174}}}],"partialFingerprints":{"codehealthFindingId/v1":"741c396ce64acfa458322255192f56c4d43d59656d0d8a4eb73a8c8822492ba3"}},{"ruleId":"D2","level":"warning","message":{"text":"bundle_analyzer.check_nextjs_config (cognitive 16): bundle_analyzer.check_nextjs_config has cognitive complexity 16 (threshold 15). Drivers by points: if/else 4 (11 pts), error handling 1 (3 pts), boolean chains 1, loops 1 (nesting depth added 9). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/skills/senior-frontend/scripts/bundle_analyzer.py"},"region":{"startLine":180}}}],"partialFingerprints":{"codehealthFindingId/v1":"dfa79c58a5530c0e1867465e17736b196a718d573b91144c01114e3cfd8c863d"}},{"ruleId":"D2","level":"warning","message":{"text":"frontend_scaffolder.main (cognitive 16): frontend_scaffolder.main has cognitive complexity 16 (threshold 15). Drivers by points: if/else 8 (12 pts), loops 2 (4 pts) (nesting depth added 6). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/skills/senior-frontend/scripts/frontend_scaffolder.py"},"region":{"startLine":919}}}],"partialFingerprints":{"codehealthFindingId/v1":"de7dfeffa89213951ff7e09dc01f4f2091382a1560a0cef9f442a9380cc8411e"}},{"ruleId":"D2","level":"warning","message":{"text":"VulnerabilityAssessor.scan_go (cognitive 16): VulnerabilityAssessor.scan_go has cognitive complexity 16 (threshold 15). Drivers by points: if/else 6 (12 pts), boolean chains 2, error handling 1, loops 1 (nesting depth added 6). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/skills/senior-secops/scripts/vulnerability_assessor.py"},"region":{"startLine":343}}}],"partialFingerprints":{"codehealthFindingId/v1":"a81c0278aebe2019c29f6e48e6a37552c58a78bb9a1e95b3dce2572d97d4f543"}},{"ruleId":"D2","level":"warning","message":{"text":"threat_modeler.format_threat_report (cognitive 16): threat_modeler.format_threat_report has cognitive complexity 16 (threshold 15). Drivers by points: if/else 6 (8 pts), loops 3 (8 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":"engineering-team/skills/senior-security/scripts/threat_modeler.py"},"region":{"startLine":419}}}],"partialFingerprints":{"codehealthFindingId/v1":"09cc66e9553517ede2956e04a9546fbc6c036ffe6235a8ab9366e917645d7a01"}},{"ruleId":"D2","level":"warning","message":{"text":"CoverageAnalyzer._parse_xml (cognitive 16): CoverageAnalyzer._parse_xml has cognitive complexity 16 (threshold 15). Drivers by points: if/else 2 (9 pts), loops 3 (6 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":"engineering-team/skills/tdd-guide/scripts/coverage_analyzer.py"},"region":{"startLine":153}}}],"partialFingerprints":{"codehealthFindingId/v1":"64c1d74e963ff5af88629671e583fea6614b34770771158c65f6d09205f3eb67"}},{"ruleId":"D2","level":"warning","message":{"text":"CoverageAnalyzer.calculate_summary (cognitive 16): CoverageAnalyzer.calculate_summary has cognitive complexity 16 (threshold 15). Drivers by points: if/else 3 (9 pts), loops 4 (7 pts) (nesting depth added 9). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/skills/tdd-guide/scripts/coverage_analyzer.py"},"region":{"startLine":194}}}],"partialFingerprints":{"codehealthFindingId/v1":"a8faf7d26a8ccb6a6a8702f1932ed4be41ef8ede2e0b207bbace3e99848781ea"}},{"ruleId":"D2","level":"warning","message":{"text":"FrameworkAdapter.detect_framework (cognitive 16): FrameworkAdapter.detect_framework has cognitive complexity 16 (threshold 15). Drivers by points: boolean chains 9, 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":"engineering-team/skills/tdd-guide/scripts/framework_adapter.py"},"region":{"startLine":390}}}],"partialFingerprints":{"codehealthFindingId/v1":"cd5414aeef46a3272513ecc0e71c5845e10bcaad1d6134a3144a1db40febe3d8"}},{"ruleId":"D2","level":"warning","message":{"text":"book_skill_validator.check_budgets (cognitive 16): book_skill_validator.check_budgets has cognitive complexity 16 (threshold 15). Drivers by points: if/else 4 (8 pts), ternaries 2 (6 pts), loops 2 (nesting depth added 8). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/book-to-skill/skills/book-to-skill/scripts/book_skill_validator.py"},"region":{"startLine":408}}}],"partialFingerprints":{"codehealthFindingId/v1":"40c1ea332bbfb86769cf9b5235857366ee46a6c4333f531ca5b0fa3b876b9f5b"}},{"ruleId":"D2","level":"warning","message":{"text":"dependencies.offer_dependency_install (cognitive 16): dependencies.offer_dependency_install has cognitive complexity 16 (threshold 15). Drivers by points: if/else 12 (15 pts), boolean chains 1 (nesting depth added 3). To reduce it, split the body: most of this score is breadth rather than depth \u2014 checks laid out side by side rather than stacked \u2014 so group the statements between the checks into named steps and move each step into its own function. Some of it IS depth: where a check sits inside another whose only job is to reach it, merge the two into one condition, and where an else follows a branch that already returns, drop the trailing else and let the rest of the body continue at one level."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/book-to-skill/skills/book-to-skill/scripts/book_to_skill/dependencies.py"},"region":{"startLine":136}}}],"partialFingerprints":{"codehealthFindingId/v1":"c8bde5976467cf16982a1f4ad4451f7424c1aec9c6a13caf4c75bceda7e28c9b"}},{"ruleId":"D2","level":"warning","message":{"text":"forgetting_policy_linter.lint (cognitive 16): forgetting_policy_linter.lint has cognitive complexity 16 (threshold 15). Drivers by points: boolean chains 8, if/else 6, ternaries 1 (2 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":"engineering/memory-engineering/skills/memory-engineering/scripts/forgetting_policy_linter.py"},"region":{"startLine":221}}}],"partialFingerprints":{"codehealthFindingId/v1":"9930378ad8158e241b05b8354a60190cd49094dda911b094d43a68d18339a1cb"}},{"ruleId":"D2","level":"warning","message":{"text":"APIScoringEngine._check_sensitive_data_handling (cognitive 16): APIScoringEngine._check_sensitive_data_handling has cognitive complexity 16 (threshold 15). Drivers by points: if/else 4 (12 pts), loops 2 (3 pts), boolean chains 1 (nesting depth added 9). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/api-design-reviewer/scripts/api_scorecard.py"},"region":{"startLine":968}}}],"partialFingerprints":{"codehealthFindingId/v1":"aca34d090324e08fde976e92eae512d37d7c0aa325940328f3ddd6dfe6da7e36"}},{"ruleId":"D2","level":"warning","message":{"text":"anti_detection_checker.format_text_report (cognitive 16): anti_detection_checker.format_text_report has cognitive complexity 16 (threshold 15). Drivers by points: if/else 6 (9 pts), loops 3 (4 pts), ternaries 1 (3 pts) (nesting depth added 6). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/browser-automation/scripts/anti_detection_checker.py"},"region":{"startLine":392}}}],"partialFingerprints":{"codehealthFindingId/v1":"a5de080b9927d0abdbc07ec398db73b0845b15f6197a7d46f79135fa3c4c856f"}},{"ruleId":"D2","level":"warning","message":{"text":"form_automation_builder.build_form_script (cognitive 16): form_automation_builder.build_form_script has cognitive complexity 16 (threshold 15). Drivers by points: if/else 9 (12 pts), loops 3, boolean chains 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":"engineering/skills/browser-automation/scripts/form_automation_builder.py"},"region":{"startLine":95}}}],"partialFingerprints":{"codehealthFindingId/v1":"ebc6efb38dc5d8478fe3c6a353a53900043854ce29429f9232a4eed57ff2c8be"}},{"ruleId":"D2","level":"warning","message":{"text":"worktree_cleanup.main (cognitive 16): worktree_cleanup.main has cognitive complexity 16 (threshold 15). Drivers by points: if/else 5 (8 pts), error handling 3 (5 pts), boolean chains 2, loops 1 (nesting depth added 5). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/git-worktree-manager/scripts/worktree_cleanup.py"},"region":{"startLine":127}}}],"partialFingerprints":{"codehealthFindingId/v1":"bafd807ca538841aacab6e1e9b45f370f05e9a9f310a07ac26e1ea18385eccf8"}},{"ruleId":"D2","level":"warning","message":{"text":"InterviewLoopDesigner._design_rounds (cognitive 16): InterviewLoopDesigner._design_rounds has cognitive complexity 16 (threshold 15). Drivers by points: if/else 7 (12 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":"engineering/skills/interview-system-designer/loop_designer.py"},"region":{"startLine":336}}}],"partialFingerprints":{"codehealthFindingId/v1":"7d8c6654ecf777b70ceed0c8f3205b58e7d5236431fb12aac635a185d8e394d8"}},{"ruleId":"D2","level":"warning","message":{"text":"QualityScorer._score_help_accessibility (cognitive 16): QualityScorer._score_help_accessibility has cognitive complexity 16 (threshold 15). Drivers by points: if/else 5 (9 pts), error handling 1 (3 pts), boolean chains 2, loops 1 (2 pts) (nesting depth added 7). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/skill-tester/scripts/quality_scorer.py"},"region":{"startLine":912}}}],"partialFingerprints":{"codehealthFindingId/v1":"feb5c282d45a2e2e7cf81ecd6cbfe275ace755ceacc0df95ebee309fe0771db8"}},{"ruleId":"D2","level":"warning","message":{"text":"ScriptTester._find_external_imports (cognitive 16): ScriptTester._find_external_imports has cognitive complexity 16 (threshold 15). Drivers by points: if/else 3 (9 pts), loops 2 (4 pts), boolean chains 3 (nesting depth added 8). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/skill-tester/scripts/script_tester.py"},"region":{"startLine":272}}}],"partialFingerprints":{"codehealthFindingId/v1":"00b1910df1bbb73c7e33c1f77075350cf9732b830e1bf1b7553168e228fced5c"}},{"ruleId":"D2","level":"warning","message":{"text":"SkillValidator._validate_frontmatter (cognitive 16): SkillValidator._validate_frontmatter has cognitive complexity 16 (threshold 15). Drivers by points: if/else 7 (12 pts), error handling 1 (2 pts), loops 1 (2 pts) (nesting depth added 7). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/skill-tester/scripts/skill_validator.py"},"region":{"startLine":263}}}],"partialFingerprints":{"codehealthFindingId/v1":"9c77dfb959523bb61a9d7609e5195155ffc6184d0d88951823ce6d372d5e4734"}},{"ruleId":"D2","level":"warning","message":{"text":"SkillValidator._validate_script_features (cognitive 16): SkillValidator._validate_script_features has cognitive complexity 16 (threshold 15). Drivers by points: if/else 6 (8 pts), ternaries 4 (8 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":"engineering/skills/skill-tester/scripts/skill_validator.py"},"region":{"startLine":462}}}],"partialFingerprints":{"codehealthFindingId/v1":"cc9f4417d9756ab024d1ab5254176086700b393b16f943780552f46c9850d835"}},{"ruleId":"D2","level":"warning","message":{"text":"schema_explorer.generate_md (cognitive 16): schema_explorer.generate_md has cognitive complexity 16 (threshold 15). Drivers by points: if/else 4 (8 pts), loops 3 (4 pts), ternaries 2 (3 pts), boolean chains 1 (nesting depth added 6). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/sql-database-assistant/scripts/schema_explorer.py"},"region":{"startLine":197}}}],"partialFingerprints":{"codehealthFindingId/v1":"8b377fac6c75952de2d8657756b28d78bfc2b8bfec11c12c5ebc605432b5a636"}},{"ruleId":"D2","level":"warning","message":{"text":"PaymentProcessor.validate_credit_card (cognitive 16): PaymentProcessor.validate_credit_card has cognitive complexity 16 (threshold 15). Drivers by points: if/else 8 (11 pts), boolean chains 4, 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":"engineering/skills/tech-debt-tracker/assets/sample_codebase/src/payment_processor.py"},"region":{"startLine":251}}}],"partialFingerprints":{"codehealthFindingId/v1":"5b9ae81ad266de70f85623887a82ef5466174153a9437a808a258486a4d62a23"}},{"ruleId":"D2","level":"warning","message":{"text":"debt_prioritizer.main (cognitive 16): debt_prioritizer.main has cognitive complexity 16 (threshold 15). Drivers by points: if/else 7 (9 pts), ternaries 2 (6 pts), error handling 1 (nesting depth added 6). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/tech-debt-tracker/scripts/debt_prioritizer.py"},"region":{"startLine":801}}}],"partialFingerprints":{"codehealthFindingId/v1":"395b8e9760b98588b66ca3c9d03c90b80e4a9775c2e745a9fb95f9ad07fd606d"}},{"ruleId":"D2","level":"warning","message":{"text":"html_renderer.main (cognitive 16): html_renderer.main has cognitive complexity 16 (threshold 15). Drivers by points: if/else 7 (8 pts), ternaries 3 (6 pts), boolean chains 2 (nesting depth added 4). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"markdown-html/skills/md-document/scripts/html_renderer.py"},"region":{"startLine":569}}}],"partialFingerprints":{"codehealthFindingId/v1":"6ec339dd39b96e3fe96aaa7af1fb4ee8973f58e725d159db55d9e8b66c3f3e7f"}},{"ruleId":"D2","level":"warning","message":{"text":"interactivity_injector.main (cognitive 16): interactivity_injector.main has cognitive complexity 16 (threshold 15). Drivers by points: if/else 13 (15 pts), boolean chains 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, 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":"markdown-html/skills/md-document/scripts/interactivity_injector.py"},"region":{"startLine":231}}}],"partialFingerprints":{"codehealthFindingId/v1":"3b73c9dc0fca0469c027e9f6e8d34b24c73faf3bcae980801457e86da7eb3f2e"}},{"ruleId":"D2","level":"warning","message":{"text":"ReviewAnalyzer.identify_issues (cognitive 16): ReviewAnalyzer.identify_issues has cognitive complexity 16 (threshold 15). Drivers by points: if/else 3 (7 pts), loops 4 (6 pts), ternaries 1 (3 pts) (nesting depth added 8). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"marketing-skill/skills/app-store-optimization/scripts/review_analyzer.py"},"region":{"startLine":175}}}],"partialFingerprints":{"codehealthFindingId/v1":"a322fd0750ea741471d869e5e5b6949f7acd8f10a1c5db899857892bc5e0bbba"}},{"ruleId":"D2","level":"warning","message":{"text":"email_sequence_analyzer.analyze_subject_line (cognitive 16): email_sequence_analyzer.analyze_subject_line has cognitive complexity 16 (threshold 15). Drivers by points: if/else 12 (13 pts), boolean chains 3 (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":"marketing-skill/skills/cold-email/scripts/email_sequence_analyzer.py"},"region":{"startLine":170}}}],"partialFingerprints":{"codehealthFindingId/v1":"07f482561de6272bcab78ef0856aca85258da309638cf22525fed2105ac65448"}},{"ruleId":"D2","level":"warning","message":{"text":"email_sequence_analyzer.analyze_body (cognitive 16): email_sequence_analyzer.analyze_body has cognitive complexity 16 (threshold 15). Drivers by points: if/else 10 (12 pts), loops 3, 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":"marketing-skill/skills/cold-email/scripts/email_sequence_analyzer.py"},"region":{"startLine":224}}}],"partialFingerprints":{"codehealthFindingId/v1":"457e479551dd1353ef505942fa5db9cad648d1a7d6b575993d9cc92fd783ad11"}},{"ruleId":"D2","level":"warning","message":{"text":"content_scorer.score_structure (cognitive 16): content_scorer.score_structure has cognitive complexity 16 (threshold 15). Drivers by points: if/else 11 (13 pts), boolean chains 2, 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, 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":"marketing-skill/skills/content-production/scripts/content_scorer.py"},"region":{"startLine":199}}}],"partialFingerprints":{"codehealthFindingId/v1":"89a42d9cbcd159a506c1cd811d4be90a34e24b7a4f79926970a5dd4c7c7615dc"}},{"ruleId":"D2","level":"warning","message":{"text":"readability_scorer.main (cognitive 16): readability_scorer.main has cognitive complexity 16 (threshold 15). Drivers by points: if/else 9 (13 pts), ternaries 3 (nesting depth added 4). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"marketing-skill/skills/copy-editing/scripts/readability_scorer.py"},"region":{"startLine":200}}}],"partialFingerprints":{"codehealthFindingId/v1":"b79d2883050c32cb09debc241e9854a109b2c817fc52712417d3fb31a4f613bc"}},{"ruleId":"D2","level":"warning","message":{"text":"FormAnalyzer.handle_starttag (cognitive 16): FormAnalyzer.handle_starttag has cognitive complexity 16 (threshold 15). Drivers by points: if/else 4 (9 pts), boolean chains 4, loops 1 (3 pts) (nesting depth added 7). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"marketing-skill/skills/form-cro/scripts/form_field_analyzer.py"},"region":{"startLine":31}}}],"partialFingerprints":{"codehealthFindingId/v1":"5e343af4206eac9b1e45cfb79d59b4c5681568bcb839b544bb019450b3454c5a"}},{"ruleId":"D2","level":"warning","message":{"text":"nap_checker.compare_nap (cognitive 16): nap_checker.compare_nap has cognitive complexity 16 (threshold 15). Drivers by points: if/else 5 (8 pts), boolean chains 6, loops 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":"marketing-skill/skills/local-seo-manager/scripts/nap_checker.py"},"region":{"startLine":107}}}],"partialFingerprints":{"codehealthFindingId/v1":"3edc707ca107caabcef75ca87c1e0bbd8c839c429d30aef46973ce8060f9e8fe"}},{"ruleId":"D2","level":"warning","message":{"text":"CROParser.handle_starttag (cognitive 16): CROParser.handle_starttag has cognitive complexity 16 (threshold 15). Drivers by points: if/else 10 (14 pts), boolean chains 2 (nesting depth added 4). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"marketing-skill/skills/page-cro/scripts/conversion_audit.py"},"region":{"startLine":62}}}],"partialFingerprints":{"codehealthFindingId/v1":"2d84cc7b4cfd938a8bd22a3387e827ca8f45204e9a03b458939354589626c67a"}},{"ruleId":"D2","level":"warning","message":{"text":"roas_calculator._recommendations (cognitive 16): roas_calculator._recommendations has cognitive complexity 16 (threshold 15). Drivers by points: if/else 9 (12 pts), boolean chains 4 (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":"marketing-skill/skills/paid-ads/scripts/roas_calculator.py"},"region":{"startLine":147}}}],"partialFingerprints":{"codehealthFindingId/v1":"110b162950a88f0176de23be57b05829a817671edf62ac65700d866f72bdf022"}},{"ruleId":"D2","level":"warning","message":{"text":"post_performance_analyzer.analyse (cognitive 16): post_performance_analyzer.analyse has cognitive complexity 16 (threshold 15). Drivers by points: if/else 6 (8 pts), ternaries 3 (4 pts), boolean chains 2, 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":"marketing/linkedin/skills/linkedin-analytics/scripts/post_performance_analyzer.py"},"region":{"startLine":111}}}],"partialFingerprints":{"codehealthFindingId/v1":"4fbc01a74b969b3aae1e3c1ff676e456b7b57d6273fcca9265d17b6ffd8881ca"}},{"ruleId":"D2","level":"warning","message":{"text":"format_picker.pick (cognitive 16): format_picker.pick has cognitive complexity 16 (threshold 15). Drivers by points: if/else 8 (11 pts), boolean chains 4, 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":"marketing/linkedin/skills/linkedin-content/scripts/format_picker.py"},"region":{"startLine":133}}}],"partialFingerprints":{"codehealthFindingId/v1":"3a63378e12cc9195187965c78719d55334bf1ccea7c9e52c7b1d785d30e01aa3"}},{"ruleId":"D2","level":"warning","message":{"text":"metrics_calculator.funnel (cognitive 16): metrics_calculator.funnel has cognitive complexity 16 (threshold 15). Drivers by points: if/else 6 (8 pts), loops 3 (4 pts), ternaries 2 (4 pts) (nesting depth added 5). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"product-team/skills/product-analytics/scripts/metrics_calculator.py"},"region":{"startLine":99}}}],"partialFingerprints":{"codehealthFindingId/v1":"2b4450788a94684c435e170d80e93fd6040f5be60c40b31ff0ba91996c7a7a4a"}},{"ruleId":"D2","level":"warning","message":{"text":"InterviewAnalyzer._extract_key_quotes (cognitive 16): InterviewAnalyzer._extract_key_quotes 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":"product-team/skills/product-manager-toolkit/scripts/customer_interview_analyzer.py"},"region":{"startLine":191}}}],"partialFingerprints":{"codehealthFindingId/v1":"4d3ff68aee0671f8ee6a848b82525b2febd272dd59e732ccada80e732d77a5ab"}},{"ruleId":"D2","level":"warning","message":{"text":"okr_cascade_generator.main (cognitive 16): okr_cascade_generator.main has cognitive complexity 16 (threshold 15). Drivers by points: if/else 7 (8 pts), ternaries 2 (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":"product-team/skills/product-strategist/scripts/okr_cascade_generator.py"},"region":{"startLine":470}}}],"partialFingerprints":{"codehealthFindingId/v1":"f7ab2a03e0648d97d48b369d18bf4d94b44e06413eef14bb9efe9807a9a3bfb0"}},{"ruleId":"D2","level":"warning","message":{"text":"skill_recommender._collect_skills (cognitive 16): skill_recommender._collect_skills has cognitive complexity 16 (threshold 15). Drivers by points: if/else 4 (7 pts), boolean chains 3, error handling 1 (3 pts), loops 2 (3 pts) (nesting depth added 6). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"productivity/handoff/skills/handoff/scripts/skill_recommender.py"},"region":{"startLine":98}}}],"partialFingerprints":{"codehealthFindingId/v1":"37e72432f859df3d5b1de8e4f8ac8199345d916ab9868d73e2acfcc9847bf98e"}},{"ruleId":"D2","level":"warning","message":{"text":"weekly_review_gate.render_human (cognitive 16): weekly_review_gate.render_human has cognitive complexity 16 (threshold 15). Drivers by points: ternaries 3 (7 pts), if/else 3 (5 pts), 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":"productivity/weekly-review/skills/weekly-review/scripts/weekly_review_gate.py"},"region":{"startLine":159}}}],"partialFingerprints":{"codehealthFindingId/v1":"fc51f78258517c6cf35779f33458465c715cfc8cad2f50cc3ace49d00972a233"}},{"ruleId":"D2","level":"warning","message":{"text":"risk_matrix_analyzer.build_risk_matrix (cognitive 16): risk_matrix_analyzer.build_risk_matrix has cognitive complexity 16 (threshold 15). Drivers by points: if/else 7 (8 pts), boolean chains 4, loops 3 (4 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":"project-management/skills/senior-pm/scripts/risk_matrix_analyzer.py"},"region":{"startLine":228}}}],"partialFingerprints":{"codehealthFindingId/v1":"85a956e90566aad748e4bac0cdb047115add5086e814ecc7819edd5e4e60be1b"}},{"ruleId":"D2","level":"warning","message":{"text":"aims_audit_scheduler.render_text (cognitive 16): aims_audit_scheduler.render_text has cognitive complexity 16 (threshold 15). Drivers by points: if/else 5 (9 pts), loops 2 (3 pts), 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":"ra-qm-team/compliance-team-iso42001/skills/iso42001-specialist/scripts/aims_audit_scheduler.py"},"region":{"startLine":179}}}],"partialFingerprints":{"codehealthFindingId/v1":"f36b8f28858646e20405f33eea1ad6bf561807cb8c45006d5676649e3ab82bb6"}},{"ruleId":"D2","level":"warning","message":{"text":"compliance_checker.check_compliance (cognitive 16): compliance_checker.check_compliance has cognitive complexity 16 (threshold 15). Drivers by points: if/else 5 (11 pts), loops 2 (3 pts), boolean chains 1, ternaries 1 (nesting depth added 7). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"ra-qm-team/skills/information-security-manager-iso27001/scripts/compliance_checker.py"},"region":{"startLine":145}}}],"partialFingerprints":{"codehealthFindingId/v1":"f34c62a649f8f7ee3185be318ea27732c6cf463ea711d1a4d2ac8a9d765c8623"}},{"ruleId":"D2","level":"warning","message":{"text":"aims_audit_scheduler.render_text (cognitive 16): aims_audit_scheduler.render_text has cognitive complexity 16 (threshold 15). Drivers by points: if/else 5 (9 pts), loops 2 (3 pts), 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":"ra-qm-team/skills/iso42001-specialist/scripts/aims_audit_scheduler.py"},"region":{"startLine":179}}}],"partialFingerprints":{"codehealthFindingId/v1":"755560369a7da65bc1f8c3ef524a552a3896a48b04af7401209183978a84c77d"}},{"ruleId":"D2","level":"warning","message":{"text":"QMSEffectivenessMonitor.detect_alerts (cognitive 16): QMSEffectivenessMonitor.detect_alerts has cognitive complexity 16 (threshold 15). Drivers by points: if/else 3 (6 pts), ternaries 2 (6 pts), boolean chains 3, loops 1 (nesting depth added 7). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"ra-qm-team/skills/quality-manager-qmr/scripts/quality_effectiveness_monitor.py"},"region":{"startLine":158}}}],"partialFingerprints":{"codehealthFindingId/v1":"a8af465469da495edebf5cc90461c41c4765d7c443ae6e556006ffc59570018f"}},{"ruleId":"D2","level":"warning","message":{"text":"QMSEffectivenessMonitor.analyze (cognitive 16): QMSEffectivenessMonitor.analyze has cognitive complexity 16 (threshold 15). Drivers by points: if/else 5 (10 pts), boolean chains 3, loops 2, ternaries 1 (nesting depth added 5). To reduce it, split the body into named stages: move each independent step or branch into its own named function so the body reads as a short sequence of named calls rather than one long body."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"ra-qm-team/skills/quality-manager-qmr/scripts/quality_effectiveness_monitor.py"},"region":{"startLine":318}}}],"partialFingerprints":{"codehealthFindingId/v1":"e6de3df4128b4e7e74577704437a17748707303a0fac4ea38229ae939c270dae"}},{"ruleId":"D2","level":"warning","message":{"text":"derive_counters.canonical_walk (cognitive 16): derive_counters.canonical_walk has cognitive complexity 16 (threshold 15). Drivers by points: if/else 3 (10 pts), loops 2 (3 pts), error handling 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":"scripts/derive_counters.py"},"region":{"startLine":59}}}],"partialFingerprints":{"codehealthFindingId/v1":"a29fd551d93ac7afad6a0cebdfd80d48f6107ebd25354bb2d57364fb35018676"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: scripts/ratios.py: FileTooLong \u2014 1881 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 1381 over it, 3.76\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":"finance/skills/stock-analysis/scripts/ratios.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"82eebf235e88501171e9302d84c01214dd603922dbc651978eb1c9d2101876a6"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: scripts/score.py: FileTooLong \u2014 1159 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 659 over it, 2.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":"finance/skills/stock-analysis/scripts/score.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"259c40114ac37bf7821e722a1a92ae10a0743edd92df31f78eee46c02a9da07f"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: scripts/etl_performance_optimizer.py: FileTooLong \u2014 1117 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 617 over it, 2.23\u00D7 the bar. To reduce it, split the file along the responsibilities already in it: move each cohesive group of declarations into its own sibling file in the same module or package, so no one file has to be read whole to change one of them."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/skills/senior-data-engineer/scripts/etl_performance_optimizer.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"7281f5309a327bfa12892195c20f602fb289acbabbcd31fa6b3c3d72fb3c043b"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: scripts/data_quality_validator.py: FileTooLong \u2014 1078 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 578 over it, 2.16\u00D7 the bar. To reduce it, split the file along the responsibilities already in it: move each cohesive group of declarations into its own sibling file in the same module or package, so no one file has to be read whole to change one of them."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/skills/senior-data-engineer/scripts/data_quality_validator.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"69e739075c54f4e3b533fc2d388bda372d2ec5718f0fe92541babf10ffd80898"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: scripts/api_scorecard.py: FileTooLong \u2014 1057 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 557 over it, 2.11\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":"engineering/skills/api-design-reviewer/scripts/api_scorecard.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"58b73066412df26a3b7d0521bfa8de4fc83877745fc30a890e826584aef5972f"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: scripts/pir_generator.py: FileTooLong \u2014 1002 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 502 over it, 2.00\u00D7 the bar. To reduce it, split the file along the responsibilities already in it: move each cohesive group of declarations into its own sibling file in the same module or package, so no one file has to be read whole to change one of them."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/skills/incident-commander/scripts/pir_generator.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"8097a28b5b444cdd34365ad44502aed163fe60c8db8e4c78a3f325e2d5d4d194"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: scripts/verify_data.py: FileTooLong \u2014 967 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 467 over it, 1.93\u00D7 the bar. To reduce it, split the file along the responsibilities already in it: move each cohesive group of declarations into its own sibling file in the same module or package, so no one file has to be read whole to change one of them."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"finance/skills/stock-analysis/scripts/verify_data.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"9db05121f31a3f12f58eca4ff1d8dcfb775697868d44b2901a6d3442fd80a1d1"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: scripts/ship_gate_scanner.py: FileTooLong \u2014 960 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 460 over it, 1.92\u00D7 the bar. To reduce it, split the file along the responsibilities already in it: move each cohesive group of declarations into its own sibling file in the same module or package, so no one file has to be read whole to change one of them."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/ship-gate/scripts/ship_gate_scanner.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"695221ef83d42d28a437f0b4fdabe05a20f7a7da24d3e8244f443a5f73cbf003"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: scripts/dataset_pipeline_builder.py: FileTooLong \u2014 955 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 455 over it, 1.91\u00D7 the bar. To reduce it, split the file along the responsibilities already in it: move each cohesive group of declarations into its own sibling file in the same module or package, so no one file has to be read whole to change one of them."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/skills/senior-computer-vision/scripts/dataset_pipeline_builder.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"cd14bd21e439f41947659ad3fff8c58335eed5b383236a1fa20085281c453293"}},{"ruleId":"D3","level":"warning","message":{"text":"FunctionTooLong: full-page-screenshot.captureFullPage: FunctionTooLong \u2014 captureFullPage runs 177 significant lines (blank, comment-only and punctuation-only lines excluded) in one body. The bar is 100 significant lines; this is 77 over it, 1.77\u00D7 the bar. This is length, not branching: a long straight-line body scores low on complexity and is still read whole to change any part of it, so the complexity numbers beside this row neither confirm nor excuse it. To reduce it, extract each cohesive step of the body \u2014 the runs of statements that work on the same values and would earn the same name \u2014 into its own named unit, and have this one call them in order."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/full-page-screenshot/scripts/full-page-screenshot.mjs"},"region":{"startLine":221}}}],"partialFingerprints":{"codehealthFindingId/v1":"79feef13938f11aa434929784d90ce13ae93f72efd1c3cd375893395f91aac23"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: agent-designer/agent_evaluator.py: FileTooLong \u2014 883 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 383 over it, 1.77\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":"engineering/skills/agent-designer/agent_evaluator.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"ec560aff81a511f6bf1e5e7f1a6d2e0bfd4e96d36f285944ce345a7d0f170eb3"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: interview-system-designer/hiring_calibrator.py: FileTooLong \u2014 883 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 383 over it, 1.77\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":"engineering/skills/interview-system-designer/hiring_calibrator.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"3d699416f834a40b0505ca5a07023c68ef0b2a10dfe5508a9f4a855dfe07af52"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: database-designer/migration_generator.py: FileTooLong \u2014 838 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 338 over it, 1.68\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":"engineering/skills/database-designer/migration_generator.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"7f65d8cf710be4939b034397eddd54b6350f8bbfecc4bb3ddc16ca74508a5bb2"}},{"ruleId":"D3","level":"warning","message":{"text":"FunctionTooLong: full-page-screenshot.captureViaProxy: FunctionTooLong \u2014 captureViaProxy runs 167 significant lines (blank, comment-only and punctuation-only lines excluded) in one body. The bar is 100 significant lines; this is 67 over it, 1.67\u00D7 the bar. This is length, not branching: a long straight-line body scores low on complexity and is still read whole to change any part of it, so the complexity numbers beside this row neither confirm nor excuse it. To reduce it, extract each cohesive step of the body \u2014 the runs of statements that work on the same values and would earn the same name \u2014 into its own named unit, and have this one call them in order."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/full-page-screenshot/scripts/full-page-screenshot.mjs"},"region":{"startLine":646}}}],"partialFingerprints":{"codehealthFindingId/v1":"a01dc00e46da25d70860d0d1b92edb00bf02b0f7bd7e41da311e37bae7fbdc7d"}},{"ruleId":"D3","level":"warning","message":{"text":"TooManyMethods: PIRGenerator: TooManyMethods \u2014 50 methods. The bar is 30 methods; this is 20 over it, 1.67\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":"engineering-team/skills/incident-commander/scripts/pir_generator.py"},"region":{"startLine":27}}}],"partialFingerprints":{"codehealthFindingId/v1":"c66e4147bd3e85ec5a11d3b9dc48302e4350edd2e7468b2cda73c634acb82d45"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: scripts/rollback_generator.py: FileTooLong \u2014 799 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 299 over it, 1.60\u00D7 the bar. To reduce it, split the file along the responsibilities already in it: move each cohesive group of declarations into its own sibling file in the same module or package, so no one file has to be read whole to change one of them."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/migration-architect/scripts/rollback_generator.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"802a99a14a6362642dc998c285d6d324c040ebbf4a6c38b26618c4c193bc12fb"}},{"ruleId":"D3","level":"warning","message":{"text":"TooManyMethods: Analysis: TooManyMethods \u2014 46 methods. The bar is 30 methods; this is 16 over it, 1.53\u00D7 the bar. To reduce it, group the members that share the same data into a smaller type of their own and delegate to it, so no single type carries every responsibility."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"finance/skills/stock-analysis/scripts/ratios.py"},"region":{"startLine":736}}}],"partialFingerprints":{"codehealthFindingId/v1":"3944f20c76be1dd56670fdd05e974336efa33555fdd564208002ad57c3d3c3fc"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: scripts/ops_efficiency_analyzer.py: FileTooLong \u2014 752 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 252 over it, 1.50\u00D7 the bar. To reduce it, split the file along the responsibilities already in it: move each cohesive group of declarations into its own sibling file in the same module or package, so no one file has to be read whole to change one of them."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"c-level-advisor/skills/coo-advisor/scripts/ops_efficiency_analyzer.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"6e4ba70d87ec6c750eaaa27cbb43ffb087e50ce153c938ac8ab2657d3fca394f"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: scripts/compliance_checker.py: FileTooLong \u2014 746 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 246 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":"engineering-team/skills/senior-secops/scripts/compliance_checker.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"d52846f4af214881385fa1d0029bc5dfff08c511f32031144df1c1a5963471af"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: scripts/skill_security_auditor.py: FileTooLong \u2014 745 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 245 over it, 1.49\u00D7 the bar. To reduce it, split the file along the responsibilities already in it: move each cohesive group of declarations into its own sibling file in the same module or package, so no one file has to be read whole to change one of them."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/skill-security-auditor/scripts/skill_security_auditor.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"0895ff116199bf082eccc44b51425398d0bc3f10be4714137d2a2c9d04446c89"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: scripts/okr_tracker.py: FileTooLong \u2014 743 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 243 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":"c-level-advisor/skills/coo-advisor/scripts/okr_tracker.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"32e08eb14b7584a410688f92040ef1d8a92938f8485daacd0d139895398ac468"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: scripts/lint_report.py: FileTooLong \u2014 739 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 239 over it, 1.48\u00D7 the bar. To reduce it, split the file along the responsibilities already in it: move each cohesive group of declarations into its own sibling file in the same module or package, so no one file has to be read whole to change one of them."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"finance/skills/stock-analysis/scripts/lint_report.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"53c3e77af9beafb0475d2af0793915f8689d40f18f25f1bcdf95c2ea5bc25acf"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: scripts/breaking_change_detector.py: FileTooLong \u2014 736 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 236 over it, 1.47\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":"engineering/skills/api-design-reviewer/scripts/breaking_change_detector.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"7084c500fcc827783763cdcf488d2114f74d986c8f06dcdade57444019192f25"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: interview-system-designer/question_bank_generator.py: FileTooLong \u2014 734 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 234 over it, 1.47\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":"engineering/skills/interview-system-designer/question_bank_generator.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"553b0c794d699624df018bac890a8668b42d22c0f2159464584ce00ffa4716e8"}},{"ruleId":"D3","level":"warning","message":{"text":"TooManyMethods: APIScoringEngine: TooManyMethods \u2014 44 methods. The bar is 30 methods; this is 14 over it, 1.47\u00D7 the bar. To reduce it, group the members that share the same data into a smaller type of their own and delegate to it, so no single type carries every responsibility."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/api-design-reviewer/scripts/api_scorecard.py"},"region":{"startLine":117}}}],"partialFingerprints":{"codehealthFindingId/v1":"127c542f18142be3a55c29159e30b61ccfbf3a34397d665cfa7a93cd0f528f8e"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: scripts/quality_scorer.py: FileTooLong \u2014 717 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 217 over it, 1.43\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":"engineering/skills/skill-tester/scripts/quality_scorer.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"9c9ea903829f5cb902fafbdac6f039612fc46091eca631c2d3a3c93659a35bab"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: scripts/dashboard_generator.py: FileTooLong \u2014 710 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 210 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":"engineering/skills/observability-designer/scripts/dashboard_generator.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"f37ad787c55d2c06d9b01021fb44347c93dd3113f7aaa33e0cb638f533c156b6"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: scripts/code_quality_checker.py: FileTooLong \u2014 701 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 201 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":"engineering-team/skills/code-reviewer/scripts/code_quality_checker.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"0105e46272caeb6503bf9517ba0bb4fc11c70260b493518eed711f35d63bc78e"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: database-designer/schema_analyzer.py: FileTooLong \u2014 692 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 192 over it, 1.38\u00D7 the bar. To reduce it, split the file along the responsibilities already in it: move each cohesive group of declarations into its own sibling file in the same module or package, so no one file has to be read whole to change one of them."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/database-designer/schema_analyzer.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"83787039c0cb6dc6aebc21aecf7139a1112b56fed5ae569ae7c4525e1a9b984c"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: scripts/license_checker.py: FileTooLong \u2014 687 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 187 over it, 1.37\u00D7 the bar. To reduce it, split the file along the responsibilities already in it: move each cohesive group of declarations into its own sibling file in the same module or package, so no one file has to be read whole to change one of them."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/dependency-auditor/scripts/license_checker.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"34f481ea7548cce324581e5451bb7a69233a8fdf7cdcfb985937ccd936ecaecf"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: agent-designer/tool_schema_generator.py: FileTooLong \u2014 680 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 180 over it, 1.36\u00D7 the bar. To reduce it, split the file along the responsibilities already in it: move each cohesive group of declarations into its own sibling file in the same module or package, so no one file has to be read whole to change one of them."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/agent-designer/tool_schema_generator.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"ea22c3b8a300a37b93d1fcd47c6ec9e07d8f134714604433373ba15407a6a502"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: scripts/cloud_posture_check.py: FileTooLong \u2014 678 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 178 over it, 1.36\u00D7 the bar. To reduce it, split the file along the responsibilities already in it: move each cohesive group of declarations into its own sibling file in the same module or package, so no one file has to be read whole to change one of them."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/skills/cloud-security/scripts/cloud_posture_check.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"8b268a28b546bf54ce4a5ea50153a7aa1035141c89e6d94a6a28b1ea4f1ebab6"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: scripts/upgrade_planner.py: FileTooLong \u2014 677 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 177 over it, 1.35\u00D7 the bar. To reduce it, split the file along the responsibilities already in it: move each cohesive group of declarations into its own sibling file in the same module or package, so no one file has to be read whole to change one of them."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/dependency-auditor/scripts/upgrade_planner.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"868d235aaa87bd53d94de98d416820388deb7aa448b0cdacb0cce3c62b0e6441"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: scripts/alert_optimizer.py: FileTooLong \u2014 668 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 168 over it, 1.34\u00D7 the bar. To reduce it, split the file along the responsibilities already in it: move each cohesive group of declarations into its own sibling file in the same module or package, so no one file has to be read whole to change one of them."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/observability-designer/scripts/alert_optimizer.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"33ccd1d540ef878546c9e8dd169e651f0ca89763b6d42741c469da93528496e7"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: scripts/debt_dashboard.py: FileTooLong \u2014 664 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 164 over it, 1.33\u00D7 the bar. To reduce it, split the file along the responsibilities already in it: move each cohesive group of declarations into its own sibling file in the same module or package, so no one file has to be read whole to change one of them."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/tech-debt-tracker/scripts/debt_dashboard.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"ce5484cbce344f74719414002960e89e94b0e78deea0166c156e194538dc9a18"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: interview-system-designer/loop_designer.py: FileTooLong \u2014 652 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 152 over it, 1.30\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":"engineering/skills/interview-system-designer/loop_designer.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"1dcb845c2843303dffb85cdc5fd9561291782d1d9c11f4dcaa64fdab7bc049da"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: agent-designer/agent_planner.py: FileTooLong \u2014 646 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 146 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":"engineering/skills/agent-designer/agent_planner.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"bbe21417def811495c1943dbdd15645d6c0cd6a98d6bdc8bf92b668bb86eac76"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: scripts/full-page-screenshot.mjs: FileTooLong \u2014 644 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 144 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":"engineering/skills/full-page-screenshot/scripts/full-page-screenshot.mjs"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"36ecf596b403782bb5fb959ebefb2018d652d20d65eaf2e750feb9a1eedb4b66"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: database-designer/index_optimizer.py: FileTooLong \u2014 639 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 139 over it, 1.28\u00D7 the bar. To reduce it, split the file along the responsibilities already in it: move each cohesive group of declarations into its own sibling file in the same module or package, so no one file has to be read whole to change one of them."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/database-designer/index_optimizer.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"bd5e7a9efce4e61bf37c8fc9a590131ac152bd0a8b25602f75e3bff5b0764000"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: scripts/compatibility_checker.py: FileTooLong \u2014 633 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 133 over it, 1.27\u00D7 the bar. To reduce it, split the file along the responsibilities already in it: move each cohesive group of declarations into its own sibling file in the same module or package, so no one file has to be read whole to change one of them."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/migration-architect/scripts/compatibility_checker.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"86fd2fb26d1448f56e64bc2d18cc0bd62bb9d7966ada8a8ba302225767dad129"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: scripts/valuation.py: FileTooLong \u2014 625 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 125 over it, 1.25\u00D7 the bar. To reduce it, split the file along the responsibilities already in it: move each cohesive group of declarations into its own sibling file in the same module or package, so no one file has to be read whole to change one of them."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"finance/skills/stock-analysis/scripts/valuation.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"6132ef854edc2fe509c6c74b072fa657b524bc4f022f977c35b73fc777c2a843"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: scripts/collect_sessions.py: FileTooLong \u2014 621 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 121 over it, 1.24\u00D7 the bar. To reduce it, split the file along the responsibilities already in it: move each cohesive group of declarations into its own sibling file in the same module or package, so no one file has to be read whole to change one of them."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skill-doctor/skills/skill-doctor/scripts/collect_sessions.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"4f3aefeb11776c947f7457f349ec347e94079faa4cdd5561e5795f7ce049727f"}},{"ruleId":"D3","level":"warning","message":{"text":"TooManyMethods: SchemaAnalyzer: TooManyMethods \u2014 37 methods. The bar is 30 methods; this is 7 over it, 1.23\u00D7 the bar. To reduce it, group the members that share the same data into a smaller type of their own and delegate to it, so no single type carries every responsibility."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/database-designer/schema_analyzer.py"},"region":{"startLine":103}}}],"partialFingerprints":{"codehealthFindingId/v1":"3a31598e09ae95ae4debe48c153b1e9c2bea3be822c9a228ec142e1944a4daf2"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: scripts/qms_audit_checklist.py: FileTooLong \u2014 615 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 115 over it, 1.23\u00D7 the bar. To reduce it, split the file along the responsibilities already in it: move each cohesive group of declarations into its own sibling file in the same module or package, so no one file has to be read whole to change one of them."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"ra-qm-team/skills/quality-manager-qms-iso13485/scripts/qms_audit_checklist.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"80849837dcc9c3a86e21a4ec320231737f9696147af742d014af25c7d965f2cd"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: scripts/architecture_designer.py: FileTooLong \u2014 605 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 105 over it, 1.21\u00D7 the bar. To reduce it, split the file along the responsibilities already in it: move each cohesive group of declarations into its own sibling file in the same module or package, so no one file has to be read whole to change one of them."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/skills/gcp-cloud-architect/scripts/architecture_designer.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"a35b293123fadb1d9228f49d2f69dd4cd595b1bc0d6de7bf36f9ddfb29e57fd8"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: scripts/architecture_designer.py: FileTooLong \u2014 604 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 104 over it, 1.21\u00D7 the bar. To reduce it, split the file along the responsibilities already in it: move each cohesive group of declarations into its own sibling file in the same module or package, so no one file has to be read whole to change one of them."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/skills/aws-solution-architect/scripts/architecture_designer.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"14633d12690c1353678201e25fdab276bac73b54f01e54e5c7fd7015b17a9578"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: scripts/compliance_tracker.py: FileTooLong \u2014 600 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 100 over it, 1.20\u00D7 the bar. To reduce it, split the file along the responsibilities already in it: move each cohesive group of declarations into its own sibling file in the same module or package, so no one file has to be read whole to change one of them."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"c-level-advisor/skills/ciso-advisor/scripts/compliance_tracker.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"48b35b6386467ec5ee0d985f8bedfa6a733cd9124bafca85cf4c756b5e1444a3"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: scripts/timeline_reconstructor.py: FileTooLong \u2014 600 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 100 over it, 1.20\u00D7 the bar. To reduce it, split the file along the responsibilities already in it: move each cohesive group of declarations into its own sibling file in the same module or package, so no one file has to be read whole to change one of them."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/skills/incident-commander/scripts/timeline_reconstructor.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"87d94ac100debd1bf9eacf421fffca3564509c29d696596649d08107ef326d64"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: scripts/retrospective_analyzer.py: FileTooLong \u2014 600 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 100 over it, 1.20\u00D7 the bar. To reduce it, split the file along the responsibilities already in it: move each cohesive group of declarations into its own sibling file in the same module or package, so no one file has to be read whole to change one of them."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"project-management/skills/scrum-master/scripts/retrospective_analyzer.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"1c17dd3fceea23bb8a2fb101fb284b77e63ad79b3a52ad827ec336944442dba3"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: scripts/api_linter.py: FileTooLong \u2014 591 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 91 over it, 1.18\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":"engineering/skills/api-design-reviewer/scripts/api_linter.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"99e422263b6b10edfbad11cbf9284048afde87442511979390f060435fa9611d"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: scripts/debt_prioritizer.py: FileTooLong \u2014 553 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 53 over it, 1.11\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":"engineering/skills/tech-debt-tracker/scripts/debt_prioritizer.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"c64787d572b3fbe4b1f2a8be6d5600238626fa64a18b9914a0635aa89b68767f"}},{"ruleId":"D3","level":"warning","message":{"text":"TooManyMethods: AlertOptimizer: TooManyMethods \u2014 33 methods. The bar is 30 methods; this is 3 over it, 1.10\u00D7 the bar. To reduce it, group the members that share the same data into a smaller type of their own and delegate to it, so no single type carries every responsibility."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/observability-designer/scripts/alert_optimizer.py"},"region":{"startLine":28}}}],"partialFingerprints":{"codehealthFindingId/v1":"e6a931dcb1645eaea98c15d779c6790639f1997f7289d8594fdb3cbf2428347e"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: scripts/incident_classifier.py: FileTooLong \u2014 550 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 50 over it, 1.10\u00D7 the bar. To reduce it, split the file along the responsibilities already in it: move each cohesive group of declarations into its own sibling file in the same module or package, so no one file has to be read whole to change one of them."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/skills/incident-commander/scripts/incident_classifier.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"d7d60a819433613336452b0773c89bca70fe04f04b236e3e6bbbe67bd41a6447"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: scripts/resource_capacity_planner.py: FileTooLong \u2014 549 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 49 over it, 1.10\u00D7 the bar. To reduce it, split the file along the responsibilities already in it: move each cohesive group of declarations into its own sibling file in the same module or package, so no one file has to be read whole to change one of them."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"project-management/skills/senior-pm/scripts/resource_capacity_planner.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"244b67d8595f2895b010389cc591a6e064fe770f9ed5320b1d3a0c6895b2e9e1"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: scripts/coverage_analyzer.py: FileTooLong \u2014 542 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 42 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":"engineering-team/skills/senior-qa/scripts/coverage_analyzer.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"e3675860a1be29200fb676523ba012ad7e794c4e556ccd6b1bc3f2151d8a152b"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: scripts/codebase_analyzer.py: FileTooLong \u2014 540 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 40 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":"product-team/code-to-prd/skills/code-to-prd/scripts/codebase_analyzer.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"cabae08d04321ce3392d1762d32154149d428933a2130fcdb14c699046d6e075"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: scripts/dep_scanner.py: FileTooLong \u2014 534 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 34 over it, 1.07\u00D7 the bar. To reduce it, split the file along the responsibilities already in it: move each cohesive group of declarations into its own sibling file in the same module or package, so no one file has to be read whole to change one of them."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/dependency-auditor/scripts/dep_scanner.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"90c2659ddd3ca2a36347d561701076c91052cb1380201d631992d3943ffcd6cf"}},{"ruleId":"D3","level":"warning","message":{"text":"TooManyMethods: ComplianceChecker: TooManyMethods \u2014 32 methods. The bar is 30 methods; this is 2 over it, 1.07\u00D7 the bar. To reduce it, group the members that share the same data into a smaller type of their own and delegate to it, so no single type carries every responsibility."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/skills/senior-secops/scripts/compliance_checker.py"},"region":{"startLine":51}}}],"partialFingerprints":{"codehealthFindingId/v1":"42c618c06989bb2e9a0c401c8406d6f0cf16a029fe6ca2b2da79840fa703376f"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: scripts/risk_quantifier.py: FileTooLong \u2014 523 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 23 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":"c-level-advisor/skills/ciso-advisor/scripts/risk_quantifier.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"80c3e67eaf7fd2090da2a35c097afe5547c0040a9cf611d4c9cd6b425b8642d9"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: rag-architect/chunking_optimizer.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":"engineering/skills/rag-architect/chunking_optimizer.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"0d55f270b420050b410c2a9be149948a28e49cdda84b23407f73b169816820cb"}},{"ruleId":"D3","level":"warning","message":{"text":"TooManyMethods: UpgradePlanner: TooManyMethods \u2014 31 methods. The bar is 30 methods; this is 1 over it, 1.03\u00D7 the bar. To reduce it, group the members that share the same data into a smaller type of their own and delegate to it, so no single type carries every responsibility."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/dependency-auditor/scripts/upgrade_planner.py"},"region":{"startLine":89}}}],"partialFingerprints":{"codehealthFindingId/v1":"ef749f48df697287a4db138600b54dcad5c45d5323becce74f3db4bba60e6c6c"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: scripts/a11y_scanner.py: FileTooLong \u2014 508 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 8 over it, 1.02\u00D7 the bar. To reduce it, split the file along the responsibilities already in it: move each cohesive group of declarations into its own sibling file in the same module or package, so no one file has to be read whole to change one of them."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/a11y-audit/skills/a11y-audit/scripts/a11y_scanner.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"22c4cb27db87b8f672fbe73452458bf25adffe0a3175149bfbbd2ed210c796cd"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: scripts/churn_analyzer.py: FileTooLong \u2014 507 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 7 over it, 1.01\u00D7 the bar. To reduce it, split the file along the responsibilities already in it: move each cohesive group of declarations into its own sibling file in the same module or package, so no one file has to be read whole to change one of them."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"c-level-advisor/skills/cro-advisor/scripts/churn_analyzer.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"447b03397381f0aa09175d8bb7d8985786ffdfb2dff8dd715fba10a8605d0b32"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: scripts/review_page_builder.py: FileTooLong \u2014 506 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 6 over it, 1.01\u00D7 the bar. To reduce it, split the file along the responsibilities already in it: move each cohesive group of declarations into its own sibling file in the same module or package, so no one file has to be read whole to change one of them."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/human-gate/skills/human-gate/scripts/review_page_builder.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"d49f476e35fc82743ec271606e76caa808980e617fc528e7ab18e735b35f1b51"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: scripts/project_health_dashboard.py: FileTooLong \u2014 506 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 6 over it, 1.01\u00D7 the bar. To reduce it, split the file along the responsibilities already in it: move each cohesive group of declarations into its own sibling file in the same module or package, so no one file has to be read whole to change one of them."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"project-management/skills/senior-pm/scripts/project_health_dashboard.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"f42f2600a04322f17357a70dea84dea7b87e6732057bc2e39b79ac87c17c3452"}},{"ruleId":"D4","level":"warning","message":{"text":"Near-duplicate member family (42 members, 23 shared lines): c-level-advisor/chief-ai-officer-advisor/skills/chief-ai-officer-advisor/scripts/ai_cost_economics.py:315-346 | c-level-advisor/chief-ai-officer-advisor/skills/chief-ai-officer-advisor/scripts/ai_risk_classifier.py:443-474 | c-level-advisor/chief-ai-officer-advisor/skills/chief-ai-officer-advisor/scripts/model_buildvsbuy_calculator.py:329-360 | c-level-advisor/chief-customer-officer-advisor/skills/chief-customer-officer-advisor/scripts/cs_coverage_calculator.py:245-276 | c-level-advisor/chief-customer-officer-advisor/skills/chief-customer-officer-advisor/scripts/customer_segmentation_designer.py:315-346 | c-level-advisor/chief-customer-officer-advisor/skills/chief-customer-officer-advisor/scripts/retention_decomposition_analyzer.py:277-308 | c-level-advisor/chief-data-officer-advisor/skills/chief-data-officer-advisor/scripts/ai_training_data_audit.py:403-443 | c-level-advisor/chief-data-officer-advisor/skills/chief-data-officer-advisor/scripts/data_asset_valuator.py:338-369 | c-level-advisor/chief-data-officer-advisor/skills/chief-data-officer-advisor/scripts/data_product_strategy_picker.py:322-353 | c-level-advisor/general-counsel-advisor/skills/general-counsel-advisor/scripts/term_sheet_analyzer.py:372-408 | c-level-advisor/skills/chief-ai-officer-advisor/scripts/ai_cost_economics.py:315-346 | c-level-advisor/skills/chief-ai-officer-advisor/scripts/ai_risk_classifier.py:443-474 | c-level-advisor/skills/chief-ai-officer-advisor/scripts/model_buildvsbuy_calculator.py:329-360 | c-level-advisor/skills/chief-customer-officer-advisor/scripts/cs_coverage_calculator.py:245-276 | c-level-advisor/skills/chief-customer-officer-advisor/scripts/customer_segmentation_designer.py:315-346 | c-level-advisor/skills/chief-customer-officer-advisor/scripts/retention_decomposition_analyzer.py:277-308 | c-level-advisor/skills/chief-data-officer-advisor/scripts/ai_training_data_audit.py:403-443 | c-level-advisor/skills/chief-data-officer-advisor/scripts/data_asset_valuator.py:338-369 | c-level-advisor/skills/chief-data-officer-advisor/scripts/data_product_strategy_picker.py:322-353 | c-level-advisor/skills/general-counsel-advisor/scripts/term_sheet_analyzer.py:372-408 | c-level-advisor/skills/vpe-advisor/scripts/delivery_throughput_analyzer.py:242-273 | c-level-advisor/skills/vpe-advisor/scripts/eng_hiring_funnel_calculator.py:247-278 | c-level-advisor/skills/vpe-advisor/scripts/eng_team_structure_designer.py:243-274 | c-level-advisor/vpe-advisor/skills/vpe-advisor/scripts/delivery_throughput_analyzer.py:242-273 | c-level-advisor/vpe-advisor/skills/vpe-advisor/scripts/eng_hiring_funnel_calculator.py:247-278 | c-level-advisor/vpe-advisor/skills/vpe-advisor/scripts/eng_team_structure_designer.py:243-274 | compliance-os/skills/compliance-os/scripts/audit_simulator.py:363-392 | compliance-os/skills/compliance-os/scripts/cross_framework_mapper.py:397-426 | compliance-os/skills/compliance-os/scripts/evidence_pool_generator.py:321-350 | compliance-os/skills/compliance-os/scripts/framework_selector.py:281-310 | ra-qm-team/compliance-team-eu-ai-act/skills/eu-ai-act-specialist/scripts/ai_act_obligation_tracker.py:240-269 | ra-qm-team/compliance-team-eu-ai-act/skills/eu-ai-act-specialist/scripts/ai_system_risk_classifier.py:305-334 | ra-qm-team/compliance-team-eu-ai-act/skills/eu-ai-act-specialist/scripts/conformity_assessment_planner.py:276-305 | ra-qm-team/compliance-team-iso42001/skills/iso42001-specialist/scripts/ai_risk_register_builder.py:224-253 | ra-qm-team/compliance-team-iso42001/skills/iso42001-specialist/scripts/aims_audit_scheduler.py:229-258 | ra-qm-team/compliance-team-iso42001/skills/iso42001-specialist/scripts/aims_gap_analyzer.py:218-247 | ra-qm-team/skills/eu-ai-act-specialist/scripts/ai_act_obligation_tracker.py:240-269 | ra-qm-team/skills/eu-ai-act-specialist/scripts/ai_system_risk_classifier.py:305-334 | ra-qm-team/skills/eu-ai-act-specialist/scripts/conformity_assessment_planner.py:276-305 | ra-qm-team/skills/iso42001-specialist/scripts/ai_risk_register_builder.py:224-253 | ra-qm-team/skills/iso42001-specialist/scripts/aims_audit_scheduler.py:229-258 | ra-qm-team/skills/iso42001-specialist/scripts/aims_gap_analyzer.py:218-247 \u2014 These 42 members are variants of one another: a block of 23 lines reported below appears in every one of them, and the pairwise near-duplicate rows they would otherwise produce are collapsed into this row. Read them as one construct written 42 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 42 times."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"c-level-advisor/chief-ai-officer-advisor/skills/chief-ai-officer-advisor/scripts/ai_cost_economics.py"},"region":{"startLine":315}}}],"partialFingerprints":{"codehealthFindingId/v1":"847b62d648f9db356d0ca3b7cc1dbf6deb9df8f9679100f58acb2c7d875b8573"}},{"ruleId":"D4","level":"warning","message":{"text":"Near-duplicate member family (6 members, 39 shared lines): project-management/skills/scrum-master/scripts/retrospective_analyzer.py:867-910 | project-management/skills/scrum-master/scripts/sprint_health_scorer.py:697-740 | project-management/skills/scrum-master/scripts/velocity_analyzer.py:533-576 | project-management/skills/senior-pm/scripts/project_health_dashboard.py:767-810 | project-management/skills/senior-pm/scripts/resource_capacity_planner.py:799-842 | project-management/skills/senior-pm/scripts/risk_matrix_analyzer.py:651-694 \u2014 These 6 members are variants of one another: a block of 39 lines reported below appears in every one of them, and the pairwise near-duplicate rows they would otherwise produce are collapsed into this row. Read them as one construct written 6 times. The repair is at the members\u0027 grain \u2014 factor the shared implementation out once and have all of them call it with their differences as parameters or as an injected step, or, where the difference is systematic, generate them from one template. Extracting the individual blocks below is not the same fix: it leaves every body in place and the next edit still has to be made 6 times."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"project-management/skills/scrum-master/scripts/retrospective_analyzer.py"},"region":{"startLine":867}}}],"partialFingerprints":{"codehealthFindingId/v1":"9f96c1fddd1a487547e4a65642515affe541b12a4aff58610bdc0941df19abc3"}},{"ruleId":"D4","level":"warning","message":{"text":"Near-duplicate member family (4 members, 16 shared lines): marketing/linkedin/skills/linkedin-engagement/scripts/outreach_message_builder.py:212-254 | marketing/linkedin/skills/linkedin-profile/scripts/about_section_builder.py:226-264 | marketing/linkedin/skills/linkedin-profile/scripts/profile_completeness_auditor.py:236-265 | marketing/linkedin/skills/linkedin-strategy/scripts/positioning_brief.py:250-298 \u2014 These 4 members are variants of one another: a block of 16 lines reported below appears in every one of them, and the pairwise near-duplicate rows they would otherwise produce are collapsed into this row. Read them as one construct written 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":"marketing/linkedin/skills/linkedin-engagement/scripts/outreach_message_builder.py"},"region":{"startLine":212}}}],"partialFingerprints":{"codehealthFindingId/v1":"29221546f1a1dbf0ab962a3c96178a1e1c18483a7313ab5516c904d52a68380f"}},{"ruleId":"D4","level":"warning","message":{"text":"Near-duplicate member family (4 members, 15 shared lines): ra-qm-team/compliance-team-eu-ai-act/skills/eu-ai-act-specialist/scripts/conformity_assessment_planner.py:236-272 | ra-qm-team/compliance-team-iso42001/skills/iso42001-specialist/scripts/ai_risk_register_builder.py:185-220 | ra-qm-team/skills/eu-ai-act-specialist/scripts/conformity_assessment_planner.py:236-272 | ra-qm-team/skills/iso42001-specialist/scripts/ai_risk_register_builder.py:185-220 \u2014 These 4 members are variants of one another: a block of 15 lines reported below appears in every one of them, and the pairwise near-duplicate rows they would otherwise produce are collapsed into this row. Read them as one construct written 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":"ra-qm-team/compliance-team-eu-ai-act/skills/eu-ai-act-specialist/scripts/conformity_assessment_planner.py"},"region":{"startLine":236}}}],"partialFingerprints":{"codehealthFindingId/v1":"f30d0cdd8fd16d32176b58ea64fbc9d390bcbdff39a6b65317a5b6bdebcdf1c2"}},{"ruleId":"D4","level":"warning","message":{"text":"Near-duplicate member pair (68 shared lines): engineering-team/skills/senior-architect/scripts/dependency_analyzer.py:521-611 | engineering-team/skills/senior-architect/scripts/project_architect.py:648-745 \u2014 These two members are variants of one another: 68 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":"engineering-team/skills/senior-architect/scripts/dependency_analyzer.py"},"region":{"startLine":521}}}],"partialFingerprints":{"codehealthFindingId/v1":"e06f36ee41e212ac17409f437f8a3fcd0ad9942fc4e1299c01c90fc2076c249d"}},{"ruleId":"D4","level":"warning","message":{"text":"Near-duplicate member pair (64 shared lines): c-level-advisor/chief-ai-officer-advisor/skills/chief-ai-officer-advisor/scripts/ai_risk_classifier.py:359-434 | c-level-advisor/skills/chief-ai-officer-advisor/scripts/ai_risk_classifier.py:359-434 \u2014 These two members are variants of one another: 64 of their lines are already reported as duplicated blocks below, spread through both bodies rather than gathered into one. Read them as a single construct written twice. The repair is at the members\u0027 grain \u2014 factor the shared pipeline into one implementation the two call with their differences as parameters or as an injected step, or, where the difference is systematic (sync against async, one transport against another), generate one from the other. Extracting the individual blocks below is not the same fix: it leaves the two bodies in place and the next edit still has to be made twice."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"c-level-advisor/chief-ai-officer-advisor/skills/chief-ai-officer-advisor/scripts/ai_risk_classifier.py"},"region":{"startLine":359}}}],"partialFingerprints":{"codehealthFindingId/v1":"c67b82605e01de948a67debdc58493dc6b61edd20d6faba210cd0cd5dbb67940"}},{"ruleId":"D4","level":"warning","message":{"text":"Near-duplicate member pair (52 shared lines): engineering/skills/agent-designer/agent_evaluator.py:1115-1214 | engineering/skills/agent-designer/tool_schema_generator.py:853-974 \u2014 These two members are variants of one another: 52 of their lines are already reported as duplicated blocks below, spread through both bodies rather than gathered into one. Read them as a single construct written twice. The repair is at the members\u0027 grain \u2014 factor the shared pipeline into one implementation the two call with their differences as parameters or as an injected step, or, where the difference is systematic (sync against async, one transport against another), generate one from the other. Extracting the individual blocks below is not the same fix: it leaves the two bodies in place and the next edit still has to be made twice."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/agent-designer/agent_evaluator.py"},"region":{"startLine":1115}}}],"partialFingerprints":{"codehealthFindingId/v1":"096fd70969e948b4c1542a89ece3ee02b31ade259561a563b2215ae615ca47ac"}},{"ruleId":"D4","level":"warning","message":{"text":"Near-duplicate member pair (51 shared lines): c-level-advisor/chief-data-officer-advisor/skills/chief-data-officer-advisor/scripts/data_asset_valuator.py:274-329 | c-level-advisor/skills/chief-data-officer-advisor/scripts/data_asset_valuator.py:274-329 \u2014 These two members are variants of one another: 51 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":"c-level-advisor/chief-data-officer-advisor/skills/chief-data-officer-advisor/scripts/data_asset_valuator.py"},"region":{"startLine":274}}}],"partialFingerprints":{"codehealthFindingId/v1":"c3daadd575d52b75afd4c477007dd1a788d06d1e6e3c11503fba2f923eaa102a"}},{"ruleId":"D4","level":"warning","message":{"text":"Near-duplicate member pair (51 shared lines): scripts/sync-hermes-skills.py:206-276 | scripts/sync-vibe-skills.py:247-332 \u2014 These two members are variants of one another: 51 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":"scripts/sync-hermes-skills.py"},"region":{"startLine":206}}}],"partialFingerprints":{"codehealthFindingId/v1":"5bff14566c5089fe48248144f5545110471a2648a26d1cf90db62b60612cd219"}},{"ruleId":"D4","level":"warning","message":{"text":"Near-duplicate member pair (48 shared lines): c-level-advisor/chief-customer-officer-advisor/skills/chief-customer-officer-advisor/scripts/customer_segmentation_designer.py:260-311 | c-level-advisor/skills/chief-customer-officer-advisor/scripts/customer_segmentation_designer.py:260-311 \u2014 These two members are variants of one another: 48 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":"c-level-advisor/chief-customer-officer-advisor/skills/chief-customer-officer-advisor/scripts/customer_segmentation_designer.py"},"region":{"startLine":260}}}],"partialFingerprints":{"codehealthFindingId/v1":"72fd17396c1d6b70c97c578f1e45949dd25aca7d23a887da430559f88ea20a8d"}},{"ruleId":"D4","level":"warning","message":{"text":"Near-duplicate member pair (44 shared lines): business-growth/skills/sales-engineer/scripts/poc_planner.py:582-722 | business-growth/skills/sales-engineer/scripts/rfp_response_analyzer.py:418-511 \u2014 These two members are variants of one another: 44 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":"business-growth/skills/sales-engineer/scripts/poc_planner.py"},"region":{"startLine":582}}}],"partialFingerprints":{"codehealthFindingId/v1":"83daa80bbea9f5c17b44807224a93f2255c817642eb61fe4d0f13b124cab41fb"}},{"ruleId":"D4","level":"warning","message":{"text":"Near-duplicate member pair (44 shared lines): finance/skills/stock-analysis/scripts/score.py:1264-1385 | finance/skills/stock-analysis/scripts/score.py:1398-1555 \u2014 These two members are variants of one another: 44 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":"finance/skills/stock-analysis/scripts/score.py"},"region":{"startLine":1264}}}],"partialFingerprints":{"codehealthFindingId/v1":"27cb11c170fd327f2a92e635c59d15063faf555a3e57e5c39983e184787ff0f3"}},{"ruleId":"D4","level":"warning","message":{"text":"Near-duplicate member pair (43 shared lines): c-level-advisor/chief-customer-officer-advisor/skills/chief-customer-officer-advisor/scripts/cs_coverage_calculator.py:194-241 | c-level-advisor/skills/chief-customer-officer-advisor/scripts/cs_coverage_calculator.py:194-241 \u2014 These two members are variants of one another: 43 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":"c-level-advisor/chief-customer-officer-advisor/skills/chief-customer-officer-advisor/scripts/cs_coverage_calculator.py"},"region":{"startLine":194}}}],"partialFingerprints":{"codehealthFindingId/v1":"78dd823e9c4e0a7f3c5c6f1f65d23a86e53878f4e06c80d0f3642f8dfceb90d6"}},{"ruleId":"D4","level":"warning","message":{"text":"Near-duplicate member pair (43 shared lines): ra-qm-team/compliance-team-iso42001/skills/iso42001-specialist/scripts/aims_audit_scheduler.py:180-225 | ra-qm-team/skills/iso42001-specialist/scripts/aims_audit_scheduler.py:180-225 \u2014 These two members are variants of one another: 43 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":"ra-qm-team/compliance-team-iso42001/skills/iso42001-specialist/scripts/aims_audit_scheduler.py"},"region":{"startLine":180}}}],"partialFingerprints":{"codehealthFindingId/v1":"26483a0bf2517a62db1e254331badaa735de2ab5a541e85b83743873f5d12747"}},{"ruleId":"D4","level":"warning","message":{"text":"Near-duplicate member pair (34 shared lines): c-level-advisor/chief-customer-officer-advisor/skills/chief-customer-officer-advisor/scripts/retention_decomposition_analyzer.py:234-273 | c-level-advisor/skills/chief-customer-officer-advisor/scripts/retention_decomposition_analyzer.py:234-273 \u2014 These two members are variants of one another: 34 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":"c-level-advisor/chief-customer-officer-advisor/skills/chief-customer-officer-advisor/scripts/retention_decomposition_analyzer.py"},"region":{"startLine":234}}}],"partialFingerprints":{"codehealthFindingId/v1":"b13592faa5543ee52a002ce4945a132b2f710689058a93b8bdee49750df29a51"}},{"ruleId":"D4","level":"warning","message":{"text":"Near-duplicate member pair (34 shared lines): engineering-team/google-workspace-cli/skills/google-workspace-cli/scripts/gws_doctor.py:199-243 | engineering-team/google-workspace-cli/skills/google-workspace-cli/scripts/workspace_audit.py:256-306 \u2014 These two members are variants of one another: 34 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":"engineering-team/google-workspace-cli/skills/google-workspace-cli/scripts/gws_doctor.py"},"region":{"startLine":199}}}],"partialFingerprints":{"codehealthFindingId/v1":"37d8eebf02ed2261ac6c68a5e6696439577d0ba523cb0944b2611cf580baabef"}},{"ruleId":"D4","level":"warning","message":{"text":"Near-duplicate member pair (33 shared lines): engineering/skills/tech-debt-tracker/scripts/debt_dashboard.py:908-966 | engineering/skills/tech-debt-tracker/scripts/debt_prioritizer.py:802-853 \u2014 These two members are variants of one another: 33 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":"engineering/skills/tech-debt-tracker/scripts/debt_dashboard.py"},"region":{"startLine":908}}}],"partialFingerprints":{"codehealthFindingId/v1":"6b80d1e31c4719823afaa6d232964f3907ebca49c0a845f12da900b03a7833fd"}},{"ruleId":"D4","level":"warning","message":{"text":"Near-duplicate member pair (26 shared lines): engineering/skills/interview-system-designer/loop_designer.py:827-904 | engineering/skills/interview-system-designer/question_bank_generator.py:971-1056 \u2014 These two members are variants of one another: 26 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":"engineering/skills/interview-system-designer/loop_designer.py"},"region":{"startLine":827}}}],"partialFingerprints":{"codehealthFindingId/v1":"071cf4eb095c40a799a634d87bf648c2cfd9988e7871faae096ed1f257d111d3"}},{"ruleId":"D4","level":"warning","message":{"text":"Near-duplicate member pair (23 shared lines): ra-qm-team/compliance-team-iso42001/skills/iso42001-specialist/scripts/aims_gap_analyzer.py:188-214 | ra-qm-team/skills/iso42001-specialist/scripts/aims_gap_analyzer.py:188-214 \u2014 These two members are variants of one another: 23 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":"ra-qm-team/compliance-team-iso42001/skills/iso42001-specialist/scripts/aims_gap_analyzer.py"},"region":{"startLine":188}}}],"partialFingerprints":{"codehealthFindingId/v1":"f53d2472fdc8ad01322f8e8bb67b94ae83352b959f1e80b25d4e11998dd5b8b8"}},{"ruleId":"D4","level":"warning","message":{"text":"Edited copy of a member (37 corresponding lines): c-level-advisor/skills/vpe-advisor/scripts/delivery_throughput_analyzer.py:202-238 | c-level-advisor/vpe-advisor/skills/vpe-advisor/scripts/delivery_throughput_analyzer.py:202-238 \u2014 These two members are one piece of code written twice and then edited apart: 37 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":"c-level-advisor/skills/vpe-advisor/scripts/delivery_throughput_analyzer.py"},"region":{"startLine":202}}}],"partialFingerprints":{"codehealthFindingId/v1":"dd5880b97ced3527294215b314ed7d04d99e8516ce0df9107cf051ebeac5984a"}},{"ruleId":"D4","level":"warning","message":{"text":"Edited copy of a member (35 corresponding lines): engineering/skills/slo-architect/scripts/slo_designer.py:120-154 | engineering/slo-architect/skills/slo-architect/scripts/slo_designer.py:120-154 \u2014 These two members are one piece of code written twice and then edited apart: 35 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":"engineering/skills/slo-architect/scripts/slo_designer.py"},"region":{"startLine":120}}}],"partialFingerprints":{"codehealthFindingId/v1":"df4c9ea362a7fa58d3c9947e02ca9fb60599d8a0621bebebd400e54cf73a4ec2"}},{"ruleId":"D4","level":"warning","message":{"text":"Edited copy of a member (27 corresponding lines): engineering/skills/slo-architect/scripts/slo_designer.py:90-116 | engineering/slo-architect/skills/slo-architect/scripts/slo_designer.py:90-116 \u2014 These two members are one piece of code written twice and then edited apart: 27 consecutive lines correspond almost exactly, broken only by small local edits. Most of that correspondence is NOT reported as duplicated blocks below \u2014 the edits cut it into fragments and only the largest of them clear the block floor, so the rows below understate it. The repair is at the members\u0027 grain \u2014 factor the shared implementation into one the two call with their differences as parameters or as an injected step, or, where the difference is systematic (an extra return value, one transport against another), generate one from the other. Left alone, the next edit has to be made twice and the two will drift further apart."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/slo-architect/scripts/slo_designer.py"},"region":{"startLine":90}}}],"partialFingerprints":{"codehealthFindingId/v1":"66ef8b9a0ed8303ada0cd3680d8d16e6530102e9d4f5d24a189357be5fd15e97"}},{"ruleId":"D4","level":"warning","message":{"text":"Edited copy of a member (24 corresponding lines): engineering/chaos-engineering/skills/chaos-engineering/scripts/experiment_designer.py:112-135 | engineering/skills/chaos-engineering/scripts/experiment_designer.py:112-135 \u2014 These two members are one piece of code written twice and then edited apart: 24 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":"engineering/chaos-engineering/skills/chaos-engineering/scripts/experiment_designer.py"},"region":{"startLine":112}}}],"partialFingerprints":{"codehealthFindingId/v1":"b87418dc89e0ba9a2900f72d5ae428aaff0aa8c9d696abf43671be0f77fe7b30"}},{"ruleId":"D4","level":"warning","message":{"text":"Edited copy of a member (18 corresponding lines): engineering/feature-flags-architect/skills/feature-flags-architect/scripts/flag_debt_scanner.py:119-136 | engineering/skills/feature-flags-architect/scripts/flag_debt_scanner.py:119-136 \u2014 These two members are one piece of code written twice and then edited apart: 18 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":"engineering/feature-flags-architect/skills/feature-flags-architect/scripts/flag_debt_scanner.py"},"region":{"startLine":119}}}],"partialFingerprints":{"codehealthFindingId/v1":"34344d51e0807eef345ba5fa8336a37b4d5439b33ecce5b2caec60c822490002"}},{"ruleId":"D4","level":"warning","message":{"text":"Edited copy of a member (19 corresponding lines): engineering/skills/slo-architect/scripts/error_budget_calculator.py:105-123 | engineering/slo-architect/skills/slo-architect/scripts/error_budget_calculator.py:105-123 \u2014 These two members are one piece of code written twice and then edited apart: 19 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":"engineering/skills/slo-architect/scripts/error_budget_calculator.py"},"region":{"startLine":105}}}],"partialFingerprints":{"codehealthFindingId/v1":"249ffbe312c6dc65ca9a1c66234becf5b62b0085df81d7612bd340bf08e74432"}},{"ruleId":"D4","level":"warning","message":{"text":"Edited copy of a member (19 corresponding lines): engineering/chaos-engineering/skills/chaos-engineering/scripts/experiment_postmortem.py:122-140 | engineering/skills/chaos-engineering/scripts/experiment_postmortem.py:122-140 \u2014 These two members are one piece of code written twice and then edited apart: 19 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":"engineering/chaos-engineering/skills/chaos-engineering/scripts/experiment_postmortem.py"},"region":{"startLine":122}}}],"partialFingerprints":{"codehealthFindingId/v1":"758b65ffb28d162ce50e12c8ef6f6645b77c82119dc26202a683bec63a6e5548"}},{"ruleId":"D4","level":"warning","message":{"text":"Edited copy of a member (14 corresponding lines): c-level-advisor/arquiteto-de-empresa/skills/arquiteto-de-empresa/scripts/okf_linter.py:140-153 | c-level-advisor/skills/arquiteto-de-empresa/scripts/okf_linter.py:140-153 \u2014 These two members are one piece of code written twice and then edited apart: 14 consecutive lines correspond almost exactly, broken only by small local edits. Most of that correspondence is NOT reported as duplicated blocks below \u2014 the edits cut it into fragments and only the largest of them clear the block floor, so the rows below understate it. The repair is at the members\u0027 grain \u2014 factor the shared implementation into one the two call with their differences as parameters or as an injected step, or, where the difference is systematic (an extra return value, one transport against another), generate one from the other. Left alone, the next edit has to be made twice and the two will drift further apart."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"c-level-advisor/arquiteto-de-empresa/skills/arquiteto-de-empresa/scripts/okf_linter.py"},"region":{"startLine":140}}}],"partialFingerprints":{"codehealthFindingId/v1":"74d8ac637ba4aef75b98abc6912970694f87be2ab6bb037b87aaf243ddaf3806"}},{"ruleId":"D4","level":"warning","message":{"text":"Edited copy of a member (8 corresponding lines): engineering/feature-flags-architect/skills/feature-flags-architect/scripts/rollout_planner.py:85-92 | engineering/skills/feature-flags-architect/scripts/rollout_planner.py:85-92 \u2014 These two members are one piece of code written twice and then edited apart: 8 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":"engineering/feature-flags-architect/skills/feature-flags-architect/scripts/rollout_planner.py"},"region":{"startLine":85}}}],"partialFingerprints":{"codehealthFindingId/v1":"68bf31e0bfa998391248a61219517e5fad5355a258893dd703a640f549cfc92e"}},{"ruleId":"D4","level":"warning","message":{"text":"Edited copy of a member (10 corresponding lines): marketing/landing/skills/landing/scripts/kebab_slug_generator.py:84-93 | research/pulse/skills/pulse/scripts/topic_slug_generator.py:99-110 \u2014 These two members are one piece of code written twice and then edited apart: 10 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":"marketing/landing/skills/landing/scripts/kebab_slug_generator.py"},"region":{"startLine":84}}}],"partialFingerprints":{"codehealthFindingId/v1":"913e1e66e7cf561882e2fb375108508f9175fa6feb0dbf600d345121eceac224"}},{"ruleId":"D4","level":"warning","message":{"text":"Edited copy of a member (49 corresponding lines): engineering-team/skills/aws-solution-architect/scripts/cost_optimizer.py:243-299 | engineering-team/skills/gcp-cloud-architect/scripts/cost_optimizer.py:271-342 \u2014 These two members are one piece of code written twice and then edited apart: 49 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":"engineering-team/skills/aws-solution-architect/scripts/cost_optimizer.py"},"region":{"startLine":243}}}],"partialFingerprints":{"codehealthFindingId/v1":"852b767cc0b994226cf87b741e7d47eae27a64a1d2728830d7bbb453b147cdfe"}},{"ruleId":"D4","level":"warning","message":{"text":"Members sharing a duplicated core (14 members, 50\u002B identical tokens): engineering-team/skills/senior-secops/scripts/compliance_checker.py:468-498 | engineering-team/skills/senior-secops/scripts/compliance_checker.py:501-530 | engineering-team/skills/senior-secops/scripts/compliance_checker.py:533-564 | engineering-team/skills/senior-secops/scripts/compliance_checker.py:567-596 | engineering-team/skills/senior-secops/scripts/compliance_checker.py:599-622 | engineering-team/skills/senior-secops/scripts/compliance_checker.py:665-688 | engineering-team/skills/senior-secops/scripts/compliance_checker.py:691-713 | engineering-team/skills/senior-secops/scripts/compliance_checker.py:716-738 | engineering-team/skills/senior-secops/scripts/compliance_checker.py:741-763 | engineering-team/skills/senior-secops/scripts/compliance_checker.py:766-788 | engineering-team/skills/senior-secops/scripts/compliance_checker.py:791-819 | engineering-team/skills/senior-secops/scripts/compliance_checker.py:822-844 | engineering-team/skills/senior-secops/scripts/compliance_checker.py:886-915 | engineering-team/skills/senior-secops/scripts/compliance_checker.py:918-946 \u2014 These 14 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 14 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 14 times."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/skills/senior-secops/scripts/compliance_checker.py"},"region":{"startLine":468}}}],"partialFingerprints":{"codehealthFindingId/v1":"634025929ca3ba1938686b0f92750d4705c88ec4237741390bf579ce7bddb32d"}},{"ruleId":"D4","level":"warning","message":{"text":"Members sharing a duplicated core (12 members, 50\u002B identical tokens): engineering/grill-with-docs/skills/grill-with-docs/scripts/adr_scanner.py:219-237 | engineering/grill-with-docs/skills/grill-with-docs/scripts/context_md_linter.py:245-268 | productivity/capture/skills/capture/scripts/dump_classifier.py:130-153 | productivity/email/skills/inbox-setup/scripts/kb_validator.py:235-259 | productivity/email/skills/inbox-setup/scripts/voice_sample_analyzer.py:266-295 | productivity/email/skills/inbox-triage/scripts/kb_reader.py:280-300 | productivity/reflect/skills/reflect/scripts/bias_pattern_detector.py:173-196 | productivity/reflect/skills/reflect/scripts/conversation_depth_analyzer.py:172-195 | research/dossier/skills/dossier/scripts/disconfirming_evidence_balance.py:182-209 | research/litreview/skills/litreview/scripts/cross_search_aggregator.py:211-235 | research/litreview/skills/litreview/scripts/framework_recommender.py:183-200 | research/patent/skills/patent/scripts/family_resolver.py:232-256 \u2014 These 12 members share a duplicated core: a run of at least 50 identical tokens appears in every one of them. That run is NOT broken out as duplicated-block rows below \u2014 it is what admitted this row, and the blocks below cover only the part of it that clears the block floor, so they understate the correspondence. Read the members as one construct written 12 times. The repair is at the members\u0027 grain \u2014 factor the shared implementation out once and have all of them call it with their differences as parameters or as an injected step, or, where the difference is systematic, generate them from one template. Extracting the individual blocks below is not the same fix: it leaves every body in place and the next edit still has to be made 12 times."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/grill-with-docs/skills/grill-with-docs/scripts/adr_scanner.py"},"region":{"startLine":219}}}],"partialFingerprints":{"codehealthFindingId/v1":"9c0e3ab250a0bdb7efb60b70908a27b8da695f2941e1a5c3c2a98fd545fe9bf9"}},{"ruleId":"D4","level":"warning","message":{"text":"Members sharing a duplicated core (12 members, 50\u002B identical tokens): research-ops/skills/clinical-research/scripts/endpoint_selector.py:157-179 | research-ops/skills/clinical-research/scripts/phase_gate_scorer.py:205-230 | research-ops/skills/clinical-research/scripts/sample_size_estimator.py:158-201 | research-ops/skills/market-research/scripts/market_sizer.py:134-158 | research-ops/skills/market-research/scripts/sample_size_planner.py:147-179 | research-ops/skills/market-research/scripts/segmentation_scorer.py:114-135 | research-ops/skills/product-research/scripts/insight_synthesizer.py:93-109 | research-ops/skills/product-research/scripts/saturation_planner.py:107-140 | research-ops/skills/product-research/scripts/study_designer.py:112-135 | research-ops/skills/research-finance/scripts/burn_runway_tracker.py:128-149 | research-ops/skills/research-finance/scripts/capex_vs_opex_router.py:155-185 | research-ops/skills/research-finance/scripts/program_budget_planner.py:134-161 \u2014 These 12 members share a duplicated core: a run of at least 50 identical tokens appears in every one of them. That run is NOT broken out as duplicated-block rows below \u2014 it is what admitted this row, and the blocks below cover only the part of it that clears the block floor, so they understate the correspondence. Read the members as one construct written 12 times. The repair is at the members\u0027 grain \u2014 factor the shared implementation out once and have all of them call it with their differences as parameters or as an injected step, or, where the difference is systematic, generate them from one template. Extracting the individual blocks below is not the same fix: it leaves every body in place and the next edit still has to be made 12 times."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"research-ops/skills/clinical-research/scripts/endpoint_selector.py"},"region":{"startLine":157}}}],"partialFingerprints":{"codehealthFindingId/v1":"8e07842819a9945edb430bdc7abc361afae748b577b308aea307f732b85566b9"}},{"ruleId":"D4","level":"warning","message":{"text":"Members sharing a duplicated core (9 members, 50\u002B identical tokens): engineering/skills/slo-architect/scripts/error_budget_calculator.py:127-151 | engineering/skills/slo-architect/scripts/slo_review.py:154-172 | engineering/slo-architect/skills/slo-architect/scripts/error_budget_calculator.py:127-151 | engineering/slo-architect/skills/slo-architect/scripts/slo_review.py:154-172 | marketing/linkedin/skills/linkedin-engagement/scripts/outreach_volume_guard.py:159-185 | marketing/linkedin/skills/linkedin-strategy/scripts/cadence_planner.py:222-249 | marketing/linkedin/skills/linkedin-strategy/scripts/newsletter_planner.py:205-236 | research/research/skills/research/scripts/classifier.py:167-184 | research/research/skills/research/scripts/fallback_decomposer.py:85-103 \u2014 These 9 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 9 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 9 times."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/slo-architect/scripts/error_budget_calculator.py"},"region":{"startLine":127}}}],"partialFingerprints":{"codehealthFindingId/v1":"4a76bb696fa5ce136c4989eb4eb6c247edbb8e31365fe0812455389a2f98855c"}},{"ruleId":"D4","level":"warning","message":{"text":"Members sharing a duplicated core (8 members, 50\u002B identical tokens): engineering-team/skills/senior-data-scientist/scripts/experiment_designer.py:69-97 | engineering-team/skills/senior-data-scientist/scripts/feature_engineering_pipeline.py:69-97 | engineering-team/skills/senior-data-scientist/scripts/model_evaluation_suite.py:69-97 | engineering-team/skills/senior-ml-engineer/scripts/ml_monitoring_suite.py:69-97 | engineering-team/skills/senior-ml-engineer/scripts/model_deployment_pipeline.py:69-97 | engineering-team/skills/senior-ml-engineer/scripts/rag_system_builder.py:69-97 | engineering/skills/database-designer/index_optimizer.py:867-922 | engineering/skills/database-designer/migration_generator.py:1118-1195 \u2014 These 8 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 8 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 8 times."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/skills/senior-data-scientist/scripts/experiment_designer.py"},"region":{"startLine":69}}}],"partialFingerprints":{"codehealthFindingId/v1":"dc4e5cd638e613783f3c7fa8aa05282f1f04e1cabc17b70e29de5a44af19924d"}},{"ruleId":"D4","level":"warning","message":{"text":"Members sharing a duplicated core (7 members, 50\u002B identical tokens): business-growth/skills/revenue-operations/scripts/forecast_accuracy_tracker.py:491-527 | business-growth/skills/revenue-operations/scripts/gtm_efficiency_calculator.py:613-654 | business-growth/skills/revenue-operations/scripts/pipeline_analyzer.py:472-523 | c-level-advisor/skills/coo-advisor/scripts/okr_tracker.py:709-768 | c-level-advisor/skills/coo-advisor/scripts/ops_efficiency_analyzer.py:784-822 | c-level-advisor/skills/cpo-advisor/scripts/pmf_scorer.py:544-607 | c-level-advisor/skills/cpo-advisor/scripts/portfolio_analyzer.py:498-543 \u2014 These 7 members share a duplicated core: a run of at least 50 identical tokens appears in every one of them. That run is NOT broken out as duplicated-block rows below \u2014 it is what admitted this row, and the blocks below cover only the part of it that clears the block floor, so they understate the correspondence. Read the members as one construct written 7 times. The repair is at the members\u0027 grain \u2014 factor the shared implementation out once and have all of them call it with their differences as parameters or as an injected step, or, where the difference is systematic, generate them from one template. Extracting the individual blocks below is not the same fix: it leaves every body in place and the next edit still has to be made 7 times."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"business-growth/skills/revenue-operations/scripts/forecast_accuracy_tracker.py"},"region":{"startLine":491}}}],"partialFingerprints":{"codehealthFindingId/v1":"75b890f7eecfe523dd52f512039f679880923a2754b772f99c21b586383e30ec"}},{"ruleId":"D4","level":"warning","message":{"text":"Members sharing a duplicated core (7 members, 50\u002B identical tokens): engineering/grill-with-docs/skills/grill-with-docs/scripts/adr_scanner.py:193-203 | engineering/grill-with-docs/skills/grill-with-docs/scripts/context_md_linter.py:231-241 | markdown-html/skills/design-system/scripts/brand_palette_validator.py:285-299 | marketing/landing/skills/landing/scripts/brand_palette_validator.py:221-235 | marketing/landing/skills/landing/scripts/html_validator.py:254-263 | productivity/email/skills/inbox-setup/scripts/kb_validator.py:210-219 | productivity/reflect/skills/reflect/scripts/directional_recommendation_validator.py:204-213 \u2014 These 7 members share a duplicated core: a run of at least 50 identical tokens appears in every one of them. That run is NOT broken out as duplicated-block rows below \u2014 it is what admitted this row, and the blocks below cover only the part of it that clears the block floor, so they understate the correspondence. Read the members as one construct written 7 times. The repair is at the members\u0027 grain \u2014 factor the shared implementation out once and have all of them call it with their differences as parameters or as an injected step, or, where the difference is systematic, generate them from one template. Extracting the individual blocks below is not the same fix: it leaves every body in place and the next edit still has to be made 7 times."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/grill-with-docs/skills/grill-with-docs/scripts/adr_scanner.py"},"region":{"startLine":193}}}],"partialFingerprints":{"codehealthFindingId/v1":"9a5c6216d706c302541b627b3164210e96df929b346d3c8a1b00443eb62de19b"}},{"ruleId":"D4","level":"warning","message":{"text":"Members sharing a duplicated core (7 members, 50\u002B identical tokens): markdown-html/skills/design-system/scripts/config_loader.py:120-141 | productivity/handoff/skills/handoff/scripts/cleanup.py:125-161 | productivity/handoff/skills/handoff/scripts/config_loader.py:128-159 | research-ops/skills/clinical-research/scripts/config_loader.py:100-119 | research-ops/skills/market-research/scripts/config_loader.py:91-110 | research-ops/skills/product-research/scripts/config_loader.py:91-110 | research-ops/skills/research-finance/scripts/config_loader.py:92-111 \u2014 These 7 members share a duplicated core: a run of at least 50 identical tokens appears in every one of them. That run is NOT broken out as duplicated-block rows below \u2014 it is what admitted this row, and the blocks below cover only the part of it that clears the block floor, so they understate the correspondence. Read the members as one construct written 7 times. The repair is at the members\u0027 grain \u2014 factor the shared implementation out once and have all of them call it with their differences as parameters or as an injected step, or, where the difference is systematic, generate them from one template. Extracting the individual blocks below is not the same fix: it leaves every body in place and the next edit still has to be made 7 times."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"markdown-html/skills/design-system/scripts/config_loader.py"},"region":{"startLine":120}}}],"partialFingerprints":{"codehealthFindingId/v1":"5b10f624f8732c6ca4b19d7a3228219166ec200dd884ccb5fab9f9ff4765070e"}},{"ruleId":"D4","level":"warning","message":{"text":"Members sharing a duplicated core (6 members, 50\u002B identical tokens): agent-launcher/skills/grade-iterate/scripts/eval_scaffold.py:49-88 | agent-launcher/skills/run-without-you/scripts/deployment_builder.py:59-135 | agent-launcher/skills/run-without-you/scripts/next_directions_writer.py:79-106 | agent-launcher/skills/wrap-up/scripts/overview_page.py:84-114 | agent-launcher/skills/wrap-up/scripts/primitives_inventory.py:72-90 | agent-launcher/skills/wrap-up/scripts/upgrade_suggester.py:56-80 \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":"agent-launcher/skills/grade-iterate/scripts/eval_scaffold.py"},"region":{"startLine":49}}}],"partialFingerprints":{"codehealthFindingId/v1":"f732b88143ce0a1fa68f4621122bbd126e718020ca83b6f9a4fc3c91309a76e7"}},{"ruleId":"D4","level":"warning","message":{"text":"Members sharing a duplicated core (6 members, 50\u002B identical tokens): business-growth/skills/customer-success-manager/scripts/churn_risk_analyzer.py:450-483 | business-growth/skills/customer-success-manager/scripts/expansion_opportunity_scorer.py:377-410 | business-growth/skills/customer-success-manager/scripts/health_score_calculator.py:428-473 | marketing-skill/skills/campaign-analytics/scripts/attribution_analyzer.py:278-343 | marketing-skill/skills/campaign-analytics/scripts/campaign_roi_calculator.py:406-455 | marketing-skill/skills/campaign-analytics/scripts/funnel_analyzer.py:243-301 \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":"business-growth/skills/customer-success-manager/scripts/churn_risk_analyzer.py"},"region":{"startLine":450}}}],"partialFingerprints":{"codehealthFindingId/v1":"680969e94807c4ef0173f843ad66bad6e50c7d0752f4503299b42979ea8a8dab"}},{"ruleId":"D4","level":"warning","message":{"text":"Members sharing a duplicated core (6 members, 50\u002B identical tokens): business-growth/skills/sales-engineer/scripts/competitive_matrix_builder.py:43-76 | business-growth/skills/sales-engineer/scripts/poc_planner.py:130-155 | business-growth/skills/sales-engineer/scripts/rfp_response_analyzer.py:49-74 | engineering/skills/secrets-vault-manager/scripts/rotation_planner.py:59-103 | ra-qm-team/skills/soc2-compliance/scripts/evidence_tracker.py:35-58 | ra-qm-team/skills/soc2-compliance/scripts/gap_analyzer.py:125-145 \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":"business-growth/skills/sales-engineer/scripts/competitive_matrix_builder.py"},"region":{"startLine":43}}}],"partialFingerprints":{"codehealthFindingId/v1":"c1825ff1fcf1d04271f00f8f8d1c2bca30ac0d44f1008562d5f41c7704e82553"}},{"ruleId":"D4","level":"warning","message":{"text":"Members sharing a duplicated core (6 members, 50\u002B identical tokens): c-level-advisor/chief-ai-officer-advisor/skills/chief-ai-officer-advisor/scripts/ai_cost_economics.py:250-302 | c-level-advisor/chief-ai-officer-advisor/skills/chief-ai-officer-advisor/scripts/model_buildvsbuy_calculator.py:272-316 | c-level-advisor/chief-data-officer-advisor/skills/chief-data-officer-advisor/scripts/data_product_strategy_picker.py:271-313 | c-level-advisor/skills/chief-ai-officer-advisor/scripts/ai_cost_economics.py:250-302 | c-level-advisor/skills/chief-ai-officer-advisor/scripts/model_buildvsbuy_calculator.py:272-316 | c-level-advisor/skills/chief-data-officer-advisor/scripts/data_product_strategy_picker.py:271-313 \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":"c-level-advisor/chief-ai-officer-advisor/skills/chief-ai-officer-advisor/scripts/ai_cost_economics.py"},"region":{"startLine":250}}}],"partialFingerprints":{"codehealthFindingId/v1":"8dfe49fa9a4394ceda99a7fd037f48056f457b56a0184c75a50b9f76438cc522"}},{"ruleId":"D4","level":"warning","message":{"text":"Members sharing a duplicated core (6 members, 50\u002B identical tokens): engineering-team/skills/senior-data-scientist/scripts/experiment_designer.py:42-61 | engineering-team/skills/senior-data-scientist/scripts/feature_engineering_pipeline.py:42-61 | engineering-team/skills/senior-data-scientist/scripts/model_evaluation_suite.py:42-61 | engineering-team/skills/senior-ml-engineer/scripts/ml_monitoring_suite.py:42-61 | engineering-team/skills/senior-ml-engineer/scripts/model_deployment_pipeline.py:42-61 | engineering-team/skills/senior-ml-engineer/scripts/rag_system_builder.py:42-61 \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":"engineering-team/skills/senior-data-scientist/scripts/experiment_designer.py"},"region":{"startLine":42}}}],"partialFingerprints":{"codehealthFindingId/v1":"9755404ac2a18bf5eb920e040cf59361dfab9c54e94111040b9e3931c3bae08d"}},{"ruleId":"D4","level":"warning","message":{"text":"Members sharing a duplicated core (6 members, 50\u002B identical tokens): engineering/docker-development/skills/docker-development/scripts/compose_validator.py:308-355 | engineering/docker-development/skills/docker-development/scripts/dockerfile_analyzer.py:304-375 | engineering/helm-chart-builder/skills/helm-chart-builder/scripts/chart_analyzer.py:401-483 | engineering/helm-chart-builder/skills/helm-chart-builder/scripts/values_validator.py:332-407 | engineering/terraform-patterns/skills/terraform-patterns/scripts/tf_module_analyzer.py:370-424 | engineering/terraform-patterns/skills/terraform-patterns/scripts/tf_security_scanner.py:486-532 \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":"engineering/docker-development/skills/docker-development/scripts/compose_validator.py"},"region":{"startLine":308}}}],"partialFingerprints":{"codehealthFindingId/v1":"89b9bc2bd8e009a1aef3b27755171b94550e56be2d2b06d05f996dbd5c4e927e"}},{"ruleId":"D4","level":"warning","message":{"text":"Members sharing a duplicated core (6 members, 50\u002B identical tokens): engineering/grill-with-docs/skills/grill-with-docs/scripts/adr_scanner.py:180-189 | engineering/grill-with-docs/skills/grill-with-docs/scripts/context_md_linter.py:218-227 | marketing/landing/skills/landing/scripts/brand_palette_validator.py:208-217 | marketing/landing/skills/landing/scripts/html_validator.py:241-250 | productivity/email/skills/inbox-setup/scripts/kb_validator.py:197-206 | productivity/reflect/skills/reflect/scripts/directional_recommendation_validator.py:168-177 \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":"engineering/grill-with-docs/skills/grill-with-docs/scripts/adr_scanner.py"},"region":{"startLine":180}}}],"partialFingerprints":{"codehealthFindingId/v1":"39bd8a1728e538cccc19f33b1fc5d33ec775ac12d251785b1afa464a2ea9cdc5"}},{"ruleId":"D4","level":"warning","message":{"text":"Members sharing a duplicated core (6 members, 50\u002B identical tokens): engineering/skills/ci-cd-pipeline-builder/scripts/pipeline_generator.py:46-60 | engineering/skills/ci-cd-pipeline-builder/scripts/stack_detector.py:46-60 | engineering/skills/git-worktree-manager/scripts/worktree_cleanup.py:42-54 | engineering/skills/git-worktree-manager/scripts/worktree_manager.py:53-66 | marketing-skill/skills/prompt-engineer-toolkit/scripts/prompt_tester.py:67-99 | marketing-skill/skills/prompt-engineer-toolkit/scripts/prompt_versioner.py:74-88 \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":"engineering/skills/ci-cd-pipeline-builder/scripts/pipeline_generator.py"},"region":{"startLine":46}}}],"partialFingerprints":{"codehealthFindingId/v1":"7ed7ca4bcd106af0d0e75c86ec2ddc9f2ad675f70bac8a2a3a4bd34f97d22ee3"}},{"ruleId":"D4","level":"warning","message":{"text":"Members sharing a duplicated core (6 members, 50\u002B identical tokens): markdown-html/skills/design-system/scripts/config_loader.py:80-86 | productivity/handoff/skills/handoff/scripts/config_loader.py:59-65 | research-ops/skills/clinical-research/scripts/config_loader.py:60-66 | research-ops/skills/market-research/scripts/config_loader.py:55-61 | research-ops/skills/product-research/scripts/config_loader.py:55-61 | research-ops/skills/research-finance/scripts/config_loader.py:56-62 \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":"markdown-html/skills/design-system/scripts/config_loader.py"},"region":{"startLine":80}}}],"partialFingerprints":{"codehealthFindingId/v1":"1ebb29da6ef3dfc2b11edbbad48a707c0325f01ada59374f8a8e60e566058615"}},{"ruleId":"D4","level":"warning","message":{"text":"Members sharing a duplicated core (6 members, 50\u002B identical tokens): marketing/linkedin/skills/linkedin-content/scripts/format_picker.py:204-237 | marketing/linkedin/skills/linkedin-content/scripts/post_linter.py:299-321 | marketing/linkedin/skills/linkedin-content/scripts/repurpose_splitter.py:197-295 | ra-qm-team/skills/quality-documentation-manager/scripts/document_version_control.py:376-456 | ra-qm-team/skills/quality-manager-qmr/scripts/quality_effectiveness_monitor.py:426-477 | research/pulse/skills/pulse/scripts/citation_tracker.py:472-569 \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":"marketing/linkedin/skills/linkedin-content/scripts/format_picker.py"},"region":{"startLine":204}}}],"partialFingerprints":{"codehealthFindingId/v1":"c943184eff2033f29b80a5c70dc66516b170da694ed87506bb2c23993df0475e"}},{"ruleId":"D4","level":"warning","message":{"text":"Members sharing a duplicated core (6 members, 50\u002B identical tokens): productivity/email/skills/inbox-setup/scripts/section_progress_tracker.py:200-250 | research/dossier/skills/dossier/scripts/citation_tracker.py:233-290 | research/grants/skills/grants/scripts/citation_tracker.py:243-299 | research/litreview/skills/litreview/scripts/citation_tracker.py:201-255 | research/patent/skills/patent/scripts/citation_tracker.py:196-237 | research/syllabus/skills/syllabus/scripts/citation_tracker.py:172-213 \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":"productivity/email/skills/inbox-setup/scripts/section_progress_tracker.py"},"region":{"startLine":200}}}],"partialFingerprints":{"codehealthFindingId/v1":"4dd06adfeb697777f8b7cdf1d0705cba8114cee44b715b2b8305e64367f975e4"}},{"ruleId":"D4","level":"warning","message":{"text":"Members sharing a duplicated core (6 members, 50\u002B identical tokens): project-management/skills/scrum-master/scripts/retrospective_analyzer.py:768-848 | project-management/skills/scrum-master/scripts/sprint_health_scorer.py:616-678 | project-management/skills/scrum-master/scripts/velocity_analyzer.py:438-514 | project-management/skills/senior-pm/scripts/project_health_dashboard.py:636-732 | project-management/skills/senior-pm/scripts/resource_capacity_planner.py:647-755 | project-management/skills/senior-pm/scripts/risk_matrix_analyzer.py:517-610 \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":"project-management/skills/scrum-master/scripts/retrospective_analyzer.py"},"region":{"startLine":768}}}],"partialFingerprints":{"codehealthFindingId/v1":"9f99b4fce3d178eb69646989e928d1409ed80dbd3886c2e5ef9f49a39f88550e"}},{"ruleId":"D4","level":"warning","message":{"text":"Members sharing a duplicated core (5 members, 50\u002B identical tokens): commercial/skills/commercial-forecaster/scripts/bookings_forecaster.py:406-451 | commercial/skills/commercial-forecaster/scripts/cohort_arr_projector.py:251-291 | commercial/skills/commercial-forecaster/scripts/funnel_confidence_scorer.py:163-200 | commercial/skills/pricing-strategist/scripts/pricing_model_picker.py:260-293 | commercial/skills/pricing-strategist/scripts/wtp_analyzer.py:228-261 \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":"commercial/skills/commercial-forecaster/scripts/bookings_forecaster.py"},"region":{"startLine":406}}}],"partialFingerprints":{"codehealthFindingId/v1":"ed0e717f1f56d0c5532834425f3ffdc87efe1745807742fcb0a311dbcf2e9146"}},{"ruleId":"D4","level":"warning","message":{"text":"Members sharing a duplicated core (5 members, 50\u002B identical tokens): engineering/chaos-engineering/skills/chaos-engineering/scripts/experiment_postmortem.py:82-118 | engineering/skills/chaos-engineering/scripts/experiment_postmortem.py:82-118 | marketing-skill/skills/aeo/scripts/aeo_audit.py:292-323 | ra-qm-team/skills/soc2-compliance/scripts/evidence_tracker.py:161-199 | research/grants/skills/grants/scripts/citation_tracker.py:194-221 \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":"engineering/chaos-engineering/skills/chaos-engineering/scripts/experiment_postmortem.py"},"region":{"startLine":82}}}],"partialFingerprints":{"codehealthFindingId/v1":"65f7f7b0df111ccfc38a12d763d1979a382c8e7f9312e78fa73c7ccd3f0df34d"}},{"ruleId":"D4","level":"warning","message":{"text":"Members sharing a duplicated core (5 members, 50\u002B identical tokens): engineering/skills/api-design-reviewer/scripts/api_scorecard.py:184-221 | engineering/skills/api-design-reviewer/scripts/api_scorecard.py:562-597 | engineering/skills/api-design-reviewer/scripts/api_scorecard.py:822-856 | engineering/skills/api-design-reviewer/scripts/api_scorecard.py:998-1032 | engineering/skills/api-design-reviewer/scripts/api_scorecard.py:1262-1296 \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":"engineering/skills/api-design-reviewer/scripts/api_scorecard.py"},"region":{"startLine":184}}}],"partialFingerprints":{"codehealthFindingId/v1":"dbd5a5d15181b5d7552e4822350c1e02b2ea3b7ce7273a9b3b0f2ee20a051c79"}},{"ruleId":"D4","level":"warning","message":{"text":"Members sharing a duplicated core (5 members, 50\u002B identical tokens): markdown-html/skills/design-system/scripts/onboard.py:174-252 | research-ops/skills/clinical-research/scripts/onboard.py:89-140 | research-ops/skills/market-research/scripts/onboard.py:66-113 | research-ops/skills/product-research/scripts/onboard.py:75-120 | research-ops/skills/research-finance/scripts/onboard.py:69-116 \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":"markdown-html/skills/design-system/scripts/onboard.py"},"region":{"startLine":174}}}],"partialFingerprints":{"codehealthFindingId/v1":"7944cf88ac1906e28d63f53077b11d3cdfec437d40af3b65cd84f4f6e246f918"}},{"ruleId":"D4","level":"warning","message":{"text":"Members sharing a duplicated core (5 members, 50\u002B identical tokens): productivity/andreessen/skills/andreessen/scripts/market_first_evaluator.py:164-173 | productivity/andreessen/skills/andreessen/scripts/pmf_signal_scorer.py:133-142 | productivity/roast/skills/roast/scripts/brief_builder.py:83-92 | productivity/roast/skills/roast/scripts/cheapest_test_designer.py:129-138 | productivity/roast/skills/roast/scripts/verdict_synthesizer.py:167-176 \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":"productivity/andreessen/skills/andreessen/scripts/market_first_evaluator.py"},"region":{"startLine":164}}}],"partialFingerprints":{"codehealthFindingId/v1":"ec983e784940a30bcc63238887d25cfc0a4da21616b9f392fab561ab837e7440"}},{"ruleId":"D4","level":"warning","message":{"text":"Members sharing a duplicated core (4 members, 50\u002B identical tokens): c-level-advisor/arquiteto-de-empresa/skills/arquiteto-de-empresa/scripts/index_generator.py:141-171 | c-level-advisor/arquiteto-de-empresa/skills/arquiteto-de-empresa/scripts/okf_linter.py:157-186 | c-level-advisor/skills/arquiteto-de-empresa/scripts/index_generator.py:141-171 | c-level-advisor/skills/arquiteto-de-empresa/scripts/okf_linter.py:157-186 \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":"c-level-advisor/arquiteto-de-empresa/skills/arquiteto-de-empresa/scripts/index_generator.py"},"region":{"startLine":141}}}],"partialFingerprints":{"codehealthFindingId/v1":"f98514b6ebb6003c107f5321c7fbe306379668504fe50c2a7a4593960bd02ffb"}},{"ruleId":"D4","level":"warning","message":{"text":"Members sharing a duplicated core (4 members, 50\u002B identical tokens): c-level-advisor/skills/vpe-advisor/scripts/eng_hiring_funnel_calculator.py:194-243 | c-level-advisor/skills/vpe-advisor/scripts/eng_team_structure_designer.py:190-239 | c-level-advisor/vpe-advisor/skills/vpe-advisor/scripts/eng_hiring_funnel_calculator.py:194-243 | c-level-advisor/vpe-advisor/skills/vpe-advisor/scripts/eng_team_structure_designer.py:190-239 \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":"c-level-advisor/skills/vpe-advisor/scripts/eng_hiring_funnel_calculator.py"},"region":{"startLine":194}}}],"partialFingerprints":{"codehealthFindingId/v1":"4e9b6538558d4bd9135eb5c9c0697f1c598e0ec413e7dcd376ee5d33e75f86b7"}},{"ruleId":"D4","level":"warning","message":{"text":"Members sharing a duplicated core (4 members, 50\u002B identical tokens): commercial/skills/channel-economics/scripts/cost_to_serve_calculator.py:140-178 | marketing-skill/skills/competitor-alternatives/scripts/comparison_matrix_builder.py:180-240 | marketing-skill/skills/form-cro/scripts/form_field_analyzer.py:183-226 | marketing-skill/skills/programmatic-seo/scripts/url_pattern_generator.py:112-155 \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":"commercial/skills/channel-economics/scripts/cost_to_serve_calculator.py"},"region":{"startLine":140}}}],"partialFingerprints":{"codehealthFindingId/v1":"88e9d935b662cf88bf962d6285a1efc1fd71efc2a328e6c9046de994d83ba84e"}},{"ruleId":"D4","level":"warning","message":{"text":"Members sharing a duplicated core (4 members, 50\u002B identical tokens): engineering-team/skills/senior-architect/scripts/project_architect.py:192-230 | engineering-team/skills/senior-architect/scripts/project_architect.py:233-268 | engineering-team/skills/senior-architect/scripts/project_architect.py:271-330 | engineering-team/skills/senior-architect/scripts/project_architect.py:392-439 \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":"engineering-team/skills/senior-architect/scripts/project_architect.py"},"region":{"startLine":192}}}],"partialFingerprints":{"codehealthFindingId/v1":"87953f3752b593c9efaed248c4d9474f059b5ac45b8e17183421c105cb659b68"}},{"ruleId":"D4","level":"warning","message":{"text":"Members sharing a duplicated core (4 members, 50\u002B identical tokens): engineering-team/skills/senior-backend/scripts/api_load_tester.py:482-603 | engineering-team/skills/senior-secops/scripts/compliance_checker.py:1038-1103 | engineering-team/skills/senior-secops/scripts/security_scanner.py:402-467 | engineering-team/skills/senior-secops/scripts/vulnerability_assessor.py:494-559 \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":"engineering-team/skills/senior-backend/scripts/api_load_tester.py"},"region":{"startLine":482}}}],"partialFingerprints":{"codehealthFindingId/v1":"9210201b9e01f83ae391f19d933f57d301606c9210bdbfb8a2da669150dbff5a"}},{"ruleId":"D4","level":"warning","message":{"text":"Members sharing a duplicated core (4 members, 50\u002B identical tokens): engineering-team/skills/senior-secops/scripts/compliance_checker.py:221-264 | engineering-team/skills/senior-secops/scripts/compliance_checker.py:348-381 | engineering-team/skills/senior-secops/scripts/compliance_checker.py:625-662 | engineering-team/skills/senior-secops/scripts/compliance_checker.py:847-883 \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":"engineering-team/skills/senior-secops/scripts/compliance_checker.py"},"region":{"startLine":221}}}],"partialFingerprints":{"codehealthFindingId/v1":"e19922cce539f53225a158c1d24a162ac56d572cb766259a9a95c29fba0672df"}},{"ruleId":"D4","level":"warning","message":{"text":"Members sharing a duplicated core (4 members, 50\u002B identical tokens): engineering/docker-development/skills/docker-development/scripts/compose_validator.py:359-386 | engineering/docker-development/skills/docker-development/scripts/dockerfile_analyzer.py:379-406 | engineering/helm-chart-builder/skills/helm-chart-builder/scripts/chart_analyzer.py:504-538 | engineering/helm-chart-builder/skills/helm-chart-builder/scripts/values_validator.py:411-438 \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":"engineering/docker-development/skills/docker-development/scripts/compose_validator.py"},"region":{"startLine":359}}}],"partialFingerprints":{"codehealthFindingId/v1":"932076523495bfd1cc99f6c79cd6d008c70e32b8e1c1963558bd059952aa01c7"}},{"ruleId":"D4","level":"warning","message":{"text":"Members sharing a duplicated core (4 members, 50\u002B identical tokens): engineering/feature-flags-architect/skills/feature-flags-architect/scripts/flag_debt_scanner.py:27-31 | engineering/feature-flags-architect/skills/feature-flags-architect/scripts/kill_switch_audit.py:27-31 | engineering/skills/feature-flags-architect/scripts/flag_debt_scanner.py:27-31 | engineering/skills/feature-flags-architect/scripts/kill_switch_audit.py:27-31 \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":"engineering/feature-flags-architect/skills/feature-flags-architect/scripts/flag_debt_scanner.py"},"region":{"startLine":27}}}],"partialFingerprints":{"codehealthFindingId/v1":"ff63028497f6744b39c655062955bc771fe29c5e7284c8168ad37b8ca554cc48"}},{"ruleId":"D4","level":"warning","message":{"text":"Members sharing a duplicated core (4 members, 50\u002B identical tokens): engineering/kubernetes-operator/skills/kubernetes-operator/scripts/reconcile_lint.py:145-157 | engineering/skills/kubernetes-operator/scripts/reconcile_lint.py:145-157 | engineering/skills/slo-architect/scripts/slo_review.py:138-150 | engineering/slo-architect/skills/slo-architect/scripts/slo_review.py:138-150 \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":"engineering/kubernetes-operator/skills/kubernetes-operator/scripts/reconcile_lint.py"},"region":{"startLine":145}}}],"partialFingerprints":{"codehealthFindingId/v1":"7602eac2b46c8af8b992209478cd9222f756cfa678e67665d306d00b17f190b4"}},{"ruleId":"D4","level":"warning","message":{"text":"Members sharing a duplicated core (4 members, 50\u002B identical tokens): engineering/skills/tc-tracker/scripts/tc_create.py:147-273 | engineering/skills/tc-tracker/scripts/tc_init.py:107-192 | engineering/skills/tc-tracker/scripts/tc_status.py:141-196 | engineering/skills/tc-tracker/scripts/tc_update.py:129-357 \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":"engineering/skills/tc-tracker/scripts/tc_create.py"},"region":{"startLine":147}}}],"partialFingerprints":{"codehealthFindingId/v1":"dfd4ad583530a3761d6802ed408dc6d1ebc3ac6da8a303c6f7365afbbfe652b1"}},{"ruleId":"D4","level":"warning","message":{"text":"Members sharing a duplicated core (4 members, 50\u002B identical tokens): finance/skills/financial-analyst/scripts/budget_variance_analyzer.py:370-430 | finance/skills/financial-analyst/scripts/dcf_valuation.py:403-472 | finance/skills/financial-analyst/scripts/forecast_builder.py:467-524 | finance/skills/financial-analyst/scripts/ratio_calculator.py:390-457 \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":"finance/skills/financial-analyst/scripts/budget_variance_analyzer.py"},"region":{"startLine":370}}}],"partialFingerprints":{"codehealthFindingId/v1":"a5b7a7929afdf4d02d15f08320e105759166d49149d0c3b05b30286011f639aa"}},{"ruleId":"D4","level":"warning","message":{"text":"Members sharing a duplicated core (4 members, 50\u002B identical tokens): marketing/landing/skills/landing/scripts/html_validator.py:267-291 | productivity/email/skills/inbox-setup/scripts/kb_validator.py:235-259 | productivity/email/skills/inbox-triage/scripts/draft_safety_validator.py:169-193 | productivity/reflect/skills/reflect/scripts/directional_recommendation_validator.py:217-243 \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":"marketing/landing/skills/landing/scripts/html_validator.py"},"region":{"startLine":267}}}],"partialFingerprints":{"codehealthFindingId/v1":"17ca596a4fec4e53218c2acb75ad4d047e573af6c8af4d91fc077c936ebc92fa"}},{"ruleId":"D4","level":"warning","message":{"text":"Members sharing a duplicated core (4 members, 50\u002B identical tokens): productivity/andreessen/skills/andreessen/scripts/market_first_evaluator.py:180-207 | productivity/andreessen/skills/andreessen/scripts/pmf_signal_scorer.py:176-202 | productivity/roast/skills/roast/scripts/cheapest_test_designer.py:168-190 | productivity/roast/skills/roast/scripts/verdict_synthesizer.py:217-245 \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":"productivity/andreessen/skills/andreessen/scripts/market_first_evaluator.py"},"region":{"startLine":180}}}],"partialFingerprints":{"codehealthFindingId/v1":"df112453dd0acae6e3c1ea73ac102c1ce02e3a40816ebef135c13c9bb0f3ac15"}},{"ruleId":"D4","level":"warning","message":{"text":"Members sharing a duplicated core (4 members, 50\u002B identical tokens): productivity/handoff/hooks/session_end.py:43-54 | productivity/handoff/hooks/session_start.py:46-58 | productivity/handoff/skills/handoff/scripts/cleanup.py:28-38 | productivity/handoff/skills/handoff/scripts/handoff_template_generator.py:68-80 \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":"productivity/handoff/hooks/session_end.py"},"region":{"startLine":43}}}],"partialFingerprints":{"codehealthFindingId/v1":"fa8efe3611f7477a4cd3ba0816da8f3a1cffc2df0950cac8f6f9ea6d5499af18"}},{"ruleId":"D4","level":"warning","message":{"text":"Members sharing a duplicated core (4 members, 50\u002B identical tokens): project-management/skills/atlassian-admin/scripts/permission_audit_tool.py:427-465 | project-management/skills/confluence-expert/scripts/content_audit_analyzer.py:415-453 | project-management/skills/confluence-expert/scripts/space_structure_generator.py:475-513 | project-management/skills/jira-expert/scripts/workflow_validator.py:382-420 \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":"project-management/skills/atlassian-admin/scripts/permission_audit_tool.py"},"region":{"startLine":427}}}],"partialFingerprints":{"codehealthFindingId/v1":"e1819bf860b4cfeb1827db80f8097ad69f4d5160b7da026493f094e61c5c9f42"}},{"ruleId":"D4","level":"warning","message":{"text":"Members sharing a duplicated core (4 members, 50\u002B identical tokens): ra-qm-team/skills/capa-officer/scripts/capa_tracker.py:473-634 | ra-qm-team/skills/qms-audit-expert/scripts/audit_schedule_optimizer.py:356-416 | ra-qm-team/skills/quality-documentation-manager/scripts/document_validator.py:546-642 | ra-qm-team/skills/quality-manager-qmr/scripts/management_review_tracker.py:437-576 \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":"ra-qm-team/skills/capa-officer/scripts/capa_tracker.py"},"region":{"startLine":473}}}],"partialFingerprints":{"codehealthFindingId/v1":"f5b79658e30dc2dde9526dd8dc30769279cac21d796c85b04f2f266c03c8b9c9"}},{"ruleId":"D4","level":"warning","message":{"text":"Members sharing a duplicated core (4 members, 50\u002B identical tokens): research-ops/skills/clinical-research/scripts/ar_evaluator.py:41-70 | research-ops/skills/market-research/scripts/ar_evaluator.py:37-73 | research-ops/skills/product-research/scripts/ar_evaluator.py:37-64 | research-ops/skills/research-finance/scripts/ar_evaluator.py:37-70 \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":"research-ops/skills/clinical-research/scripts/ar_evaluator.py"},"region":{"startLine":41}}}],"partialFingerprints":{"codehealthFindingId/v1":"ebb6e61ceb1c088d20d53a37d54b207596b677b88958cd11464b22df85a1818a"}},{"ruleId":"D4","level":"warning","message":{"text":"Members sharing a duplicated core (4 members, 50\u002B identical tokens): research/grants/skills/grants/scripts/mechanism_matcher.py:189-212 | research/notebooklm/skills/notebooklm/scripts/action_router.py:226-268 | research/notebooklm/skills/notebooklm/scripts/async_action_classifier.py:238-258 | research/notebooklm/skills/notebooklm/scripts/custom_prompt_template_generator.py:243-266 \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":"research/grants/skills/grants/scripts/mechanism_matcher.py"},"region":{"startLine":189}}}],"partialFingerprints":{"codehealthFindingId/v1":"a02d3f367f6eb9ed381eff89d62de92fd4e6fd4d0d8833ee4c96169fb5587e6f"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (250 lines \u00D7 2): c-level-advisor/general-counsel-advisor/skills/general-counsel-advisor/scripts/term_sheet_analyzer.py:81-330 | c-level-advisor/skills/general-counsel-advisor/scripts/term_sheet_analyzer.py:81-330 \u2014 before extracting anything, compare \u0060c-level-advisor/general-counsel-advisor/skills/general-counsel-advisor/scripts/term_sheet_analyzer.py\u0060 and \u0060c-level-advisor/skills/general-counsel-advisor/scripts/term_sheet_analyzer.py\u0060 as WHOLE FILES: this scan already matched 6 separate duplicated blocks between them, totalling at least 323 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The \u0060return\u0060 at the foot of the matched lines is the enclosing body\u0027s own terminal exit, not an early one: it moves with them unchanged, and each site calls the extracted unit from the position that \u0060return\u0060 occupied \u2014 no decision has to be handed back and re-acted on."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"c-level-advisor/general-counsel-advisor/skills/general-counsel-advisor/scripts/term_sheet_analyzer.py"},"region":{"startLine":81}}}],"partialFingerprints":{"codehealthFindingId/v1":"a589ce0297a4a022415f89a09c196febbb55b9c8ad2e64ea3391597cb2b6c409"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (179 lines \u00D7 2): c-level-advisor/chief-data-officer-advisor/skills/chief-data-officer-advisor/scripts/ai_training_data_audit.py:126-304 | c-level-advisor/skills/chief-data-officer-advisor/scripts/ai_training_data_audit.py:126-304 \u2014 before extracting anything, compare \u0060c-level-advisor/chief-data-officer-advisor/skills/chief-data-officer-advisor/scripts/ai_training_data_audit.py\u0060 and \u0060c-level-advisor/skills/chief-data-officer-advisor/scripts/ai_training_data_audit.py\u0060 as WHOLE FILES: this scan already matched 8 separate duplicated blocks between them, totalling at least 314 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"c-level-advisor/chief-data-officer-advisor/skills/chief-data-officer-advisor/scripts/ai_training_data_audit.py"},"region":{"startLine":126}}}],"partialFingerprints":{"codehealthFindingId/v1":"86530a58706c9692f012934941d20247430e3e52b7923502e66e879b365eb250"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (113 lines \u00D7 2): c-level-advisor/chief-ai-officer-advisor/skills/chief-ai-officer-advisor/scripts/ai_risk_classifier.py:79-191 | c-level-advisor/skills/chief-ai-officer-advisor/scripts/ai_risk_classifier.py:79-191 \u2014 before extracting anything, compare \u0060c-level-advisor/chief-ai-officer-advisor/skills/chief-ai-officer-advisor/scripts/ai_risk_classifier.py\u0060 and \u0060c-level-advisor/skills/chief-ai-officer-advisor/scripts/ai_risk_classifier.py\u0060 as WHOLE FILES: this scan already matched 11 separate duplicated blocks between them, totalling at least 356 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"c-level-advisor/chief-ai-officer-advisor/skills/chief-ai-officer-advisor/scripts/ai_risk_classifier.py"},"region":{"startLine":79}}}],"partialFingerprints":{"codehealthFindingId/v1":"a97fc7347c233189c10bbc8624da8412ccc37e1a27ebbc74b48517128603f414"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (99 lines \u00D7 2): c-level-advisor/chief-ai-officer-advisor/skills/chief-ai-officer-advisor/scripts/model_buildvsbuy_calculator.py:125-223 | c-level-advisor/skills/chief-ai-officer-advisor/scripts/model_buildvsbuy_calculator.py:125-223 \u2014 before extracting anything, compare \u0060c-level-advisor/chief-ai-officer-advisor/skills/chief-ai-officer-advisor/scripts/model_buildvsbuy_calculator.py\u0060 and \u0060c-level-advisor/skills/chief-ai-officer-advisor/scripts/model_buildvsbuy_calculator.py\u0060 as WHOLE FILES: this scan already matched 12 separate duplicated blocks between them, totalling at least 251 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"c-level-advisor/chief-ai-officer-advisor/skills/chief-ai-officer-advisor/scripts/model_buildvsbuy_calculator.py"},"region":{"startLine":125}}}],"partialFingerprints":{"codehealthFindingId/v1":"8274ebfb346fff73b149838d79fb00ee8d4ee50e08da00c1efa08afb00dac59e"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (95 lines \u00D7 2): c-level-advisor/chief-customer-officer-advisor/skills/chief-customer-officer-advisor/scripts/cs_coverage_calculator.py:96-190 | c-level-advisor/skills/chief-customer-officer-advisor/scripts/cs_coverage_calculator.py:96-190 \u2014 before extracting anything, compare \u0060c-level-advisor/chief-customer-officer-advisor/skills/chief-customer-officer-advisor/scripts/cs_coverage_calculator.py\u0060 and \u0060c-level-advisor/skills/chief-customer-officer-advisor/scripts/cs_coverage_calculator.py\u0060 as WHOLE FILES: this scan already matched 8 separate duplicated blocks between them, totalling at least 188 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"c-level-advisor/chief-customer-officer-advisor/skills/chief-customer-officer-advisor/scripts/cs_coverage_calculator.py"},"region":{"startLine":96}}}],"partialFingerprints":{"codehealthFindingId/v1":"c9bbff545acbd228bc2a77e7b9c7cacd2fbb851d4761d4ebd8bc08cad223014a"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (86 lines \u00D7 2): ra-qm-team/compliance-team-eu-ai-act/skills/eu-ai-act-specialist/scripts/ai_system_risk_classifier.py:161-246 | ra-qm-team/skills/eu-ai-act-specialist/scripts/ai_system_risk_classifier.py:161-246 \u2014 before extracting anything, compare \u0060ra-qm-team/compliance-team-eu-ai-act/skills/eu-ai-act-specialist/scripts/ai_system_risk_classifier.py\u0060 and \u0060ra-qm-team/skills/eu-ai-act-specialist/scripts/ai_system_risk_classifier.py\u0060 as WHOLE FILES: this scan already matched 7 separate duplicated blocks between them, totalling at least 156 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"ra-qm-team/compliance-team-eu-ai-act/skills/eu-ai-act-specialist/scripts/ai_system_risk_classifier.py"},"region":{"startLine":161}}}],"partialFingerprints":{"codehealthFindingId/v1":"d3d3af6ac09efa6c1178aa3c16ca73ea82260190ac631543b72a96f064f9a3f3"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (80 lines \u00D7 2): c-level-advisor/chief-data-officer-advisor/skills/chief-data-officer-advisor/scripts/data_product_strategy_picker.py:116-195 | c-level-advisor/skills/chief-data-officer-advisor/scripts/data_product_strategy_picker.py:116-195 \u2014 before extracting anything, compare \u0060c-level-advisor/chief-data-officer-advisor/skills/chief-data-officer-advisor/scripts/data_product_strategy_picker.py\u0060 and \u0060c-level-advisor/skills/chief-data-officer-advisor/scripts/data_product_strategy_picker.py\u0060 as WHOLE FILES: this scan already matched 9 separate duplicated blocks between them, totalling at least 282 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The \u0060return\u0060 at the foot of the matched lines is the enclosing body\u0027s own terminal exit, not an early one: it moves with them unchanged, and each site calls the extracted unit from the position that \u0060return\u0060 occupied \u2014 no decision has to be handed back and re-acted on."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"c-level-advisor/chief-data-officer-advisor/skills/chief-data-officer-advisor/scripts/data_product_strategy_picker.py"},"region":{"startLine":116}}}],"partialFingerprints":{"codehealthFindingId/v1":"c55107ce1b2e4f057dff24baa547c29fa9802d35bcea9f722b318330eee8d541"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (78 lines \u00D7 2): c-level-advisor/chief-data-officer-advisor/skills/chief-data-officer-advisor/scripts/data_asset_valuator.py:166-243 | c-level-advisor/skills/chief-data-officer-advisor/scripts/data_asset_valuator.py:166-243 \u2014 before extracting anything, compare \u0060c-level-advisor/chief-data-officer-advisor/skills/chief-data-officer-advisor/scripts/data_asset_valuator.py\u0060 and \u0060c-level-advisor/skills/chief-data-officer-advisor/scripts/data_asset_valuator.py\u0060 as WHOLE FILES: this scan already matched 12 separate duplicated blocks between them, totalling at least 283 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The \u0060return\u0060 at the foot of the matched lines is the enclosing body\u0027s own terminal exit, not an early one: it moves with them unchanged, and each site calls the extracted unit from the position that \u0060return\u0060 occupied \u2014 no decision has to be handed back and re-acted on."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"c-level-advisor/chief-data-officer-advisor/skills/chief-data-officer-advisor/scripts/data_asset_valuator.py"},"region":{"startLine":166}}}],"partialFingerprints":{"codehealthFindingId/v1":"d7bd94074f632f776d34328e00a5cfb28180200e88914e1c48c3afa205c2aa41"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (74 lines \u00D7 2): c-level-advisor/chief-ai-officer-advisor/skills/chief-ai-officer-advisor/scripts/ai_cost_economics.py:173-246 | c-level-advisor/skills/chief-ai-officer-advisor/scripts/ai_cost_economics.py:173-246 \u2014 before extracting anything, compare \u0060c-level-advisor/chief-ai-officer-advisor/skills/chief-ai-officer-advisor/scripts/ai_cost_economics.py\u0060 and \u0060c-level-advisor/skills/chief-ai-officer-advisor/scripts/ai_cost_economics.py\u0060 as WHOLE FILES: this scan already matched 11 separate duplicated blocks between them, totalling at least 231 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"c-level-advisor/chief-ai-officer-advisor/skills/chief-ai-officer-advisor/scripts/ai_cost_economics.py"},"region":{"startLine":173}}}],"partialFingerprints":{"codehealthFindingId/v1":"a98c944e78f24275c7dcd055bd3a765ec3efce6380b1574c30e778eab0e79b8d"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (70 lines \u00D7 2): scripts/sync-hermes-skills.py:59-128 | scripts/sync-vibe-skills.py:72-141 \u2014 before extracting anything, compare \u0060scripts/sync-hermes-skills.py\u0060 and \u0060scripts/sync-vibe-skills.py\u0060 as WHOLE FILES: this scan already matched 6 separate duplicated blocks between them, totalling at least 165 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":"scripts/sync-hermes-skills.py"},"region":{"startLine":59}}}],"partialFingerprints":{"codehealthFindingId/v1":"4d5a773d3fe24248d9330920180042394a7099c15e49b4961905839143a6baf4"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (66 lines \u00D7 2): c-level-advisor/arquiteto-de-empresa/skills/arquiteto-de-empresa/scripts/okf_linter.py:56-121 | c-level-advisor/skills/arquiteto-de-empresa/scripts/okf_linter.py:56-121 \u2014 before extracting anything, compare \u0060c-level-advisor/arquiteto-de-empresa/skills/arquiteto-de-empresa/scripts/okf_linter.py\u0060 and \u0060c-level-advisor/skills/arquiteto-de-empresa/scripts/okf_linter.py\u0060 as WHOLE FILES: this scan already matched 7 separate duplicated blocks between them, totalling at least 147 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"c-level-advisor/arquiteto-de-empresa/skills/arquiteto-de-empresa/scripts/okf_linter.py"},"region":{"startLine":56}}}],"partialFingerprints":{"codehealthFindingId/v1":"eb0a772b3a6e823ffa638b8c2d2fcc74011b36dab7634da4c2f54c6edd84b901"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (65 lines \u00D7 2): c-level-advisor/skills/vpe-advisor/scripts/eng_hiring_funnel_calculator.py:126-190 | c-level-advisor/vpe-advisor/skills/vpe-advisor/scripts/eng_hiring_funnel_calculator.py:126-190 \u2014 before extracting anything, compare \u0060c-level-advisor/skills/vpe-advisor/scripts/eng_hiring_funnel_calculator.py\u0060 and \u0060c-level-advisor/vpe-advisor/skills/vpe-advisor/scripts/eng_hiring_funnel_calculator.py\u0060 as WHOLE FILES: this scan already matched 7 separate duplicated blocks between them, totalling at least 151 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"c-level-advisor/skills/vpe-advisor/scripts/eng_hiring_funnel_calculator.py"},"region":{"startLine":126}}}],"partialFingerprints":{"codehealthFindingId/v1":"a52d27accd47ac1977810c30fed72a78b041a221e58996297077ee0480fdac5b"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (64 lines \u00D7 2): c-level-advisor/chief-ai-officer-advisor/skills/chief-ai-officer-advisor/scripts/ai_risk_classifier.py:195-258 | c-level-advisor/skills/chief-ai-officer-advisor/scripts/ai_risk_classifier.py:195-258 \u2014 before extracting anything, compare \u0060c-level-advisor/chief-ai-officer-advisor/skills/chief-ai-officer-advisor/scripts/ai_risk_classifier.py\u0060 and \u0060c-level-advisor/skills/chief-ai-officer-advisor/scripts/ai_risk_classifier.py\u0060 as WHOLE FILES: this scan already matched 11 separate duplicated blocks between them, totalling at least 356 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The \u0060return\u0060 at the foot of the matched lines is the enclosing body\u0027s own terminal exit, not an early one: it moves with them unchanged, and each site calls the extracted unit from the position that \u0060return\u0060 occupied \u2014 no decision has to be handed back and re-acted on."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"c-level-advisor/chief-ai-officer-advisor/skills/chief-ai-officer-advisor/scripts/ai_risk_classifier.py"},"region":{"startLine":195}}}],"partialFingerprints":{"codehealthFindingId/v1":"670fed4fe09328f3ce74bdcc8bf4f266a69ba5553df49525f2f5b7eb816670e0"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (49\u201364 lines \u00D7 2): engineering-team/skills/aws-solution-architect/scripts/cost_optimizer.py:251-299 | engineering-team/skills/gcp-cloud-architect/scripts/cost_optimizer.py:279-342 \u2014 before extracting anything, compare \u0060engineering-team/skills/aws-solution-architect/scripts/cost_optimizer.py\u0060 and \u0060engineering-team/skills/gcp-cloud-architect/scripts/cost_optimizer.py\u0060 as WHOLE FILES: this scan already matched 6 separate duplicated blocks between them, totalling at least 200 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The \u0060return\u0060 at the foot of the matched lines is the enclosing body\u0027s own terminal exit, not an early one: it moves with them unchanged, and each site calls the extracted unit from the position that \u0060return\u0060 occupied \u2014 no decision has to be handed back and re-acted on."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/skills/aws-solution-architect/scripts/cost_optimizer.py"},"region":{"startLine":251}}}],"partialFingerprints":{"codehealthFindingId/v1":"65c2b2d3ccf8ff8afc0e00eba408e210f75c8a2886d5ddd829610b528d1a80ff"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (63 lines \u00D7 2): c-level-advisor/chief-data-officer-advisor/skills/chief-data-officer-advisor/scripts/data_asset_valuator.py:54-116 | c-level-advisor/skills/chief-data-officer-advisor/scripts/data_asset_valuator.py:54-116 \u2014 before extracting anything, compare \u0060c-level-advisor/chief-data-officer-advisor/skills/chief-data-officer-advisor/scripts/data_asset_valuator.py\u0060 and \u0060c-level-advisor/skills/chief-data-officer-advisor/scripts/data_asset_valuator.py\u0060 as WHOLE FILES: this scan already matched 12 separate duplicated blocks between them, totalling at least 283 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"c-level-advisor/chief-data-officer-advisor/skills/chief-data-officer-advisor/scripts/data_asset_valuator.py"},"region":{"startLine":54}}}],"partialFingerprints":{"codehealthFindingId/v1":"858410b2bec5ec664d8b63b520cad0558d61616c7aa5311540b2e096fda263f1"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (62 lines \u00D7 2): c-level-advisor/chief-data-officer-advisor/skills/chief-data-officer-advisor/scripts/data_product_strategy_picker.py:51-112 | c-level-advisor/skills/chief-data-officer-advisor/scripts/data_product_strategy_picker.py:51-112 \u2014 before extracting anything, compare \u0060c-level-advisor/chief-data-officer-advisor/skills/chief-data-officer-advisor/scripts/data_product_strategy_picker.py\u0060 and \u0060c-level-advisor/skills/chief-data-officer-advisor/scripts/data_product_strategy_picker.py\u0060 as WHOLE FILES: this scan already matched 9 separate duplicated blocks between them, totalling at least 282 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"c-level-advisor/chief-data-officer-advisor/skills/chief-data-officer-advisor/scripts/data_product_strategy_picker.py"},"region":{"startLine":51}}}],"partialFingerprints":{"codehealthFindingId/v1":"e68dde5756fd4147843b00547d24eeddba4b4dd608c977cda2d7481292b03ec1"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (56 lines \u00D7 2): c-level-advisor/chief-data-officer-advisor/skills/chief-data-officer-advisor/scripts/data_product_strategy_picker.py:199-254 | c-level-advisor/skills/chief-data-officer-advisor/scripts/data_product_strategy_picker.py:199-254 \u2014 before extracting anything, compare \u0060c-level-advisor/chief-data-officer-advisor/skills/chief-data-officer-advisor/scripts/data_product_strategy_picker.py\u0060 and \u0060c-level-advisor/skills/chief-data-officer-advisor/scripts/data_product_strategy_picker.py\u0060 as WHOLE FILES: this scan already matched 9 separate duplicated blocks between them, totalling at least 282 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The \u0060return\u0060 at the foot of the matched lines is the enclosing body\u0027s own terminal exit, not an early one: it moves with them unchanged, and each site calls the extracted unit from the position that \u0060return\u0060 occupied \u2014 no decision has to be handed back and re-acted on."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"c-level-advisor/chief-data-officer-advisor/skills/chief-data-officer-advisor/scripts/data_product_strategy_picker.py"},"region":{"startLine":199}}}],"partialFingerprints":{"codehealthFindingId/v1":"68798b52710055b187714fe0dda52360deab4662f81d01ef0ac757019fd640a3"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (52\u201353 lines \u00D7 2): markdown-html/skills/md-document/scripts/html_renderer.py:413-465 | markdown-html/skills/md-slides/scripts/deck_html_renderer.py:105-156 \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":"markdown-html/skills/md-document/scripts/html_renderer.py"},"region":{"startLine":413}}}],"partialFingerprints":{"codehealthFindingId/v1":"7749eb3e8268b652394547ac6efd0b347d07cca7227bc9d0d61467d0cd018380"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (31\u201352 lines \u00D7 3): ra-qm-team/skills/capa-officer/scripts/capa_tracker.py:475-505 | ra-qm-team/skills/quality-documentation-manager/scripts/document_validator.py:548-599 | ra-qm-team/skills/quality-manager-qmr/scripts/management_review_tracker.py:439-469 \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. Read the line range as the matched WINDOW rather than a finished unit: at \u0060ra-qm-team/skills/capa-officer/scripts/capa_tracker.py:475\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":"ra-qm-team/skills/capa-officer/scripts/capa_tracker.py"},"region":{"startLine":475}}}],"partialFingerprints":{"codehealthFindingId/v1":"8b28dd8594721a6067dac64b328b66acd7188f6826182f7f80f86a08b7296786"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (46\u201351 lines \u00D7 3): engineering/skills/skill-tester/scripts/security_scorer.py:308-358 | engineering/skills/skill-tester/scripts/security_scorer.py:369-414 | engineering/skills/skill-tester/scripts/security_scorer.py:425-472 \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 \u0060engineering/skills/skill-tester/scripts/security_scorer.py:308\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":"engineering/skills/skill-tester/scripts/security_scorer.py"},"region":{"startLine":308}}}],"partialFingerprints":{"codehealthFindingId/v1":"df1eaac07aeb61d1e384cfd264ac89ae18e27d74515cae339c5f22c196777f85"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (50 lines \u00D7 2): product-team/skills/product-skills/scripts/product_goal_router.py:154-203 | project-management/skills/pm-skills/scripts/pm_goal_router.py:126-175 \u2014 before extracting anything, compare \u0060product-team/skills/product-skills/scripts/product_goal_router.py\u0060 and \u0060project-management/skills/pm-skills/scripts/pm_goal_router.py\u0060 as WHOLE FILES: this scan already matched 9 separate duplicated blocks between them, totalling at least 130 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The \u0060return\u0060 at the foot of the matched lines is the enclosing body\u0027s own terminal exit, not an early one: it moves with them unchanged, and each site calls the extracted unit from the position that \u0060return\u0060 occupied \u2014 no decision has to be handed back and re-acted on."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"product-team/skills/product-skills/scripts/product_goal_router.py"},"region":{"startLine":154}}}],"partialFingerprints":{"codehealthFindingId/v1":"0512fe5c74d86aad7636ab21eefa75f75ae7da2f41b0af43fc33ee881fe5203e"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (48 lines \u00D7 2): c-level-advisor/chief-data-officer-advisor/skills/chief-data-officer-advisor/scripts/ai_training_data_audit.py:308-355 | c-level-advisor/skills/chief-data-officer-advisor/scripts/ai_training_data_audit.py:308-355 \u2014 before extracting anything, compare \u0060c-level-advisor/chief-data-officer-advisor/skills/chief-data-officer-advisor/scripts/ai_training_data_audit.py\u0060 and \u0060c-level-advisor/skills/chief-data-officer-advisor/scripts/ai_training_data_audit.py\u0060 as WHOLE FILES: this scan already matched 8 separate duplicated blocks between them, totalling at least 314 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"c-level-advisor/chief-data-officer-advisor/skills/chief-data-officer-advisor/scripts/ai_training_data_audit.py"},"region":{"startLine":308}}}],"partialFingerprints":{"codehealthFindingId/v1":"389ad71401c01fd525159050f458284b6f2c11c968c8cf65d273fa084a31abde"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (46 lines \u00D7 2): c-level-advisor/executive-mentor/skills/executive-mentor/scripts/decision_matrix_scorer.py:442-487 | c-level-advisor/executive-mentor/skills/executive-mentor/scripts/stakeholder_mapper.py:498-543 \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":"c-level-advisor/executive-mentor/skills/executive-mentor/scripts/decision_matrix_scorer.py"},"region":{"startLine":442}}}],"partialFingerprints":{"codehealthFindingId/v1":"7d54a7a272e4cd0430bc059ff07bb5d793a270686942eca99f5d80e20bfa768d"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (45 lines \u00D7 2): c-level-advisor/arquiteto-de-empresa/skills/arquiteto-de-empresa/scripts/scaffold_bundle.py:158-202 | c-level-advisor/skills/arquiteto-de-empresa/scripts/scaffold_bundle.py:158-202 \u2014 before extracting anything, compare \u0060c-level-advisor/arquiteto-de-empresa/skills/arquiteto-de-empresa/scripts/scaffold_bundle.py\u0060 and \u0060c-level-advisor/skills/arquiteto-de-empresa/scripts/scaffold_bundle.py\u0060 as WHOLE FILES: this scan already matched 7 separate duplicated blocks between them, totalling at least 108 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The \u0060return\u0060 at the foot of the matched lines is the enclosing body\u0027s own terminal exit, not an early one: it moves with them unchanged, and each site calls the extracted unit from the position that \u0060return\u0060 occupied \u2014 no decision has to be handed back and re-acted on."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"c-level-advisor/arquiteto-de-empresa/skills/arquiteto-de-empresa/scripts/scaffold_bundle.py"},"region":{"startLine":158}}}],"partialFingerprints":{"codehealthFindingId/v1":"f13aa16ea3cd6a075b0244f319a2b4fe0057508c2a208062e62d672d13dbd435"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (44 lines \u00D7 2): c-level-advisor/skills/vpe-advisor/scripts/eng_team_structure_designer.py:196-239 | c-level-advisor/vpe-advisor/skills/vpe-advisor/scripts/eng_team_structure_designer.py:196-239 \u2014 before extracting anything, compare \u0060c-level-advisor/skills/vpe-advisor/scripts/eng_team_structure_designer.py\u0060 and \u0060c-level-advisor/vpe-advisor/skills/vpe-advisor/scripts/eng_team_structure_designer.py\u0060 as WHOLE FILES: this scan already matched 11 separate duplicated blocks between them, totalling at least 223 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The \u0060return\u0060 at the foot of the matched lines is the enclosing body\u0027s own terminal exit, not an early one: it moves with them unchanged, and each site calls the extracted unit from the position that \u0060return\u0060 occupied \u2014 no decision has to be handed back and re-acted on."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"c-level-advisor/skills/vpe-advisor/scripts/eng_team_structure_designer.py"},"region":{"startLine":196}}}],"partialFingerprints":{"codehealthFindingId/v1":"775312c47680f16fc2064ae593799d67ca046de62fb70b8b781a794d8cc2c49b"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (44 lines \u00D7 2): ra-qm-team/compliance-team-eu-ai-act/skills/eu-ai-act-specialist/scripts/conformity_assessment_planner.py:139-182 | ra-qm-team/skills/eu-ai-act-specialist/scripts/conformity_assessment_planner.py:139-182 \u2014 before extracting anything, compare \u0060ra-qm-team/compliance-team-eu-ai-act/skills/eu-ai-act-specialist/scripts/conformity_assessment_planner.py\u0060 and \u0060ra-qm-team/skills/eu-ai-act-specialist/scripts/conformity_assessment_planner.py\u0060 as WHOLE FILES: this scan already matched 13 separate duplicated blocks between them, totalling at least 187 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"ra-qm-team/compliance-team-eu-ai-act/skills/eu-ai-act-specialist/scripts/conformity_assessment_planner.py"},"region":{"startLine":139}}}],"partialFingerprints":{"codehealthFindingId/v1":"6c233b61d423dfe8b1cf542a585fef731ecab493cfeadad9c5bfbaec27992b3b"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (43 lines \u00D7 2): c-level-advisor/chief-data-officer-advisor/skills/chief-data-officer-advisor/scripts/data_asset_valuator.py:120-162 | c-level-advisor/skills/chief-data-officer-advisor/scripts/data_asset_valuator.py:120-162 \u2014 before extracting anything, compare \u0060c-level-advisor/chief-data-officer-advisor/skills/chief-data-officer-advisor/scripts/data_asset_valuator.py\u0060 and \u0060c-level-advisor/skills/chief-data-officer-advisor/scripts/data_asset_valuator.py\u0060 as WHOLE FILES: this scan already matched 12 separate duplicated blocks between them, totalling at least 283 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"c-level-advisor/chief-data-officer-advisor/skills/chief-data-officer-advisor/scripts/data_asset_valuator.py"},"region":{"startLine":120}}}],"partialFingerprints":{"codehealthFindingId/v1":"b8e92fd46415017befcb0e1a92edbe8396a27e394cb3df05ed43d0eaab9e46b7"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (43 lines \u00D7 2): c-level-advisor/general-counsel-advisor/skills/general-counsel-advisor/scripts/contract_risk_scanner.py:315-357 | c-level-advisor/skills/general-counsel-advisor/scripts/contract_risk_scanner.py:315-357 \u2014 before extracting anything, compare \u0060c-level-advisor/general-counsel-advisor/skills/general-counsel-advisor/scripts/contract_risk_scanner.py\u0060 and \u0060c-level-advisor/skills/general-counsel-advisor/scripts/contract_risk_scanner.py\u0060 as WHOLE FILES: this scan already matched 5 separate duplicated blocks between them, totalling at least 106 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"c-level-advisor/general-counsel-advisor/skills/general-counsel-advisor/scripts/contract_risk_scanner.py"},"region":{"startLine":315}}}],"partialFingerprints":{"codehealthFindingId/v1":"5c1033ddbe65d26ef96b71462dc7bcc64970ebea902551272beceeb058b32bab"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (42 lines \u00D7 2): c-level-advisor/chief-ai-officer-advisor/skills/chief-ai-officer-advisor/scripts/model_buildvsbuy_calculator.py:227-268 | c-level-advisor/skills/chief-ai-officer-advisor/scripts/model_buildvsbuy_calculator.py:227-268 \u2014 before extracting anything, compare \u0060c-level-advisor/chief-ai-officer-advisor/skills/chief-ai-officer-advisor/scripts/model_buildvsbuy_calculator.py\u0060 and \u0060c-level-advisor/skills/chief-ai-officer-advisor/scripts/model_buildvsbuy_calculator.py\u0060 as WHOLE FILES: this scan already matched 12 separate duplicated blocks between them, totalling at least 251 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"c-level-advisor/chief-ai-officer-advisor/skills/chief-ai-officer-advisor/scripts/model_buildvsbuy_calculator.py"},"region":{"startLine":227}}}],"partialFingerprints":{"codehealthFindingId/v1":"a8f739d31e4e44a5355869ab1542f4f67a2d46ad81c9f7ae0c7e3a2ee7198fd3"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (41 lines \u00D7 2): c-level-advisor/chief-ai-officer-advisor/skills/chief-ai-officer-advisor/scripts/ai_cost_economics.py:129-169 | c-level-advisor/skills/chief-ai-officer-advisor/scripts/ai_cost_economics.py:129-169 \u2014 before extracting anything, compare \u0060c-level-advisor/chief-ai-officer-advisor/skills/chief-ai-officer-advisor/scripts/ai_cost_economics.py\u0060 and \u0060c-level-advisor/skills/chief-ai-officer-advisor/scripts/ai_cost_economics.py\u0060 as WHOLE FILES: this scan already matched 11 separate duplicated blocks between them, totalling at least 231 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"c-level-advisor/chief-ai-officer-advisor/skills/chief-ai-officer-advisor/scripts/ai_cost_economics.py"},"region":{"startLine":129}}}],"partialFingerprints":{"codehealthFindingId/v1":"4ba78983bff59647acdbd866c9f180d91ba0f434e517d5c43c0e26679acac0ea"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (41 lines \u00D7 2): marketing-skill/skills/free-tool-strategy/scripts/tool_roi_estimator.py:333-373 | marketing-skill/skills/referral-program/scripts/referral_roi_calculator.py:356-396 \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":"marketing-skill/skills/free-tool-strategy/scripts/tool_roi_estimator.py"},"region":{"startLine":333}}}],"partialFingerprints":{"codehealthFindingId/v1":"aee16a012061f2641a4871ef2547c511176a2198a6dd70b049b7b335448c1640"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (35\u201340 lines \u00D7 3): engineering/memory-engineering/skills/memory-engineering/scripts/forgetting_policy_linter.py:348-387 | engineering/memory-engineering/skills/memory-engineering/scripts/memory_architecture_picker.py:343-377 | engineering/memory-engineering/skills/memory-engineering/scripts/memory_cost_profiler.py:314-348 \u2014 the copies sit in sibling files of one directory, so a shared home is within easy reach: extract the block into a single shared function the call sites can all reach \u2014 a file they already depend on, or a new one alongside them \u2014 and call it from all 3 call sites, so a change lands once. Read the line range as the matched WINDOW rather than a finished unit: at \u0060engineering/memory-engineering/skills/memory-engineering/scripts/forgetting_policy_linter.py:348\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":"engineering/memory-engineering/skills/memory-engineering/scripts/forgetting_policy_linter.py"},"region":{"startLine":348}}}],"partialFingerprints":{"codehealthFindingId/v1":"dfe73fa597f106a2d346e4d85c3ded4772dd389f7c16827604bad5ca72815498"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (39 lines \u00D7 2): c-level-advisor/skills/vpe-advisor/scripts/eng_team_structure_designer.py:148-186 | c-level-advisor/vpe-advisor/skills/vpe-advisor/scripts/eng_team_structure_designer.py:148-186 \u2014 before extracting anything, compare \u0060c-level-advisor/skills/vpe-advisor/scripts/eng_team_structure_designer.py\u0060 and \u0060c-level-advisor/vpe-advisor/skills/vpe-advisor/scripts/eng_team_structure_designer.py\u0060 as WHOLE FILES: this scan already matched 11 separate duplicated blocks between them, totalling at least 223 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"c-level-advisor/skills/vpe-advisor/scripts/eng_team_structure_designer.py"},"region":{"startLine":148}}}],"partialFingerprints":{"codehealthFindingId/v1":"73cb0e8d921b9252c269fe37f21fb26f124cf1f6779602d494b47c872d847d9a"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (4\u201339 lines \u00D7 3): business-growth/skills/sales-engineer/scripts/poc_planner.py:629-632 | engineering/chaos-engineering/skills/chaos-engineering/scripts/experiment_designer.py:70-108 | engineering/skills/chaos-engineering/scripts/experiment_designer.py:70-108 \u2014 before extracting anything, compare \u0060engineering/chaos-engineering/skills/chaos-engineering/scripts/experiment_designer.py\u0060 and \u0060engineering/skills/chaos-engineering/scripts/experiment_designer.py\u0060 as WHOLE FILES: this scan already matched 7 separate duplicated blocks between them, totalling at least 111 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The \u0060return\u0060 at the foot of the matched lines is the enclosing body\u0027s own terminal exit, not an early one: it moves with them unchanged, and each site calls the extracted unit from the position that \u0060return\u0060 occupied \u2014 no decision has to be handed back and re-acted on."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"business-growth/skills/sales-engineer/scripts/poc_planner.py"},"region":{"startLine":629}}}],"partialFingerprints":{"codehealthFindingId/v1":"e0428596ea0d0f7963394e35e7206c2de00b85f70b33b592f7fe2e44cd1f430f"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (38 lines \u00D7 2): c-level-advisor/chief-ai-officer-advisor/skills/chief-ai-officer-advisor/scripts/ai_risk_classifier.py:301-338 | c-level-advisor/skills/chief-ai-officer-advisor/scripts/ai_risk_classifier.py:301-338 \u2014 before extracting anything, compare \u0060c-level-advisor/chief-ai-officer-advisor/skills/chief-ai-officer-advisor/scripts/ai_risk_classifier.py\u0060 and \u0060c-level-advisor/skills/chief-ai-officer-advisor/scripts/ai_risk_classifier.py\u0060 as WHOLE FILES: this scan already matched 11 separate duplicated blocks between them, totalling at least 356 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The \u0060return\u0060 at the foot of the matched lines is the enclosing body\u0027s own terminal exit, not an early one: it moves with them unchanged, and each site calls the extracted unit from the position that \u0060return\u0060 occupied \u2014 no decision has to be handed back and re-acted on."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"c-level-advisor/chief-ai-officer-advisor/skills/chief-ai-officer-advisor/scripts/ai_risk_classifier.py"},"region":{"startLine":301}}}],"partialFingerprints":{"codehealthFindingId/v1":"d23ae3e3279d6d7b8d457c33a25b8a637f893d427a995eef8986c24127ada160"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (36\u201337 lines \u00D7 3): engineering-team/skills/senior-backend/scripts/backend_decision_engine.py:192-227 | engineering-team/skills/senior-frontend/scripts/frontend_decision_engine.py:146-181 | engineering-team/skills/senior-fullstack/scripts/fullstack_decision_engine.py:188-224 \u2014 before extracting anything, compare \u0060engineering-team/skills/senior-backend/scripts/backend_decision_engine.py\u0060 and \u0060engineering-team/skills/senior-frontend/scripts/frontend_decision_engine.py\u0060 as WHOLE FILES: this scan already matched 6 separate duplicated blocks between them, totalling at least 99 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. Read the line range as the matched WINDOW rather than a finished unit: at \u0060engineering-team/skills/senior-fullstack/scripts/fullstack_decision_engine.py:188\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":"engineering-team/skills/senior-backend/scripts/backend_decision_engine.py"},"region":{"startLine":192}}}],"partialFingerprints":{"codehealthFindingId/v1":"ad7cf7f562fd253760088e971ebf6ac7f86428e4c5329127e00b276a740ca2a7"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (37 lines \u00D7 2): c-level-advisor/chief-customer-officer-advisor/skills/chief-customer-officer-advisor/scripts/retention_decomposition_analyzer.py:141-177 | c-level-advisor/skills/chief-customer-officer-advisor/scripts/retention_decomposition_analyzer.py:141-177 \u2014 before extracting anything, compare \u0060c-level-advisor/chief-customer-officer-advisor/skills/chief-customer-officer-advisor/scripts/retention_decomposition_analyzer.py\u0060 and \u0060c-level-advisor/skills/chief-customer-officer-advisor/scripts/retention_decomposition_analyzer.py\u0060 as WHOLE FILES: this scan already matched 9 separate duplicated blocks between them, totalling at least 171 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"c-level-advisor/chief-customer-officer-advisor/skills/chief-customer-officer-advisor/scripts/retention_decomposition_analyzer.py"},"region":{"startLine":141}}}],"partialFingerprints":{"codehealthFindingId/v1":"c680c550e128bc728f5edbe32f501f10b1f47cae4121105be0ceef22d759890e"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (32\u201337 lines \u00D7 2): engineering-team/skills/aws-solution-architect/scripts/cost_optimizer.py:25-61 | engineering-team/skills/gcp-cloud-architect/scripts/cost_optimizer.py:28-59 \u2014 before extracting anything, compare \u0060engineering-team/skills/aws-solution-architect/scripts/cost_optimizer.py\u0060 and \u0060engineering-team/skills/gcp-cloud-architect/scripts/cost_optimizer.py\u0060 as WHOLE FILES: this scan already matched 6 separate duplicated blocks between them, totalling at least 200 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/skills/aws-solution-architect/scripts/cost_optimizer.py"},"region":{"startLine":25}}}],"partialFingerprints":{"codehealthFindingId/v1":"a121037fda5637a325e9c0eae4131a93147fe4dba87a02dcd7e6137e9208ee5b"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (37 lines \u00D7 2): engineering-team/skills/senior-secops/scripts/compliance_checker.py:1038-1074 | engineering-team/skills/senior-secops/scripts/security_scanner.py:402-438 \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":"engineering-team/skills/senior-secops/scripts/compliance_checker.py"},"region":{"startLine":1038}}}],"partialFingerprints":{"codehealthFindingId/v1":"0f09928cdc8d7d388a9d0e3b1780bece73c1a265a8e8346ff333b94b85d5519c"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (37 lines \u00D7 2): ra-qm-team/compliance-team-iso42001/skills/iso42001-specialist/scripts/aims_audit_scheduler.py:140-176 | ra-qm-team/skills/iso42001-specialist/scripts/aims_audit_scheduler.py:140-176 \u2014 before extracting anything, compare \u0060ra-qm-team/compliance-team-iso42001/skills/iso42001-specialist/scripts/aims_audit_scheduler.py\u0060 and \u0060ra-qm-team/skills/iso42001-specialist/scripts/aims_audit_scheduler.py\u0060 as WHOLE FILES: this scan already matched 9 separate duplicated blocks between them, totalling at least 151 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. Read the line range as the matched WINDOW rather than a finished unit: at \u0060ra-qm-team/compliance-team-iso42001/skills/iso42001-specialist/scripts/aims_audit_scheduler.py:140\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":"ra-qm-team/compliance-team-iso42001/skills/iso42001-specialist/scripts/aims_audit_scheduler.py"},"region":{"startLine":140}}}],"partialFingerprints":{"codehealthFindingId/v1":"33e730a656ac41e0d7b42d5a3455569038dbafeb2c1e7a472e12e42aa6fdcb29"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (33\u201336 lines \u00D7 5): engineering/skills/api-design-reviewer/scripts/api_scorecard.py:186-221 | engineering/skills/api-design-reviewer/scripts/api_scorecard.py:564-597 | engineering/skills/api-design-reviewer/scripts/api_scorecard.py:824-856 | engineering/skills/api-design-reviewer/scripts/api_scorecard.py:1000-1032 | engineering/skills/api-design-reviewer/scripts/api_scorecard.py:1264-1296 \u2014 all 5 copies are in the same file, so extract the block into one function there and call it from every one of those sites \u2014 resolving only two of them leaves the rest to drift apart the first time one is edited."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/api-design-reviewer/scripts/api_scorecard.py"},"region":{"startLine":186}}}],"partialFingerprints":{"codehealthFindingId/v1":"b2d1871d131101bf8a43855f66c96bfca3b11bee9b6d5f9691f1e228304157fe"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (35\u201336 lines \u00D7 2): engineering-team/skills/senior-secops/scripts/compliance_checker.py:625-660 | engineering-team/skills/senior-secops/scripts/compliance_checker.py:847-881 \u2014 both copies are in the same file, so extract the block into one function there and call it from each site \u2014 the copies drift apart the first time only one of them is edited. Read the line range as the matched WINDOW rather than a finished unit: at \u0060engineering-team/skills/senior-secops/scripts/compliance_checker.py:625\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":"engineering-team/skills/senior-secops/scripts/compliance_checker.py"},"region":{"startLine":625}}}],"partialFingerprints":{"codehealthFindingId/v1":"b0139f524b6f5fc9d9e1d11a3937139c4d668815bd8cf1acd9dc996307d37be5"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (35 lines \u00D7 2): c-level-advisor/chief-ai-officer-advisor/skills/chief-ai-officer-advisor/scripts/ai_risk_classifier.py:368-402 | c-level-advisor/skills/chief-ai-officer-advisor/scripts/ai_risk_classifier.py:368-402 \u2014 before extracting anything, compare \u0060c-level-advisor/chief-ai-officer-advisor/skills/chief-ai-officer-advisor/scripts/ai_risk_classifier.py\u0060 and \u0060c-level-advisor/skills/chief-ai-officer-advisor/scripts/ai_risk_classifier.py\u0060 as WHOLE FILES: this scan already matched 11 separate duplicated blocks between them, totalling at least 356 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"c-level-advisor/chief-ai-officer-advisor/skills/chief-ai-officer-advisor/scripts/ai_risk_classifier.py"},"region":{"startLine":368}}}],"partialFingerprints":{"codehealthFindingId/v1":"0392fbb426f2247a3b3788bc1ffd745267f7f66577d5111b194ff044ae422e95"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (35 lines \u00D7 2): c-level-advisor/skills/vpe-advisor/scripts/eng_team_structure_designer.py:51-85 | c-level-advisor/vpe-advisor/skills/vpe-advisor/scripts/eng_team_structure_designer.py:51-85 \u2014 before extracting anything, compare \u0060c-level-advisor/skills/vpe-advisor/scripts/eng_team_structure_designer.py\u0060 and \u0060c-level-advisor/vpe-advisor/skills/vpe-advisor/scripts/eng_team_structure_designer.py\u0060 as WHOLE FILES: this scan already matched 11 separate duplicated blocks between them, totalling at least 223 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"c-level-advisor/skills/vpe-advisor/scripts/eng_team_structure_designer.py"},"region":{"startLine":51}}}],"partialFingerprints":{"codehealthFindingId/v1":"989b01cac95fa30fe22ef077d2e69bd931ab58701f8fcfccbf34e5c2c63f63fd"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (35 lines \u00D7 2): engineering/chaos-engineering/skills/chaos-engineering/scripts/blast_radius_calculator.py:15-49 | engineering/skills/chaos-engineering/scripts/blast_radius_calculator.py:15-49 \u2014 before extracting anything, compare \u0060engineering/chaos-engineering/skills/chaos-engineering/scripts/blast_radius_calculator.py\u0060 and \u0060engineering/skills/chaos-engineering/scripts/blast_radius_calculator.py\u0060 as WHOLE FILES: this scan already matched 3 separate duplicated blocks between them, totalling at least 85 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/chaos-engineering/skills/chaos-engineering/scripts/blast_radius_calculator.py"},"region":{"startLine":15}}}],"partialFingerprints":{"codehealthFindingId/v1":"3de250bd1ee945ab0cc7c60ff82ccce7d77cdf66d343469b1b0f8ebe94469aca"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (35 lines \u00D7 2): engineering/kubernetes-operator/skills/kubernetes-operator/scripts/reconcile_lint.py:63-97 | engineering/skills/kubernetes-operator/scripts/reconcile_lint.py:63-97 \u2014 before extracting anything, compare \u0060engineering/kubernetes-operator/skills/kubernetes-operator/scripts/reconcile_lint.py\u0060 and \u0060engineering/skills/kubernetes-operator/scripts/reconcile_lint.py\u0060 as WHOLE FILES: this scan already matched 9 separate duplicated blocks between them, totalling at least 127 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The \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":"engineering/kubernetes-operator/skills/kubernetes-operator/scripts/reconcile_lint.py"},"region":{"startLine":63}}}],"partialFingerprints":{"codehealthFindingId/v1":"5b4c0fa3a9b52f55cc6b16daa96d0a66950a20a3636a0c125a3a8eab76b560ee"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (35 lines \u00D7 2): engineering/skills/slo-architect/scripts/slo_review.py:77-111 | engineering/slo-architect/skills/slo-architect/scripts/slo_review.py:77-111 \u2014 before extracting anything, compare \u0060engineering/skills/slo-architect/scripts/slo_review.py\u0060 and \u0060engineering/slo-architect/skills/slo-architect/scripts/slo_review.py\u0060 as WHOLE FILES: this scan already matched 9 separate duplicated blocks between them, totalling at least 103 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The \u0060return\u0060 at the foot of the matched lines is the enclosing body\u0027s own terminal exit, not an early one: it moves with them unchanged, and each site calls the extracted unit from the position that \u0060return\u0060 occupied \u2014 no decision has to be handed back and re-acted on."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/slo-architect/scripts/slo_review.py"},"region":{"startLine":77}}}],"partialFingerprints":{"codehealthFindingId/v1":"a6aea375539bbfa64f142038796fcd73db47d08d4daec8332ed5de7ce5987fc8"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (32\u201334 lines \u00D7 3): engineering-team/skills/aws-solution-architect/scripts/cost_optimizer.py:117-150 | engineering-team/skills/azure-cloud-architect/scripts/cost_optimizer.py:192-225 | engineering-team/skills/gcp-cloud-architect/scripts/cost_optimizer.py:143-174 \u2014 before extracting anything, compare \u0060engineering-team/skills/aws-solution-architect/scripts/cost_optimizer.py\u0060 and \u0060engineering-team/skills/gcp-cloud-architect/scripts/cost_optimizer.py\u0060 as WHOLE FILES: this scan already matched 6 separate duplicated blocks between them, totalling at least 200 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The \u0060return\u0060 at the foot of the matched lines is the enclosing body\u0027s own terminal exit, not an early one: it moves with them unchanged, and each site calls the extracted unit from the position that \u0060return\u0060 occupied \u2014 no decision has to be handed back and re-acted on."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/skills/aws-solution-architect/scripts/cost_optimizer.py"},"region":{"startLine":117}}}],"partialFingerprints":{"codehealthFindingId/v1":"baec9d6c8835e731b1d73fae56636c68013420e4e79fb20d233a5f1fffaa43f2"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (34 lines \u00D7 2): c-level-advisor/chief-ai-officer-advisor/skills/chief-ai-officer-advisor/scripts/ai_cost_economics.py:92-125 | c-level-advisor/skills/chief-ai-officer-advisor/scripts/ai_cost_economics.py:92-125 \u2014 before extracting anything, compare \u0060c-level-advisor/chief-ai-officer-advisor/skills/chief-ai-officer-advisor/scripts/ai_cost_economics.py\u0060 and \u0060c-level-advisor/skills/chief-ai-officer-advisor/scripts/ai_cost_economics.py\u0060 as WHOLE FILES: this scan already matched 11 separate duplicated blocks between them, totalling at least 231 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"c-level-advisor/chief-ai-officer-advisor/skills/chief-ai-officer-advisor/scripts/ai_cost_economics.py"},"region":{"startLine":92}}}],"partialFingerprints":{"codehealthFindingId/v1":"94346ef472922e48c8069f4a7bef62d6b92702e2f696064429378b33fa777f09"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (34 lines \u00D7 2): c-level-advisor/chief-data-officer-advisor/skills/chief-data-officer-advisor/scripts/data_product_strategy_picker.py:280-313 | c-level-advisor/skills/chief-data-officer-advisor/scripts/data_product_strategy_picker.py:280-313 \u2014 before extracting anything, compare \u0060c-level-advisor/chief-data-officer-advisor/skills/chief-data-officer-advisor/scripts/data_product_strategy_picker.py\u0060 and \u0060c-level-advisor/skills/chief-data-officer-advisor/scripts/data_product_strategy_picker.py\u0060 as WHOLE FILES: this scan already matched 9 separate duplicated blocks between them, totalling at least 282 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The \u0060return\u0060 at the foot of the matched lines is the enclosing body\u0027s own terminal exit, not an early one: it moves with them unchanged, and each site calls the extracted unit from the position that \u0060return\u0060 occupied \u2014 no decision has to be handed back and re-acted on."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"c-level-advisor/chief-data-officer-advisor/skills/chief-data-officer-advisor/scripts/data_product_strategy_picker.py"},"region":{"startLine":280}}}],"partialFingerprints":{"codehealthFindingId/v1":"4103f4cc4e8b07ad078399a6bfa97f12db7fcdf417d9b464836c2ce03490f78d"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (34 lines \u00D7 2): c-level-advisor/skills/vpe-advisor/scripts/eng_hiring_funnel_calculator.py:210-243 | c-level-advisor/vpe-advisor/skills/vpe-advisor/scripts/eng_hiring_funnel_calculator.py:210-243 \u2014 before extracting anything, compare \u0060c-level-advisor/skills/vpe-advisor/scripts/eng_hiring_funnel_calculator.py\u0060 and \u0060c-level-advisor/vpe-advisor/skills/vpe-advisor/scripts/eng_hiring_funnel_calculator.py\u0060 as WHOLE FILES: this scan already matched 7 separate duplicated blocks between them, totalling at least 151 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The \u0060return\u0060 at the foot of the matched lines is the enclosing body\u0027s own terminal exit, not an early one: it moves with them unchanged, and each site calls the extracted unit from the position that \u0060return\u0060 occupied \u2014 no decision has to be handed back and re-acted on."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"c-level-advisor/skills/vpe-advisor/scripts/eng_hiring_funnel_calculator.py"},"region":{"startLine":210}}}],"partialFingerprints":{"codehealthFindingId/v1":"36d2d8a39e7161a40a280505cba0befb20147b69c6463397135b4203d11f5037"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (34 lines \u00D7 2): engineering/chaos-engineering/skills/chaos-engineering/scripts/blast_radius_calculator.py:73-106 | engineering/skills/chaos-engineering/scripts/blast_radius_calculator.py:73-106 \u2014 before extracting anything, compare \u0060engineering/chaos-engineering/skills/chaos-engineering/scripts/blast_radius_calculator.py\u0060 and \u0060engineering/skills/chaos-engineering/scripts/blast_radius_calculator.py\u0060 as WHOLE FILES: this scan already matched 3 separate duplicated blocks between them, totalling at least 85 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/chaos-engineering/skills/chaos-engineering/scripts/blast_radius_calculator.py"},"region":{"startLine":73}}}],"partialFingerprints":{"codehealthFindingId/v1":"577c6a3563775f68b35bcf969ba34019039bfab7611409e7929dca9be6df6c47"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (33 lines \u00D7 3): c-level-advisor/skills/ciso-advisor/scripts/compliance_tracker.py:274-306 | c-level-advisor/skills/ciso-advisor/scripts/compliance_tracker.py:343-375 | c-level-advisor/skills/ciso-advisor/scripts/compliance_tracker.py:389-421 \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 \u0060c-level-advisor/skills/ciso-advisor/scripts/compliance_tracker.py:274\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":"c-level-advisor/skills/ciso-advisor/scripts/compliance_tracker.py"},"region":{"startLine":274}}}],"partialFingerprints":{"codehealthFindingId/v1":"d9b59c2ce46aa2fea5850c3663fd6494894e63585d193665c1fa54be9a8febbb"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (33 lines \u00D7 2): c-level-advisor/arquiteto-de-empresa/skills/arquiteto-de-empresa/scripts/index_generator.py:79-111 | c-level-advisor/skills/arquiteto-de-empresa/scripts/index_generator.py:79-111 \u2014 before extracting anything, compare \u0060c-level-advisor/arquiteto-de-empresa/skills/arquiteto-de-empresa/scripts/index_generator.py\u0060 and \u0060c-level-advisor/skills/arquiteto-de-empresa/scripts/index_generator.py\u0060 as WHOLE FILES: this scan already matched 10 separate duplicated blocks between them, totalling at least 135 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"c-level-advisor/arquiteto-de-empresa/skills/arquiteto-de-empresa/scripts/index_generator.py"},"region":{"startLine":79}}}],"partialFingerprints":{"codehealthFindingId/v1":"dfab492adf53babe4d5aa688c2027a9594ced05934a2d442ed1e6c02c79e7bff"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (33 lines \u00D7 2): c-level-advisor/chief-customer-officer-advisor/skills/chief-customer-officer-advisor/scripts/retention_decomposition_analyzer.py:181-213 | c-level-advisor/skills/chief-customer-officer-advisor/scripts/retention_decomposition_analyzer.py:181-213 \u2014 before extracting anything, compare \u0060c-level-advisor/chief-customer-officer-advisor/skills/chief-customer-officer-advisor/scripts/retention_decomposition_analyzer.py\u0060 and \u0060c-level-advisor/skills/chief-customer-officer-advisor/scripts/retention_decomposition_analyzer.py\u0060 as WHOLE FILES: this scan already matched 9 separate duplicated blocks between them, totalling at least 171 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"c-level-advisor/chief-customer-officer-advisor/skills/chief-customer-officer-advisor/scripts/retention_decomposition_analyzer.py"},"region":{"startLine":181}}}],"partialFingerprints":{"codehealthFindingId/v1":"c808685ac11dc5eb0e50e7dbf6afed3336937f4488d3377d27771d6c8a814b57"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (30\u201333 lines \u00D7 2): engineering-team/skills/senior-data-engineer/scripts/data_quality_validator.py:1553-1582 | engineering-team/skills/senior-data-engineer/scripts/etl_performance_optimizer.py:1593-1625 \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. 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":"engineering-team/skills/senior-data-engineer/scripts/data_quality_validator.py"},"region":{"startLine":1553}}}],"partialFingerprints":{"codehealthFindingId/v1":"f020de3ce443b8707f2c77e17d4688f0bc3fe917d7c7e7f2a86a2df4bfb90c70"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (33 lines \u00D7 2): ra-qm-team/compliance-team-eu-ai-act/skills/eu-ai-act-specialist/scripts/conformity_assessment_planner.py:240-272 | ra-qm-team/skills/eu-ai-act-specialist/scripts/conformity_assessment_planner.py:240-272 \u2014 before extracting anything, compare \u0060ra-qm-team/compliance-team-eu-ai-act/skills/eu-ai-act-specialist/scripts/conformity_assessment_planner.py\u0060 and \u0060ra-qm-team/skills/eu-ai-act-specialist/scripts/conformity_assessment_planner.py\u0060 as WHOLE FILES: this scan already matched 13 separate duplicated blocks between them, totalling at least 187 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"ra-qm-team/compliance-team-eu-ai-act/skills/eu-ai-act-specialist/scripts/conformity_assessment_planner.py"},"region":{"startLine":240}}}],"partialFingerprints":{"codehealthFindingId/v1":"795367fc257c4ddff287ed591f836c6fbd4d323ee2410f2aa91129fa9091b16e"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (31\u201332 lines \u00D7 2): engineering-team/skills/aws-solution-architect/scripts/cost_optimizer.py:64-95 | engineering-team/skills/gcp-cloud-architect/scripts/cost_optimizer.py:62-92 \u2014 before extracting anything, compare \u0060engineering-team/skills/aws-solution-architect/scripts/cost_optimizer.py\u0060 and \u0060engineering-team/skills/gcp-cloud-architect/scripts/cost_optimizer.py\u0060 as WHOLE FILES: this scan already matched 6 separate duplicated blocks between them, totalling at least 200 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/skills/aws-solution-architect/scripts/cost_optimizer.py"},"region":{"startLine":64}}}],"partialFingerprints":{"codehealthFindingId/v1":"95490831d87db97db5dd91ceeeb73808f00f0bdfd7be13766668738ec1f1ca88"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (25\u201331 lines \u00D7 3): engineering/docker-development/skills/docker-development/scripts/compose_validator.py:314-339 | engineering/terraform-patterns/skills/terraform-patterns/scripts/tf_module_analyzer.py:374-404 | engineering/terraform-patterns/skills/terraform-patterns/scripts/tf_security_scanner.py:490-514 \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":"engineering/docker-development/skills/docker-development/scripts/compose_validator.py"},"region":{"startLine":314}}}],"partialFingerprints":{"codehealthFindingId/v1":"2d4cb3cbf4e88961bf1c06366feb71a2b000dcd052b4a2809ac9ffc7cd82488c"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (31 lines \u00D7 2): c-level-advisor/chief-customer-officer-advisor/skills/chief-customer-officer-advisor/scripts/customer_segmentation_designer.py:187-217 | c-level-advisor/skills/chief-customer-officer-advisor/scripts/customer_segmentation_designer.py:187-217 \u2014 before extracting anything, compare \u0060c-level-advisor/chief-customer-officer-advisor/skills/chief-customer-officer-advisor/scripts/customer_segmentation_designer.py\u0060 and \u0060c-level-advisor/skills/chief-customer-officer-advisor/scripts/customer_segmentation_designer.py\u0060 as WHOLE FILES: this scan already matched 11 separate duplicated blocks between them, totalling at least 146 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"c-level-advisor/chief-customer-officer-advisor/skills/chief-customer-officer-advisor/scripts/customer_segmentation_designer.py"},"region":{"startLine":187}}}],"partialFingerprints":{"codehealthFindingId/v1":"91c56349177806a23735323fbe46c006c6b1eafa9b1a34105a2a0c9f7bda2bd7"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (18\u201331 lines \u00D7 2): engineering/skills/api-design-reviewer/scripts/breaking_change_detector.py:1013-1043 | engineering/skills/dependency-auditor/scripts/license_checker.py:944-961 \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 \u0060engineering/skills/api-design-reviewer/scripts/breaking_change_detector.py:1013\u0060 it does not close everything it opens, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that. Note that the copies do not run to the end of the range shown: their LAST lines are different code, not the same code under different names \u2014 the matched region ends inside that line. Extract the lines above it, and read the last line of each site separately. \u2605 These copies have DRIFTED, and that is worth reading before extracting anything: just before the matched lines, \u0060engineering/skills/dependency-auditor/scripts/license_checker.py:941\u0060 calls \u0060join\u0060 and \u0060engineering/skills/api-design-reviewer/scripts/breaking_change_detector.py:1009\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":"engineering/skills/api-design-reviewer/scripts/breaking_change_detector.py"},"region":{"startLine":1013}}}],"partialFingerprints":{"codehealthFindingId/v1":"852730db5647c702c094fd85379bfca879cf1f5a18422baefe0b45d82d25d01c"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (30 lines \u00D7 2): engineering-team/skills/senior-architect/scripts/dependency_analyzer.py:521-551 | engineering-team/skills/senior-architect/scripts/project_architect.py:648-677 \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 \u0060engineering-team/skills/senior-architect/scripts/dependency_analyzer.py:521\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":"engineering-team/skills/senior-architect/scripts/dependency_analyzer.py"},"region":{"startLine":521}}}],"partialFingerprints":{"codehealthFindingId/v1":"cd3aebf097851231670843c2e3bd0b2060b431f7860d490a181af444401917e8"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (3\u201330 lines \u00D7 5): engineering/chaos-engineering/skills/chaos-engineering/scripts/experiment_postmortem.py:89-118 | engineering/skills/chaos-engineering/scripts/experiment_postmortem.py:89-118 | marketing-skill/skills/aeo/scripts/aeo_audit.py:299-301 | ra-qm-team/skills/soc2-compliance/scripts/evidence_tracker.py:165-170 | research/grants/skills/grants/scripts/citation_tracker.py:207-210 \u2014 before extracting anything, compare \u0060engineering/chaos-engineering/skills/chaos-engineering/scripts/experiment_postmortem.py\u0060 and \u0060engineering/skills/chaos-engineering/scripts/experiment_postmortem.py\u0060 as WHOLE FILES: this scan already matched 4 separate duplicated blocks between them, totalling at least 63 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The \u0060return\u0060 at the foot of the matched lines is the enclosing body\u0027s own terminal exit, not an early one: it moves with them unchanged, and each site calls the extracted unit from the position that \u0060return\u0060 occupied \u2014 no decision has to be handed back and re-acted on. 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":"engineering/chaos-engineering/skills/chaos-engineering/scripts/experiment_postmortem.py"},"region":{"startLine":89}}}],"partialFingerprints":{"codehealthFindingId/v1":"08f7476ee78055f4b2d4dd914c5f345e7b4f95557de71077b54cea9ebec44ce0"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (30 lines \u00D7 2): engineering/feature-flags-architect/skills/feature-flags-architect/scripts/rollout_planner.py:52-81 | engineering/skills/feature-flags-architect/scripts/rollout_planner.py:52-81 \u2014 before extracting anything, compare \u0060engineering/feature-flags-architect/skills/feature-flags-architect/scripts/rollout_planner.py\u0060 and \u0060engineering/skills/feature-flags-architect/scripts/rollout_planner.py\u0060 as WHOLE FILES: this scan already matched 5 separate duplicated blocks between them, totalling at least 68 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. Read the line range as the matched WINDOW rather than a finished unit: at \u0060engineering/feature-flags-architect/skills/feature-flags-architect/scripts/rollout_planner.py:52\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":"engineering/feature-flags-architect/skills/feature-flags-architect/scripts/rollout_planner.py"},"region":{"startLine":52}}}],"partialFingerprints":{"codehealthFindingId/v1":"953ca1f6a4f5d76efa19f936f9229d105f79cbb66cb94ac2b8325a0acb518e29"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (26\u201329 lines \u00D7 3): engineering/skills/tech-debt-tracker/assets/sample_codebase/src/payment_processor.py:109-137 | engineering/skills/tech-debt-tracker/assets/sample_codebase/src/payment_processor.py:152-177 | engineering/skills/tech-debt-tracker/assets/sample_codebase/src/payment_processor.py:194-219 \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 \u0060engineering/skills/tech-debt-tracker/assets/sample_codebase/src/payment_processor.py:109\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":"engineering/skills/tech-debt-tracker/assets/sample_codebase/src/payment_processor.py"},"region":{"startLine":109}}}],"partialFingerprints":{"codehealthFindingId/v1":"fedbe5c6557074baa11dbaa8cc0403a0078dcfa60a11aa94dd727e24a194090f"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (29 lines \u00D7 2): c-level-advisor/arquiteto-de-empresa/skills/arquiteto-de-empresa/scripts/index_generator.py:143-171 | c-level-advisor/skills/arquiteto-de-empresa/scripts/index_generator.py:143-171 \u2014 before extracting anything, compare \u0060c-level-advisor/arquiteto-de-empresa/skills/arquiteto-de-empresa/scripts/index_generator.py\u0060 and \u0060c-level-advisor/skills/arquiteto-de-empresa/scripts/index_generator.py\u0060 as WHOLE FILES: this scan already matched 10 separate duplicated blocks between them, totalling at least 135 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"c-level-advisor/arquiteto-de-empresa/skills/arquiteto-de-empresa/scripts/index_generator.py"},"region":{"startLine":143}}}],"partialFingerprints":{"codehealthFindingId/v1":"51708f46521eeeb7951606c7f205d7ff3d409af9d01c3cc8c7cc46ab81f3f05a"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (28 lines \u00D7 2): business-growth/skills/sales-engineer/scripts/competitive_matrix_builder.py:486-513 | business-growth/skills/sales-engineer/scripts/poc_planner.py:726-753 \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":"business-growth/skills/sales-engineer/scripts/competitive_matrix_builder.py"},"region":{"startLine":486}}}],"partialFingerprints":{"codehealthFindingId/v1":"3213884febbb2b7162db0ee2039f589b206120a1dfb88a9fd98ef45241ca37e7"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (28 lines \u00D7 2): c-level-advisor/arquiteto-de-empresa/skills/arquiteto-de-empresa/scripts/okf_linter.py:159-186 | c-level-advisor/skills/arquiteto-de-empresa/scripts/okf_linter.py:159-186 \u2014 before extracting anything, compare \u0060c-level-advisor/arquiteto-de-empresa/skills/arquiteto-de-empresa/scripts/okf_linter.py\u0060 and \u0060c-level-advisor/skills/arquiteto-de-empresa/scripts/okf_linter.py\u0060 as WHOLE FILES: this scan already matched 7 separate duplicated blocks between them, totalling at least 147 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"c-level-advisor/arquiteto-de-empresa/skills/arquiteto-de-empresa/scripts/okf_linter.py"},"region":{"startLine":159}}}],"partialFingerprints":{"codehealthFindingId/v1":"3d4d2f258b4c6df0ea56de8309e6868e42c66efc719d970ec9a3fba31e4c59a0"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (28 lines \u00D7 2): c-level-advisor/chief-customer-officer-advisor/skills/chief-customer-officer-advisor/scripts/customer_segmentation_designer.py:221-248 | c-level-advisor/skills/chief-customer-officer-advisor/scripts/customer_segmentation_designer.py:221-248 \u2014 before extracting anything, compare \u0060c-level-advisor/chief-customer-officer-advisor/skills/chief-customer-officer-advisor/scripts/customer_segmentation_designer.py\u0060 and \u0060c-level-advisor/skills/chief-customer-officer-advisor/scripts/customer_segmentation_designer.py\u0060 as WHOLE FILES: this scan already matched 11 separate duplicated blocks between them, totalling at least 146 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"c-level-advisor/chief-customer-officer-advisor/skills/chief-customer-officer-advisor/scripts/customer_segmentation_designer.py"},"region":{"startLine":221}}}],"partialFingerprints":{"codehealthFindingId/v1":"dfb1387ed775467964a1cf58676b29aea13dc8523b88016ba8afd6742e5fdce3"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (28 lines \u00D7 2): c-level-advisor/skills/ciso-advisor/scripts/compliance_tracker.py:207-234 | c-level-advisor/skills/ciso-advisor/scripts/compliance_tracker.py:298-325 \u2014 both copies are in the same file, so extract the block 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 \u0060c-level-advisor/skills/ciso-advisor/scripts/compliance_tracker.py:207\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":"c-level-advisor/skills/ciso-advisor/scripts/compliance_tracker.py"},"region":{"startLine":207}}}],"partialFingerprints":{"codehealthFindingId/v1":"e981679c602446611df0d5ed0b6c13ed6f73aa331417317d555eaf4297e91970"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (15\u201328 lines \u00D7 2): engineering-team/skills/senior-prompt-engineer/scripts/agent_orchestrator.py:463-490 | engineering-team/skills/senior-prompt-engineer/scripts/prompt_optimizer.py:418-432 \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":"engineering-team/skills/senior-prompt-engineer/scripts/agent_orchestrator.py"},"region":{"startLine":463}}}],"partialFingerprints":{"codehealthFindingId/v1":"22538d8009ee4e151bb098787ac8cd7e69a983ff313813b81fb5c85b9b9b6416"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (25\u201328 lines \u00D7 2): engineering/skills/observability-designer/scripts/dashboard_generator.py:1132-1159 | engineering/skills/observability-designer/scripts/slo_designer.py:600-624 \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 \u0060engineering/skills/observability-designer/scripts/dashboard_generator.py:1132\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":"engineering/skills/observability-designer/scripts/dashboard_generator.py"},"region":{"startLine":1132}}}],"partialFingerprints":{"codehealthFindingId/v1":"5e71cf900fd822859ad23b91efc42e554700ea8bc2214e519ca57e5f65d38a78"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (28 lines \u00D7 2): engineering/skills/slo-architect/scripts/error_budget_calculator.py:52-79 | engineering/slo-architect/skills/slo-architect/scripts/error_budget_calculator.py:52-79 \u2014 before extracting anything, compare \u0060engineering/skills/slo-architect/scripts/error_budget_calculator.py\u0060 and \u0060engineering/slo-architect/skills/slo-architect/scripts/error_budget_calculator.py\u0060 as WHOLE FILES: this scan already matched 7 separate duplicated blocks between them, totalling at least 89 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/slo-architect/scripts/error_budget_calculator.py"},"region":{"startLine":52}}}],"partialFingerprints":{"codehealthFindingId/v1":"d9c5078bf2171922de3d5ad14e710169c2125fa3be6f439212a6d29bb268008a"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (21\u201328 lines \u00D7 2): finance/skills/stock-analysis/scripts/valuation.py:114-134 | finance/skills/stock-analysis/scripts/verify_data.py:326-353 \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":"finance/skills/stock-analysis/scripts/valuation.py"},"region":{"startLine":114}}}],"partialFingerprints":{"codehealthFindingId/v1":"1efc000f175521d42f73c3fe6cf0726a3c7106ddf46d77f5854f856b5cbee74f"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (15\u201328 lines \u00D7 2): scripts/sync-codex-skills.py:185-212 | scripts/sync-gemini-skills.py:164-178 \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":"scripts/sync-codex-skills.py"},"region":{"startLine":185}}}],"partialFingerprints":{"codehealthFindingId/v1":"a3ca62e6c31ce095e88ed923bfa7d3b308fb1dc3b98b93cc4a1fb2dfaef0420b"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (27 lines \u00D7 4): c-level-advisor/skills/ciso-advisor/scripts/compliance_tracker.py:196-222 | c-level-advisor/skills/ciso-advisor/scripts/compliance_tracker.py:263-289 | c-level-advisor/skills/ciso-advisor/scripts/compliance_tracker.py:332-358 | c-level-advisor/skills/ciso-advisor/scripts/compliance_tracker.py:378-404 \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 \u0060c-level-advisor/skills/ciso-advisor/scripts/compliance_tracker.py:196\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":"c-level-advisor/skills/ciso-advisor/scripts/compliance_tracker.py"},"region":{"startLine":196}}}],"partialFingerprints":{"codehealthFindingId/v1":"9dddc0ee7c451d8984c74a755f1f5eb12788bbfca97841fba5dc74eb10f7cbff"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (27 lines \u00D7 2): c-level-advisor/skills/ciso-advisor/scripts/compliance_tracker.py:355-381 | c-level-advisor/skills/ciso-advisor/scripts/compliance_tracker.py:425-451 \u2014 both copies are in the same file, so extract the block into one function there and call it from each site \u2014 the copies drift apart the first time only one of them is edited. Read the line range as the matched WINDOW rather than a finished unit: at \u0060c-level-advisor/skills/ciso-advisor/scripts/compliance_tracker.py:355\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":"c-level-advisor/skills/ciso-advisor/scripts/compliance_tracker.py"},"region":{"startLine":355}}}],"partialFingerprints":{"codehealthFindingId/v1":"b86d21bab685719472798617d32ede31d59cc7ef507e8fe1169f2edc678dd119"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (26\u201327 lines \u00D7 2): engineering-team/skills/senior-computer-vision/scripts/dataset_pipeline_builder.py:1085-1110 | engineering-team/skills/senior-computer-vision/scripts/dataset_pipeline_builder.py:1195-1221 \u2014 both copies are in the same file, so extract the block 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":"engineering-team/skills/senior-computer-vision/scripts/dataset_pipeline_builder.py"},"region":{"startLine":1085}}}],"partialFingerprints":{"codehealthFindingId/v1":"fcf7a7bb219be99d0160809430a6e61da42a7e8a53c3adeb6c7907f9ca486569"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (27 lines \u00D7 2): engineering-team/skills/senior-data-engineer/scripts/data_quality_validator.py:1365-1391 | engineering-team/skills/senior-data-engineer/scripts/data_quality_validator.py:1465-1491 \u2014 both copies are in the same file, so extract the block 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":"engineering-team/skills/senior-data-engineer/scripts/data_quality_validator.py"},"region":{"startLine":1365}}}],"partialFingerprints":{"codehealthFindingId/v1":"0ca63a672409ce5e1eeb6bb2696f38a1c5eac75543a714051cdfa21ee89320a3"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (25\u201327 lines \u00D7 2): engineering/skills/secrets-vault-manager/scripts/rotation_planner.py:229-255 | engineering/skills/secrets-vault-manager/scripts/vault_config_generator.py:262-286 \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 \u0060engineering/skills/secrets-vault-manager/scripts/rotation_planner.py:229\u0060 it does not close everything it opens, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that. \u2605 These copies have DRIFTED, and that is worth reading before extracting anything: just after the matched lines, \u0060engineering/skills/secrets-vault-manager/scripts/vault_config_generator.py:287\u0060 calls \u0060add_argument\u0060 and \u0060engineering/skills/secrets-vault-manager/scripts/rotation_planner.py:256\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":"engineering/skills/secrets-vault-manager/scripts/rotation_planner.py"},"region":{"startLine":229}}}],"partialFingerprints":{"codehealthFindingId/v1":"e5f199b4215aa4c7277b561e509b8d7646dfeb62593491af980b1b1573fe80ee"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (16\u201327 lines \u00D7 2): scripts/sync-codex-skills.py:305-331 | scripts/sync-gemini-skills.py:244-259 \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":"scripts/sync-codex-skills.py"},"region":{"startLine":305}}}],"partialFingerprints":{"codehealthFindingId/v1":"6e8750af19894f93e4e76640417fab55d51a3c74582c0ce8b33b6bffc8e6eee8"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (27 lines \u00D7 2): scripts/sync-hermes-skills.py:154-180 | scripts/sync-vibe-skills.py:191-217 \u2014 before extracting anything, compare \u0060scripts/sync-hermes-skills.py\u0060 and \u0060scripts/sync-vibe-skills.py\u0060 as WHOLE FILES: this scan already matched 6 separate duplicated blocks between them, totalling at least 165 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":"scripts/sync-hermes-skills.py"},"region":{"startLine":154}}}],"partialFingerprints":{"codehealthFindingId/v1":"7be939f2a24f4cab7c8704eb905c73d9283692b1bc4b0c805003dfdd3e33bf25"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (23\u201326 lines \u00D7 6): engineering-team/skills/senior-secops/scripts/compliance_checker.py:501-524 | engineering-team/skills/senior-secops/scripts/compliance_checker.py:533-558 | engineering-team/skills/senior-secops/scripts/compliance_checker.py:567-590 | engineering-team/skills/senior-secops/scripts/compliance_checker.py:791-813 | engineering-team/skills/senior-secops/scripts/compliance_checker.py:886-909 | engineering-team/skills/senior-secops/scripts/compliance_checker.py:918-940 \u2014 all 6 copies are in the same file, so extract the block into one function there and call it from every one of those sites \u2014 resolving only two of them leaves the rest to drift apart the first time one is edited. Read the line range as the matched WINDOW rather than a finished unit: at \u0060engineering-team/skills/senior-secops/scripts/compliance_checker.py:501\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":"engineering-team/skills/senior-secops/scripts/compliance_checker.py"},"region":{"startLine":501}}}],"partialFingerprints":{"codehealthFindingId/v1":"028cd9a961b05517fb4d5e12c4d8c2beb73d3b40f0c01d069846f989bdcc6ab9"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (26 lines \u00D7 2): business-operations/skills/process-mapper/scripts/bottleneck_detector.py:236-261 | business-operations/skills/process-mapper/scripts/cycle_time_analyzer.py:182-207 \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":"business-operations/skills/process-mapper/scripts/bottleneck_detector.py"},"region":{"startLine":236}}}],"partialFingerprints":{"codehealthFindingId/v1":"53fd4365c2a0c3cfef74bd7840a5fc0ab18a5255f49b253e1c35e249b618553f"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (26 lines \u00D7 2): c-level-advisor/chief-customer-officer-advisor/skills/chief-customer-officer-advisor/scripts/retention_decomposition_analyzer.py:112-137 | c-level-advisor/skills/chief-customer-officer-advisor/scripts/retention_decomposition_analyzer.py:112-137 \u2014 before extracting anything, compare \u0060c-level-advisor/chief-customer-officer-advisor/skills/chief-customer-officer-advisor/scripts/retention_decomposition_analyzer.py\u0060 and \u0060c-level-advisor/skills/chief-customer-officer-advisor/scripts/retention_decomposition_analyzer.py\u0060 as WHOLE FILES: this scan already matched 9 separate duplicated blocks between them, totalling at least 171 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"c-level-advisor/chief-customer-officer-advisor/skills/chief-customer-officer-advisor/scripts/retention_decomposition_analyzer.py"},"region":{"startLine":112}}}],"partialFingerprints":{"codehealthFindingId/v1":"7badc0b550145b9420a1ef48c7ca951372dfe94dceff874e1608e6253bdc40ea"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (26 lines \u00D7 2): engineering/skills/slo-architect/scripts/slo_designer.py:129-154 | engineering/slo-architect/skills/slo-architect/scripts/slo_designer.py:129-154 \u2014 before extracting anything, compare \u0060engineering/skills/slo-architect/scripts/slo_designer.py\u0060 and \u0060engineering/slo-architect/skills/slo-architect/scripts/slo_designer.py\u0060 as WHOLE FILES: this scan already matched 8 separate duplicated blocks between them, totalling at least 70 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/slo-architect/scripts/slo_designer.py"},"region":{"startLine":129}}}],"partialFingerprints":{"codehealthFindingId/v1":"9bac4caf19aceb77b0602f7421284acf322638f893c80900a3123001edbb0431"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (26 lines \u00D7 2): markdown-html/skills/design-system/scripts/onboard.py:180-205 | research-ops/skills/clinical-research/scripts/onboard.py:93-118 \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 \u0060markdown-html/skills/design-system/scripts/onboard.py:180\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":"markdown-html/skills/design-system/scripts/onboard.py"},"region":{"startLine":180}}}],"partialFingerprints":{"codehealthFindingId/v1":"b93cc40d12717806cca57b4c176da5aa0299c0a0ee30ca531bde49046d219306"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (26 lines \u00D7 2): ra-qm-team/compliance-team-iso42001/skills/iso42001-specialist/scripts/aims_gap_analyzer.py:137-162 | ra-qm-team/skills/iso42001-specialist/scripts/aims_gap_analyzer.py:137-162 \u2014 before extracting anything, compare \u0060ra-qm-team/compliance-team-iso42001/skills/iso42001-specialist/scripts/aims_gap_analyzer.py\u0060 and \u0060ra-qm-team/skills/iso42001-specialist/scripts/aims_gap_analyzer.py\u0060 as WHOLE FILES: this scan already matched 8 separate duplicated blocks between them, totalling at least 105 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"ra-qm-team/compliance-team-iso42001/skills/iso42001-specialist/scripts/aims_gap_analyzer.py"},"region":{"startLine":137}}}],"partialFingerprints":{"codehealthFindingId/v1":"3d9571e1076b9dcf8139c8f27c8549ff91e6846254549c0ff582d21ddb2d70aa"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (25 lines \u00D7 2): c-level-advisor/chief-data-officer-advisor/skills/chief-data-officer-advisor/scripts/ai_training_data_audit.py:419-443 | c-level-advisor/skills/chief-data-officer-advisor/scripts/ai_training_data_audit.py:419-443 \u2014 before extracting anything, compare \u0060c-level-advisor/chief-data-officer-advisor/skills/chief-data-officer-advisor/scripts/ai_training_data_audit.py\u0060 and \u0060c-level-advisor/skills/chief-data-officer-advisor/scripts/ai_training_data_audit.py\u0060 as WHOLE FILES: this scan already matched 8 separate duplicated blocks between them, totalling at least 314 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"c-level-advisor/chief-data-officer-advisor/skills/chief-data-officer-advisor/scripts/ai_training_data_audit.py"},"region":{"startLine":419}}}],"partialFingerprints":{"codehealthFindingId/v1":"a6f900ef0b9b2c2018c1b2686107777b608f7d911e1c2ede0092881beed23b38"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (25 lines \u00D7 2): engineering/feature-flags-architect/skills/feature-flags-architect/scripts/kill_switch_audit.py:73-97 | engineering/skills/feature-flags-architect/scripts/kill_switch_audit.py:73-97 \u2014 before extracting anything, compare \u0060engineering/feature-flags-architect/skills/feature-flags-architect/scripts/kill_switch_audit.py\u0060 and \u0060engineering/skills/feature-flags-architect/scripts/kill_switch_audit.py\u0060 as WHOLE FILES: this scan already matched 6 separate duplicated blocks between them, totalling at least 94 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/feature-flags-architect/skills/feature-flags-architect/scripts/kill_switch_audit.py"},"region":{"startLine":73}}}],"partialFingerprints":{"codehealthFindingId/v1":"b80c1ff3ca0a504e0d56266422e9f68e28127e8518c0eec7cef3acf0fe51bee9"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (23\u201325 lines \u00D7 2): marketing-skill/skills/ad-creative/scripts/ad_copy_validator.py:218-242 | marketing-skill/skills/ad-creative/scripts/ad_copy_validator.py:254-276 \u2014 both copies are in the same file, so extract the block 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":"marketing-skill/skills/ad-creative/scripts/ad_copy_validator.py"},"region":{"startLine":218}}}],"partialFingerprints":{"codehealthFindingId/v1":"074c299a85cd6cd870d124f1767661d2acc21c96059135a8ad09eaa8a80e19a6"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (24 lines \u00D7 3): business-growth/skills/sales-engineer/scripts/competitive_matrix_builder.py:43-66 | business-growth/skills/sales-engineer/scripts/poc_planner.py:130-153 | business-growth/skills/sales-engineer/scripts/rfp_response_analyzer.py:49-72 \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":"business-growth/skills/sales-engineer/scripts/competitive_matrix_builder.py"},"region":{"startLine":43}}}],"partialFingerprints":{"codehealthFindingId/v1":"4282c5ba7506f779c26f2bce1a2097819d7340c84ccaf136281011bad86f95c9"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (24 lines \u00D7 3): research-ops/skills/market-research/scripts/onboard.py:69-92 | research-ops/skills/product-research/scripts/onboard.py:78-101 | research-ops/skills/research-finance/scripts/onboard.py:72-95 \u2014 before extracting anything, compare \u0060research-ops/skills/market-research/scripts/onboard.py\u0060 and \u0060research-ops/skills/product-research/scripts/onboard.py\u0060 as WHOLE FILES: this scan already matched 5 separate duplicated blocks between them, totalling at least 60 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"research-ops/skills/market-research/scripts/onboard.py"},"region":{"startLine":69}}}],"partialFingerprints":{"codehealthFindingId/v1":"3ad0268fcc62214154b09d85c368c5eaafb82e7db7baa4746a33b0e1ccc0e410"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (24 lines \u00D7 2): business-growth/skills/revenue-operations/scripts/forecast_accuracy_tracker.py:491-514 | business-growth/skills/revenue-operations/scripts/gtm_efficiency_calculator.py:613-636 \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":"business-growth/skills/revenue-operations/scripts/forecast_accuracy_tracker.py"},"region":{"startLine":491}}}],"partialFingerprints":{"codehealthFindingId/v1":"035a338ffbc95c24679f2e0f6bb8ca40e270f06a8962463f634ecbf5be99070a"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (20\u201324 lines \u00D7 2): engineering-team/skills/incident-commander/scripts/timeline_reconstructor.py:919-942 | engineering-team/skills/senior-frontend/scripts/component_generator.py:258-277 \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 \u0060engineering-team/skills/senior-frontend/scripts/component_generator.py:258\u0060 it begins part-way through the construct above it, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that. Note that the copies do not run to the end of the range shown: their LAST lines are different code, not the same code under different names \u2014 the matched region ends inside that line. Extract the lines above it, and read the last line of each site separately."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/skills/incident-commander/scripts/timeline_reconstructor.py"},"region":{"startLine":919}}}],"partialFingerprints":{"codehealthFindingId/v1":"64ef0d048bee5f3c2dbac73f380feab5ecd94866aa7363c82601fe7e4a5561ff"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (24 lines \u00D7 2): engineering-team/skills/senior-architect/scripts/architecture_diagram_generator.py:585-608 | engineering-team/skills/senior-qa/scripts/coverage_analyzer.py:786-809 \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 \u0060engineering-team/skills/senior-architect/scripts/architecture_diagram_generator.py:585\u0060 it runs out through the closing brace of the declaration holding it and carries on into the declaration that follows \u2014 the window is the tail of one member plus the head of the next, so no call can be substituted for those exact lines, and the smallest declaration that contains all of them is the type they sit in. The repeated unit is the member each site sits in: where those members\u0027 bodies are the same, move one whole member to the shared location and have the others delegate to it; where the copies are a run of near-identical overloads or wrappers that differ only in their signatures, the repetition IS the run \u2014 a one-line delegation has no helper inside it to lift \u2014 so generate the run from the set it enumerates, or accept it and keep each member\u0027s own documentation with it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/skills/senior-architect/scripts/architecture_diagram_generator.py"},"region":{"startLine":585}}}],"partialFingerprints":{"codehealthFindingId/v1":"796584db0e00fd02a4ac47b43bc1381dd5dbf5773bf662e8cbb6b384c238d688"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (19\u201324 lines \u00D7 2): engineering/skills/agent-designer/agent_planner.py:868-886 | engineering/skills/agent-designer/tool_schema_generator.py:884-907 \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":"engineering/skills/agent-designer/agent_planner.py"},"region":{"startLine":868}}}],"partialFingerprints":{"codehealthFindingId/v1":"cf6f7043ab3ac9a24d065f72815d66cf8dde25558235485bf3dd0fbd0a385fe3"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9\u201324 lines \u00D7 2): ra-qm-team/skills/quality-manager-qms-iso13485/scripts/qms_audit_checklist.py:816-839 | ra-qm-team/skills/risk-management-specialist/scripts/risk_matrix_calculator.py:372-380 \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 \u0060ra-qm-team/skills/quality-manager-qms-iso13485/scripts/qms_audit_checklist.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 \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":"ra-qm-team/skills/quality-manager-qms-iso13485/scripts/qms_audit_checklist.py"},"region":{"startLine":816}}}],"partialFingerprints":{"codehealthFindingId/v1":"32b4ce41b6eccd9fa6627006e8c75a126ebe0809a1df630bce14cee098fcd03d"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (23\u201324 lines \u00D7 2): scripts/sync-hermes-skills.py:252-274 | scripts/sync-vibe-skills.py:302-325 \u2014 before extracting anything, compare \u0060scripts/sync-hermes-skills.py\u0060 and \u0060scripts/sync-vibe-skills.py\u0060 as WHOLE FILES: this scan already matched 6 separate duplicated blocks between them, totalling at least 165 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":"scripts/sync-hermes-skills.py"},"region":{"startLine":252}}}],"partialFingerprints":{"codehealthFindingId/v1":"237cd85412ff7d065d13a2b46006dd6ca5f16bd25d98f29a26ed362537e1641b"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6\u201323 lines \u00D7 3): engineering-team/skills/senior-frontend/scripts/component_generator.py:265-287 | productivity/meetings/skills/meetings/scripts/meeting_cost_calculator.py:145-151 | scripts/check_model_freshness.py:176-181 \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. Read the line range as the matched WINDOW rather than a finished unit: at \u0060engineering-team/skills/senior-frontend/scripts/component_generator.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. Note that the copies do not run to the end of the range shown: their LAST lines are different code, not the same code under different names \u2014 the matched region ends inside that line. Extract the lines above it, and read the last line of each site separately. \u2605 These copies have DRIFTED, and that is worth reading before extracting anything: just before the matched lines, \u0060scripts/check_model_freshness.py:175\u0060 calls \u0060add_argument\u0060 and \u0060engineering-team/skills/senior-frontend/scripts/component_generator.py:265\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":"engineering-team/skills/senior-frontend/scripts/component_generator.py"},"region":{"startLine":265}}}],"partialFingerprints":{"codehealthFindingId/v1":"4c59f055b850176f2009e1b90046c7c7ece961d3ec6f1ef2704d4c84e6667eb8"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (20\u201323 lines \u00D7 2): engineering-team/google-workspace-cli/skills/google-workspace-cli/scripts/gws_doctor.py:199-221 | engineering-team/google-workspace-cli/skills/google-workspace-cli/scripts/workspace_audit.py:256-275 \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":"engineering-team/google-workspace-cli/skills/google-workspace-cli/scripts/gws_doctor.py"},"region":{"startLine":199}}}],"partialFingerprints":{"codehealthFindingId/v1":"10f5c80f5d3e9957b79c2213378257f65aa3507acbf22daa7dd61342225b4f60"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (23 lines \u00D7 2): engineering-team/skills/senior-architect/scripts/dependency_analyzer.py:553-575 | engineering-team/skills/senior-architect/scripts/project_architect.py:679-701 \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 \u0060engineering-team/skills/senior-architect/scripts/dependency_analyzer.py:553\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":"engineering-team/skills/senior-architect/scripts/dependency_analyzer.py"},"region":{"startLine":553}}}],"partialFingerprints":{"codehealthFindingId/v1":"e81fb59c3e271ae970b2457a3f4df21eb0a74568e8b1cbf4a5b03d30948daa52"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (23 lines \u00D7 2): engineering-team/skills/senior-backend/scripts/api_scaffolder.py:585-607 | engineering-team/skills/senior-frontend/scripts/component_generator.py:250-272 \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 \u0060engineering-team/skills/senior-backend/scripts/api_scaffolder.py:585\u0060 it begins part-way through the construct above it, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that. Note that the copies do not run to the end of the range shown: their LAST lines are different code, not the same code under different names \u2014 the matched region ends inside that line. Extract the lines above it, and read the last line of each site separately."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/skills/senior-backend/scripts/api_scaffolder.py"},"region":{"startLine":585}}}],"partialFingerprints":{"codehealthFindingId/v1":"aaedfcd4078eba73bc764774380f95da42a542ed361647105839bf01ef19c039"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (20\u201323 lines \u00D7 2): engineering-team/skills/senior-computer-vision/scripts/inference_optimizer.py:268-290 | engineering-team/skills/senior-computer-vision/scripts/inference_optimizer.py:337-356 \u2014 both copies are in the same file, so extract the block into one function there and call it from each site \u2014 the copies drift apart the first time only one of them is edited. Read the line range as the matched WINDOW rather than a finished unit: at \u0060engineering-team/skills/senior-computer-vision/scripts/inference_optimizer.py:268\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":"engineering-team/skills/senior-computer-vision/scripts/inference_optimizer.py"},"region":{"startLine":268}}}],"partialFingerprints":{"codehealthFindingId/v1":"2596c2748021e884802643395509f6f99f1fa4521fadc8c081a209d9d8674ee2"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (23 lines \u00D7 2): engineering/feature-flags-architect/skills/feature-flags-architect/scripts/kill_switch_audit.py:101-123 | engineering/skills/feature-flags-architect/scripts/kill_switch_audit.py:101-123 \u2014 before extracting anything, compare \u0060engineering/feature-flags-architect/skills/feature-flags-architect/scripts/kill_switch_audit.py\u0060 and \u0060engineering/skills/feature-flags-architect/scripts/kill_switch_audit.py\u0060 as WHOLE FILES: this scan already matched 6 separate duplicated blocks between them, totalling at least 94 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/feature-flags-architect/skills/feature-flags-architect/scripts/kill_switch_audit.py"},"region":{"startLine":101}}}],"partialFingerprints":{"codehealthFindingId/v1":"ea161e7ed7cc5641108b64ace2ccf89a5c9cd53288c68b7c54d61daac8eb219a"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (23 lines \u00D7 2): engineering/kubernetes-operator/skills/kubernetes-operator/scripts/operator_capability_audit.py:76-98 | engineering/skills/kubernetes-operator/scripts/operator_capability_audit.py:76-98 \u2014 before extracting anything, compare \u0060engineering/kubernetes-operator/skills/kubernetes-operator/scripts/operator_capability_audit.py\u0060 and \u0060engineering/skills/kubernetes-operator/scripts/operator_capability_audit.py\u0060 as WHOLE FILES: this scan already matched 5 separate duplicated blocks between them, totalling at least 75 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/kubernetes-operator/skills/kubernetes-operator/scripts/operator_capability_audit.py"},"region":{"startLine":76}}}],"partialFingerprints":{"codehealthFindingId/v1":"0e66b02dcb53506a73938aec2eab94c0124b6755d5e74a1e2a30c29d10835eeb"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (23 lines \u00D7 2): engineering/kubernetes-operator/skills/kubernetes-operator/scripts/reconcile_lint.py:37-59 | engineering/skills/kubernetes-operator/scripts/reconcile_lint.py:37-59 \u2014 before extracting anything, compare \u0060engineering/kubernetes-operator/skills/kubernetes-operator/scripts/reconcile_lint.py\u0060 and \u0060engineering/skills/kubernetes-operator/scripts/reconcile_lint.py\u0060 as WHOLE FILES: this scan already matched 9 separate duplicated blocks between them, totalling at least 127 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/kubernetes-operator/skills/kubernetes-operator/scripts/reconcile_lint.py"},"region":{"startLine":37}}}],"partialFingerprints":{"codehealthFindingId/v1":"f7004973ed121f8347931b095c17df7f42d117f13a96173300dbfe7cef238cb9"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (23 lines \u00D7 2): ra-qm-team/compliance-team-iso42001/skills/iso42001-specialist/scripts/aims_audit_scheduler.py:112-134 | ra-qm-team/skills/iso42001-specialist/scripts/aims_audit_scheduler.py:112-134 \u2014 before extracting anything, compare \u0060ra-qm-team/compliance-team-iso42001/skills/iso42001-specialist/scripts/aims_audit_scheduler.py\u0060 and \u0060ra-qm-team/skills/iso42001-specialist/scripts/aims_audit_scheduler.py\u0060 as WHOLE FILES: this scan already matched 9 separate duplicated blocks between them, totalling at least 151 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. Read the line range as the matched WINDOW rather than a finished unit: at \u0060ra-qm-team/compliance-team-iso42001/skills/iso42001-specialist/scripts/aims_audit_scheduler.py:112\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":"ra-qm-team/compliance-team-iso42001/skills/iso42001-specialist/scripts/aims_audit_scheduler.py"},"region":{"startLine":112}}}],"partialFingerprints":{"codehealthFindingId/v1":"04c295392d526196a65965fde437cf3fe78e527b2cdd76aeb7375cfd5ddee45e"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (16\u201322 lines \u00D7 6): engineering/docker-development/skills/docker-development/scripts/compose_validator.py:324-340 | engineering/docker-development/skills/docker-development/scripts/dockerfile_analyzer.py:333-354 | engineering/helm-chart-builder/skills/helm-chart-builder/scripts/chart_analyzer.py:445-462 | engineering/helm-chart-builder/skills/helm-chart-builder/scripts/values_validator.py:370-388 | engineering/terraform-patterns/skills/terraform-patterns/scripts/tf_module_analyzer.py:384-405 | engineering/terraform-patterns/skills/terraform-patterns/scripts/tf_security_scanner.py:500-515 \u2014 the copies span different directories, so extracting a shared function means choosing where it lives: put it somewhere all 6 call sites can already reach \u2014 a location they all depend on today, or a new shared one if there is none \u2014 and call it from each site; until then, every change has to be made 6 times. The matched lines also transfer control out of the body holding them, 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, \u0060engineering/helm-chart-builder/skills/helm-chart-builder/scripts/chart_analyzer.py:443\u0060 calls \u0060parse_yaml_simple\u0060, \u0060read_text\u0060, \u0060exists\u0060 and \u0060engineering/terraform-patterns/skills/terraform-patterns/scripts/tf_module_analyzer.py:382\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":"engineering/docker-development/skills/docker-development/scripts/compose_validator.py"},"region":{"startLine":324}}}],"partialFingerprints":{"codehealthFindingId/v1":"a326bf5742d9f95b89e760dc95c8d4de0b6be117b96037e81ae5a9cbdde27e7f"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (15\u201322 lines \u00D7 3): engineering-team/skills/senior-backend/scripts/backend_decision_engine.py:254-268 | engineering-team/skills/senior-frontend/scripts/frontend_decision_engine.py:200-221 | engineering-team/skills/senior-fullstack/scripts/fullstack_decision_engine.py:252-268 \u2014 before extracting anything, compare \u0060engineering-team/skills/senior-backend/scripts/backend_decision_engine.py\u0060 and \u0060engineering-team/skills/senior-frontend/scripts/frontend_decision_engine.py\u0060 as WHOLE FILES: this scan already matched 6 separate duplicated blocks between them, totalling at least 99 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. Read the line range as the matched WINDOW rather than a finished unit: at \u0060engineering-team/skills/senior-fullstack/scripts/fullstack_decision_engine.py:252\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":"engineering-team/skills/senior-backend/scripts/backend_decision_engine.py"},"region":{"startLine":254}}}],"partialFingerprints":{"codehealthFindingId/v1":"77bf85c383e17c13f818da26882de43f999946f5ae3e9a3129a4a4d4b0ad30ae"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (22 lines \u00D7 2): c-level-advisor/general-counsel-advisor/skills/general-counsel-advisor/scripts/contract_risk_scanner.py:378-399 | c-level-advisor/skills/general-counsel-advisor/scripts/contract_risk_scanner.py:378-399 \u2014 before extracting anything, compare \u0060c-level-advisor/general-counsel-advisor/skills/general-counsel-advisor/scripts/contract_risk_scanner.py\u0060 and \u0060c-level-advisor/skills/general-counsel-advisor/scripts/contract_risk_scanner.py\u0060 as WHOLE FILES: this scan already matched 5 separate duplicated blocks between them, totalling at least 106 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"c-level-advisor/general-counsel-advisor/skills/general-counsel-advisor/scripts/contract_risk_scanner.py"},"region":{"startLine":378}}}],"partialFingerprints":{"codehealthFindingId/v1":"7b1fb4c176180332429f3e3e54c3a6492b81d9c6feabe3a208e471e79f9d9743"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (22 lines \u00D7 2): engineering-team/skills/senior-secops/scripts/compliance_checker.py:403-424 | engineering-team/skills/senior-secops/scripts/compliance_checker.py:444-465 \u2014 both copies are in the same file, so extract the block 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":"engineering-team/skills/senior-secops/scripts/compliance_checker.py"},"region":{"startLine":403}}}],"partialFingerprints":{"codehealthFindingId/v1":"029299944af93d1af1f5825e35a3f299d2f26db9c4b197779a6846f4fd9db986"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (22 lines \u00D7 2): engineering/kubernetes-operator/skills/kubernetes-operator/scripts/reconcile_lint.py:101-122 | engineering/skills/kubernetes-operator/scripts/reconcile_lint.py:101-122 \u2014 before extracting anything, compare \u0060engineering/kubernetes-operator/skills/kubernetes-operator/scripts/reconcile_lint.py\u0060 and \u0060engineering/skills/kubernetes-operator/scripts/reconcile_lint.py\u0060 as WHOLE FILES: this scan already matched 9 separate duplicated blocks between them, totalling at least 127 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/kubernetes-operator/skills/kubernetes-operator/scripts/reconcile_lint.py"},"region":{"startLine":101}}}],"partialFingerprints":{"codehealthFindingId/v1":"b60ab0de812c1818fdaa11075333b6932ef0e044beca4df2365c57fa33c3d134"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (22 lines \u00D7 2): engineering/skills/agent-designer/agent_evaluator.py:556-577 | engineering/skills/agent-designer/agent_evaluator.py:581-602 \u2014 both copies are in the same file, so extract the block into one function there and call it from each site \u2014 the copies drift apart the first time only one of them is edited."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/agent-designer/agent_evaluator.py"},"region":{"startLine":556}}}],"partialFingerprints":{"codehealthFindingId/v1":"24bddbbe3f729f77504329221f8e6257f1fbaff30d9a4c6202e97ca8114e1965"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (19\u201322 lines \u00D7 2): engineering/skills/agent-designer/agent_evaluator.py:1163-1184 | engineering/skills/agent-designer/tool_schema_generator.py:913-931 \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. 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":"engineering/skills/agent-designer/agent_evaluator.py"},"region":{"startLine":1163}}}],"partialFingerprints":{"codehealthFindingId/v1":"e8590c223003e6879ca994d77714324fb216c8981b700cdf3db02b535f47d948"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (22 lines \u00D7 2): engineering/skills/slo-architect/scripts/error_budget_calculator.py:130-151 | engineering/slo-architect/skills/slo-architect/scripts/error_budget_calculator.py:130-151 \u2014 before extracting anything, compare \u0060engineering/skills/slo-architect/scripts/error_budget_calculator.py\u0060 and \u0060engineering/slo-architect/skills/slo-architect/scripts/error_budget_calculator.py\u0060 as WHOLE FILES: this scan already matched 7 separate duplicated blocks between them, totalling at least 89 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/slo-architect/scripts/error_budget_calculator.py"},"region":{"startLine":130}}}],"partialFingerprints":{"codehealthFindingId/v1":"795a31decfc4f0a711abb4aa0d1be7675fdbe200b9feb8d31f7edcfd0f15c9f2"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (22 lines \u00D7 2): marketing-skill/skills/campaign-analytics/scripts/campaign_roi_calculator.py:406-427 | marketing-skill/skills/campaign-analytics/scripts/funnel_analyzer.py:243-264 \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":"marketing-skill/skills/campaign-analytics/scripts/campaign_roi_calculator.py"},"region":{"startLine":406}}}],"partialFingerprints":{"codehealthFindingId/v1":"f914353fe8a973b672a5a8bb2d27492da8bb171bdea8561a8c1a154c49be80a9"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (21\u201322 lines \u00D7 2): productivity/handoff/skills/handoff/scripts/handoff_template_generator.py:193-213 | productivity/handoff/skills/handoff/scripts/setup.py:266-287 \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 \u0060productivity/handoff/skills/handoff/scripts/setup.py:266\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":"productivity/handoff/skills/handoff/scripts/handoff_template_generator.py"},"region":{"startLine":193}}}],"partialFingerprints":{"codehealthFindingId/v1":"d10d96bfab7e043f8c4f6ccb91457b10bddea72e952f5f2429c7b1f86e3cce12"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (22 lines \u00D7 2): ra-qm-team/compliance-team-iso42001/skills/iso42001-specialist/scripts/aims_gap_analyzer.py:163-184 | ra-qm-team/skills/iso42001-specialist/scripts/aims_gap_analyzer.py:163-184 \u2014 before extracting anything, compare \u0060ra-qm-team/compliance-team-iso42001/skills/iso42001-specialist/scripts/aims_gap_analyzer.py\u0060 and \u0060ra-qm-team/skills/iso42001-specialist/scripts/aims_gap_analyzer.py\u0060 as WHOLE FILES: this scan already matched 8 separate duplicated blocks between them, totalling at least 105 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"ra-qm-team/compliance-team-iso42001/skills/iso42001-specialist/scripts/aims_gap_analyzer.py"},"region":{"startLine":163}}}],"partialFingerprints":{"codehealthFindingId/v1":"d14c08528c92cd8ebca53e49aabc7787aba0553009be87338b90b431738ef6ce"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (21 lines \u00D7 10): c-level-advisor/skills/ciso-advisor/scripts/compliance_tracker.py:148-168 | c-level-advisor/skills/ciso-advisor/scripts/compliance_tracker.py:170-190 | c-level-advisor/skills/ciso-advisor/scripts/compliance_tracker.py:192-212 | c-level-advisor/skills/ciso-advisor/scripts/compliance_tracker.py:215-235 | c-level-advisor/skills/ciso-advisor/scripts/compliance_tracker.py:237-257 | c-level-advisor/skills/ciso-advisor/scripts/compliance_tracker.py:259-279 | c-level-advisor/skills/ciso-advisor/scripts/compliance_tracker.py:306-326 | c-level-advisor/skills/ciso-advisor/scripts/compliance_tracker.py:328-348 | c-level-advisor/skills/ciso-advisor/scripts/compliance_tracker.py:374-394 | c-level-advisor/skills/ciso-advisor/scripts/compliance_tracker.py:444-464 \u2014 all 10 copies are in the same file, so extract the block into one function there and call it from every one of those sites \u2014 resolving only two of them leaves the rest to drift apart the first time one is edited. Read the line range as the matched WINDOW rather than a finished unit: at \u0060c-level-advisor/skills/ciso-advisor/scripts/compliance_tracker.py:148\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":"c-level-advisor/skills/ciso-advisor/scripts/compliance_tracker.py"},"region":{"startLine":148}}}],"partialFingerprints":{"codehealthFindingId/v1":"c6254ca53078f65632f0013c137de93df32018bc9532421b74b077c7a00a4ddf"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (21 lines \u00D7 6): project-management/skills/scrum-master/scripts/retrospective_analyzer.py:867-887 | project-management/skills/scrum-master/scripts/sprint_health_scorer.py:697-717 | project-management/skills/scrum-master/scripts/velocity_analyzer.py:533-553 | project-management/skills/senior-pm/scripts/project_health_dashboard.py:767-787 | project-management/skills/senior-pm/scripts/resource_capacity_planner.py:799-819 | project-management/skills/senior-pm/scripts/risk_matrix_analyzer.py:651-671 \u2014 the copies span different directories, so extracting a shared function means choosing where it lives: put it somewhere all 6 call sites can already reach \u2014 a location they all depend on today, or a new shared one if there is none \u2014 and call it from each site; until then, every change has to be made 6 times."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"project-management/skills/scrum-master/scripts/retrospective_analyzer.py"},"region":{"startLine":867}}}],"partialFingerprints":{"codehealthFindingId/v1":"b5864e4ca21a32a4c2326f10d89f2242d591ed9a0b9a288f44200b1bd1a22f9b"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5\u201321 lines \u00D7 5): engineering-team/skills/senior-frontend/scripts/component_generator.py:264-284 | engineering-team/skills/senior-frontend/scripts/frontend_scaffolder.py:940-960 | markdown-html/skills/md-slides/scripts/deck_html_renderer.py:535-542 | productivity/meetings/skills/meetings/scripts/meeting_cost_calculator.py:146-151 | scripts/check_model_freshness.py:176-180 \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. Read the line range as the matched WINDOW rather than a finished unit: at \u0060engineering-team/skills/senior-frontend/scripts/component_generator.py:264\u0060 it begins part-way through the construct above it, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that. Note that the copies do not run to the end of the range shown: their LAST lines are different code, not the same code under different names \u2014 the matched region ends inside that line. Extract the lines above it, and read the last line of each site separately."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/skills/senior-frontend/scripts/component_generator.py"},"region":{"startLine":264}}}],"partialFingerprints":{"codehealthFindingId/v1":"101aa44af0d587ef53bda1202aa915a7924cd93e24be2f19febad7b06a2aeada"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (19\u201321 lines \u00D7 5): markdown-html/skills/design-system/scripts/config_loader.py:121-141 | research-ops/skills/clinical-research/scripts/config_loader.py:101-119 | research-ops/skills/market-research/scripts/config_loader.py:92-110 | research-ops/skills/product-research/scripts/config_loader.py:92-110 | research-ops/skills/research-finance/scripts/config_loader.py:93-111 \u2014 before extracting anything, compare \u0060markdown-html/skills/design-system/scripts/config_loader.py\u0060 and \u0060research-ops/skills/clinical-research/scripts/config_loader.py\u0060 as WHOLE FILES: this scan already matched 6 separate duplicated blocks between them, totalling at least 60 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The \u0060return\u0060 at the foot of the matched lines is the enclosing body\u0027s own terminal exit, not an early one: it moves with them unchanged, and each site calls the extracted unit from the position that \u0060return\u0060 occupied \u2014 no decision has to be handed back and re-acted on."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"markdown-html/skills/design-system/scripts/config_loader.py"},"region":{"startLine":121}}}],"partialFingerprints":{"codehealthFindingId/v1":"4f358f996b8708e85468510604907396f6688110cf5d1fe8778a21e1e68a5793"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (21 lines \u00D7 4): ra-qm-team/skills/capa-officer/scripts/capa_tracker.py:473-493 | ra-qm-team/skills/qms-audit-expert/scripts/audit_schedule_optimizer.py:356-376 | ra-qm-team/skills/quality-documentation-manager/scripts/document_validator.py:546-566 | ra-qm-team/skills/quality-manager-qmr/scripts/management_review_tracker.py:437-457 \u2014 the copies span different directories, so extracting a shared function means choosing where it lives: put it somewhere all 4 call sites can already reach \u2014 a location they all depend on today, or a new shared one if there is none \u2014 and call it from each site; until then, every change has to be made 4 times. Read the line range as the matched WINDOW rather than a finished unit: at \u0060ra-qm-team/skills/capa-officer/scripts/capa_tracker.py:473\u0060 it does not close everything it opens, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"ra-qm-team/skills/capa-officer/scripts/capa_tracker.py"},"region":{"startLine":473}}}],"partialFingerprints":{"codehealthFindingId/v1":"026499e40adf81df9c8ed238e9cc9c32c3079358a8c1902e4ab4d3b639ce8e58"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (21 lines \u00D7 3): business-operations/skills/process-mapper/scripts/bottleneck_detector.py:245-265 | business-operations/skills/process-mapper/scripts/cycle_time_analyzer.py:191-211 | business-operations/skills/process-mapper/scripts/process_documenter.py:247-267 \u2014 the copies sit in sibling files of one directory, so a shared home is within easy reach: extract the block into a single shared function the call sites can all reach \u2014 a file they already depend on, or a new one alongside them \u2014 and call it from all 3 call sites, so a change lands once. Read the line range as the matched WINDOW rather than a finished unit: at \u0060business-operations/skills/process-mapper/scripts/bottleneck_detector.py:245\u0060 it begins part-way through the construct above it, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"business-operations/skills/process-mapper/scripts/bottleneck_detector.py"},"region":{"startLine":245}}}],"partialFingerprints":{"codehealthFindingId/v1":"e120d6f9df4ec51bc97ead647b25246f2ecd1cab7ae6d457f50c65ab77f3e5b7"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (16\u201321 lines \u00D7 3): c-level-advisor/skills/org-health-diagnostic/scripts/health_scorer.py:158-178 | c-level-advisor/skills/org-health-diagnostic/scripts/health_scorer.py:183-203 | c-level-advisor/skills/org-health-diagnostic/scripts/health_scorer.py:243-258 \u2014 all 3 copies are in the same file, so extract the block into one function there and call it from every one of those sites \u2014 resolving only two of them leaves the rest to drift apart the first time one is edited. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"c-level-advisor/skills/org-health-diagnostic/scripts/health_scorer.py"},"region":{"startLine":158}}}],"partialFingerprints":{"codehealthFindingId/v1":"74683c17f967044425cff41125aaf9455e00330cef76fc8e6e83f40468dc41f3"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (21 lines \u00D7 3): engineering/skills/api-design-reviewer/scripts/api_linter.py:937-957 | engineering/skills/api-design-reviewer/scripts/api_scorecard.py:1634-1654 | engineering/skills/api-design-reviewer/scripts/breaking_change_detector.py:1081-1101 \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":"engineering/skills/api-design-reviewer/scripts/api_linter.py"},"region":{"startLine":937}}}],"partialFingerprints":{"codehealthFindingId/v1":"c6a66170547c32960e7f708c15f276e579a39f6b94c780f27b61201b0e4a6992"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (21 lines \u00D7 2): c-level-advisor/arquiteto-de-empresa/skills/arquiteto-de-empresa/scripts/index_generator.py:46-66 | c-level-advisor/skills/arquiteto-de-empresa/scripts/index_generator.py:46-66 \u2014 before extracting anything, compare \u0060c-level-advisor/arquiteto-de-empresa/skills/arquiteto-de-empresa/scripts/index_generator.py\u0060 and \u0060c-level-advisor/skills/arquiteto-de-empresa/scripts/index_generator.py\u0060 as WHOLE FILES: this scan already matched 10 separate duplicated blocks between them, totalling at least 135 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"c-level-advisor/arquiteto-de-empresa/skills/arquiteto-de-empresa/scripts/index_generator.py"},"region":{"startLine":46}}}],"partialFingerprints":{"codehealthFindingId/v1":"7cf767a9e31957066908f1654266975470124b765eaea7b10cbfe9ce5c693fac"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (21 lines \u00D7 2): c-level-advisor/chief-customer-officer-advisor/skills/chief-customer-officer-advisor/scripts/cs_coverage_calculator.py:221-241 | c-level-advisor/skills/chief-customer-officer-advisor/scripts/cs_coverage_calculator.py:221-241 \u2014 before extracting anything, compare \u0060c-level-advisor/chief-customer-officer-advisor/skills/chief-customer-officer-advisor/scripts/cs_coverage_calculator.py\u0060 and \u0060c-level-advisor/skills/chief-customer-officer-advisor/scripts/cs_coverage_calculator.py\u0060 as WHOLE FILES: this scan already matched 8 separate duplicated blocks between them, totalling at least 188 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The \u0060return\u0060 at the foot of the matched lines is the enclosing body\u0027s own terminal exit, not an early one: it moves with them unchanged, and each site calls the extracted unit from the position that \u0060return\u0060 occupied \u2014 no decision has to be handed back and re-acted on."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"c-level-advisor/chief-customer-officer-advisor/skills/chief-customer-officer-advisor/scripts/cs_coverage_calculator.py"},"region":{"startLine":221}}}],"partialFingerprints":{"codehealthFindingId/v1":"79a17ca5bf236b3d7da9a64c65942770b109c308826c7bf559df228519098536"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (21 lines \u00D7 2): c-level-advisor/general-counsel-advisor/skills/general-counsel-advisor/scripts/term_sheet_analyzer.py:388-408 | c-level-advisor/skills/general-counsel-advisor/scripts/term_sheet_analyzer.py:388-408 \u2014 before extracting anything, compare \u0060c-level-advisor/general-counsel-advisor/skills/general-counsel-advisor/scripts/term_sheet_analyzer.py\u0060 and \u0060c-level-advisor/skills/general-counsel-advisor/scripts/term_sheet_analyzer.py\u0060 as WHOLE FILES: this scan already matched 6 separate duplicated blocks between them, totalling at least 323 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"c-level-advisor/general-counsel-advisor/skills/general-counsel-advisor/scripts/term_sheet_analyzer.py"},"region":{"startLine":388}}}],"partialFingerprints":{"codehealthFindingId/v1":"4dc43f1a87533d13c9a528aea38e66c4a3e244cae5605059e0b10582cc39518e"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (20\u201321 lines \u00D7 2): engineering-team/skills/red-team/scripts/engagement_planner.py:320-339 | engineering/skills/skill-security-auditor/scripts/skill_security_auditor.py:1014-1034 \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 \u0060engineering-team/skills/red-team/scripts/engagement_planner.py:320\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":"engineering-team/skills/red-team/scripts/engagement_planner.py"},"region":{"startLine":320}}}],"partialFingerprints":{"codehealthFindingId/v1":"fe55c2dc4b59138e8c053f3ba3441d4981fdbe2e9853d4af90a88afc3fce6703"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (21 lines \u00D7 2): engineering/kubernetes-operator/skills/kubernetes-operator/scripts/crd_validator.py:44-64 | engineering/skills/kubernetes-operator/scripts/crd_validator.py:44-64 \u2014 before extracting anything, compare \u0060engineering/kubernetes-operator/skills/kubernetes-operator/scripts/crd_validator.py\u0060 and \u0060engineering/skills/kubernetes-operator/scripts/crd_validator.py\u0060 as WHOLE FILES: this scan already matched 8 separate duplicated blocks between them, totalling at least 79 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/kubernetes-operator/skills/kubernetes-operator/scripts/crd_validator.py"},"region":{"startLine":44}}}],"partialFingerprints":{"codehealthFindingId/v1":"a7297059f1d91108a5b7ed778c650e1051d48ef11c366f406db5e64b845d8cfb"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (21 lines \u00D7 2): engineering/skills/dependency-auditor/scripts/dep_scanner.py:474-494 | engineering/skills/dependency-auditor/scripts/dep_scanner.py:560-580 \u2014 both copies are in the same file, so extract the block 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 \u0060engineering/skills/dependency-auditor/scripts/dep_scanner.py:474\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":"engineering/skills/dependency-auditor/scripts/dep_scanner.py"},"region":{"startLine":474}}}],"partialFingerprints":{"codehealthFindingId/v1":"b221da02917faac4f631ea518da7b7457a764dd68965e19198f6de3a0b3e1a64"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (21 lines \u00D7 2): engineering/skills/migration-architect/scripts/migration_planner.py:637-657 | engineering/skills/migration-architect/scripts/rollback_generator.py:1085-1105 \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":"engineering/skills/migration-architect/scripts/migration_planner.py"},"region":{"startLine":637}}}],"partialFingerprints":{"codehealthFindingId/v1":"a76393d0c836d344b7e3f918a2f3d1cf6ec2897b29bb028e5e6616e7b195ba87"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (13\u201321 lines \u00D7 2): marketing/landing/skills/landing/scripts/kebab_slug_generator.py:36-48 | research/pulse/skills/pulse/scripts/topic_slug_generator.py:36-56 \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":"marketing/landing/skills/landing/scripts/kebab_slug_generator.py"},"region":{"startLine":36}}}],"partialFingerprints":{"codehealthFindingId/v1":"dd53ad3347e4019d457d92dd422c3c504bf056e11cafe3c69373434d447e5877"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (21 lines \u00D7 2): ra-qm-team/compliance-team-iso42001/skills/iso42001-specialist/scripts/ai_risk_register_builder.py:138-158 | ra-qm-team/skills/iso42001-specialist/scripts/ai_risk_register_builder.py:138-158 \u2014 before extracting anything, compare \u0060ra-qm-team/compliance-team-iso42001/skills/iso42001-specialist/scripts/ai_risk_register_builder.py\u0060 and \u0060ra-qm-team/skills/iso42001-specialist/scripts/ai_risk_register_builder.py\u0060 as WHOLE FILES: this scan already matched 12 separate duplicated blocks between them, totalling at least 132 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"ra-qm-team/compliance-team-iso42001/skills/iso42001-specialist/scripts/ai_risk_register_builder.py"},"region":{"startLine":138}}}],"partialFingerprints":{"codehealthFindingId/v1":"b9a87a90aa72b4b678dc51b961366ea48d35697c7b52341f8434908deecc7419"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (21 lines \u00D7 2): ra-qm-team/compliance-team-iso42001/skills/iso42001-specialist/scripts/aims_audit_scheduler.py:75-95 | ra-qm-team/skills/iso42001-specialist/scripts/aims_audit_scheduler.py:75-95 \u2014 before extracting anything, compare \u0060ra-qm-team/compliance-team-iso42001/skills/iso42001-specialist/scripts/aims_audit_scheduler.py\u0060 and \u0060ra-qm-team/skills/iso42001-specialist/scripts/aims_audit_scheduler.py\u0060 as WHOLE FILES: this scan already matched 9 separate duplicated blocks between them, totalling at least 151 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"ra-qm-team/compliance-team-iso42001/skills/iso42001-specialist/scripts/aims_audit_scheduler.py"},"region":{"startLine":75}}}],"partialFingerprints":{"codehealthFindingId/v1":"c435a8e93196c5c5d7ed8273857f364afde16015147f4452c9b23444d69ad35a"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (21 lines \u00D7 2): ra-qm-team/compliance-team-iso42001/skills/iso42001-specialist/scripts/aims_audit_scheduler.py:199-219 | ra-qm-team/skills/iso42001-specialist/scripts/aims_audit_scheduler.py:199-219 \u2014 before extracting anything, compare \u0060ra-qm-team/compliance-team-iso42001/skills/iso42001-specialist/scripts/aims_audit_scheduler.py\u0060 and \u0060ra-qm-team/skills/iso42001-specialist/scripts/aims_audit_scheduler.py\u0060 as WHOLE FILES: this scan already matched 9 separate duplicated blocks between them, totalling at least 151 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"ra-qm-team/compliance-team-iso42001/skills/iso42001-specialist/scripts/aims_audit_scheduler.py"},"region":{"startLine":199}}}],"partialFingerprints":{"codehealthFindingId/v1":"b15de6e6c2dc05072306fdf595fe6edb05a0a273813c238f89eed12272204f79"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (21 lines \u00D7 2): ra-qm-team/skills/information-security-manager-iso27001/scripts/compliance_checker.py:353-373 | ra-qm-team/skills/isms-audit-expert/scripts/isms_audit_scheduler.py:236-256 \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 \u0060ra-qm-team/skills/information-security-manager-iso27001/scripts/compliance_checker.py:353\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":"ra-qm-team/skills/information-security-manager-iso27001/scripts/compliance_checker.py"},"region":{"startLine":353}}}],"partialFingerprints":{"codehealthFindingId/v1":"e2537f4efaae4663ea87b101e2f4c7cfe63b96c51f3db2633fb351e9821ab16c"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (20 lines \u00D7 6): engineering-team/skills/senior-data-scientist/scripts/experiment_designer.py:42-61 | engineering-team/skills/senior-data-scientist/scripts/feature_engineering_pipeline.py:42-61 | engineering-team/skills/senior-data-scientist/scripts/model_evaluation_suite.py:42-61 | engineering-team/skills/senior-ml-engineer/scripts/ml_monitoring_suite.py:42-61 | engineering-team/skills/senior-ml-engineer/scripts/model_deployment_pipeline.py:42-61 | engineering-team/skills/senior-ml-engineer/scripts/rag_system_builder.py:42-61 \u2014 before extracting anything, compare \u0060engineering-team/skills/senior-data-scientist/scripts/experiment_designer.py\u0060 and \u0060engineering-team/skills/senior-data-scientist/scripts/feature_engineering_pipeline.py\u0060 as WHOLE FILES: 90% of the shorter file\u0027s lines also appear in the other, so this reads as one file having been copied from the other rather than as a helper waiting to be extracted. The 2 duplicated block(s) this scan matched between them are fragments of that copy, not the extent of it \u2014 treat the file pair as the unit. 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":"engineering-team/skills/senior-data-scientist/scripts/experiment_designer.py"},"region":{"startLine":42}}}],"partialFingerprints":{"codehealthFindingId/v1":"c3eb619c6a143a27a6221c41f7c8cf869c6a2d08e4a0bc24ec48528980579cdf"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (20 lines \u00D7 3): engineering-team/skills/incident-commander/scripts/incident_classifier.py:889-908 | engineering-team/skills/incident-commander/scripts/pir_generator.py:1613-1632 | engineering-team/skills/incident-commander/scripts/timeline_reconstructor.py:982-1001 \u2014 the copies sit in sibling files of one directory, so a shared home is within easy reach: extract the block into a single shared function the call sites can all reach \u2014 a file they already depend on, or a new one alongside them \u2014 and call it from all 3 call sites, so a change lands once. Read the line range as the matched WINDOW rather than a finished unit: at \u0060engineering-team/skills/incident-commander/scripts/pir_generator.py:1613\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":"engineering-team/skills/incident-commander/scripts/incident_classifier.py"},"region":{"startLine":889}}}],"partialFingerprints":{"codehealthFindingId/v1":"e9d8ac5fef938ab982afb9d926fc3fd139c3a5fce85f35d01657ab58e054b2b1"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (20 lines \u00D7 2): commercial/skills/channel-economics/scripts/channel_mix_optimizer.py:290-309 | commercial/skills/channel-economics/scripts/channel_roi_analyzer.py:238-257 \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 \u0060commercial/skills/channel-economics/scripts/channel_mix_optimizer.py:290\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":"commercial/skills/channel-economics/scripts/channel_mix_optimizer.py"},"region":{"startLine":290}}}],"partialFingerprints":{"codehealthFindingId/v1":"74b6a05b9d98093b3ca9d9574f5cc06597631df67cd09b2bbff18de885b1e78e"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (20 lines \u00D7 2): engineering-team/skills/senior-fullstack/scripts/code_quality_analyzer.py:662-681 | ra-qm-team/skills/gdpr-dsgvo-expert/scripts/gdpr_compliance_checker.py:414-433 \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 \u0060engineering-team/skills/senior-fullstack/scripts/code_quality_analyzer.py:662\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":"engineering-team/skills/senior-fullstack/scripts/code_quality_analyzer.py"},"region":{"startLine":662}}}],"partialFingerprints":{"codehealthFindingId/v1":"6e52eb3d4482168a61d3df33ca151bf14a44d45275e65feae28e617bdf34753a"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (20 lines \u00D7 2): engineering/chaos-engineering/skills/chaos-engineering/scripts/experiment_designer.py:116-135 | engineering/skills/chaos-engineering/scripts/experiment_designer.py:116-135 \u2014 before extracting anything, compare \u0060engineering/chaos-engineering/skills/chaos-engineering/scripts/experiment_designer.py\u0060 and \u0060engineering/skills/chaos-engineering/scripts/experiment_designer.py\u0060 as WHOLE FILES: this scan already matched 7 separate duplicated blocks between them, totalling at least 111 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The \u0060return\u0060 at the foot of the matched lines is the enclosing body\u0027s own terminal exit, not an early one: it moves with them unchanged, and each site calls the extracted unit from the position that \u0060return\u0060 occupied \u2014 no decision has to be handed back and re-acted on."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/chaos-engineering/skills/chaos-engineering/scripts/experiment_designer.py"},"region":{"startLine":116}}}],"partialFingerprints":{"codehealthFindingId/v1":"a09600407b1cc3e863d4aa5c4af481093495909afa2f70f4d1132c67d036ece0"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (20 lines \u00D7 2): engineering/terraform-patterns/skills/terraform-patterns/scripts/tf_security_scanner.py:358-377 | engineering/terraform-patterns/skills/terraform-patterns/scripts/tf_security_scanner.py:379-398 \u2014 both copies are in the same file, so extract the block 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 \u0060engineering/terraform-patterns/skills/terraform-patterns/scripts/tf_security_scanner.py:358\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":"engineering/terraform-patterns/skills/terraform-patterns/scripts/tf_security_scanner.py"},"region":{"startLine":358}}}],"partialFingerprints":{"codehealthFindingId/v1":"e8fbed35e66d682f970923f304bf84939f3fc1431082df8092c9ca156cbeed58"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (20 lines \u00D7 2): marketing-skill/skills/content-production/scripts/content_quality_gates.py:222-241 | marketing-skill/skills/copy-editing/scripts/ai_content_detector.py:240-259 \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":"marketing-skill/skills/content-production/scripts/content_quality_gates.py"},"region":{"startLine":222}}}],"partialFingerprints":{"codehealthFindingId/v1":"637972c605125f6e2873a99ad805d5b7cbc56588d7633d65b89a83a93e43eac2"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (20 lines \u00D7 2): project-management/skills/atlassian-templates/scripts/template_scaffolder.py:351-370 | project-management/skills/jira-expert/scripts/jql_query_builder.py:440-459 \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":"project-management/skills/atlassian-templates/scripts/template_scaffolder.py"},"region":{"startLine":351}}}],"partialFingerprints":{"codehealthFindingId/v1":"c48aa6df7b2fe7cc3c779ba1c0d416c55693025418654a7a4616e582bd6e0a65"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (4\u201319 lines \u00D7 8): engineering-team/skills/senior-data-scientist/scripts/experiment_designer.py:69-87 | engineering-team/skills/senior-data-scientist/scripts/feature_engineering_pipeline.py:69-87 | engineering-team/skills/senior-data-scientist/scripts/model_evaluation_suite.py:69-87 | engineering-team/skills/senior-ml-engineer/scripts/ml_monitoring_suite.py:69-87 | engineering-team/skills/senior-ml-engineer/scripts/model_deployment_pipeline.py:69-87 | engineering-team/skills/senior-ml-engineer/scripts/rag_system_builder.py:69-87 | engineering/skills/database-designer/index_optimizer.py:867-870 | engineering/skills/database-designer/migration_generator.py:1118-1121 \u2014 before extracting anything, compare \u0060engineering-team/skills/senior-data-scientist/scripts/experiment_designer.py\u0060 and \u0060engineering-team/skills/senior-data-scientist/scripts/feature_engineering_pipeline.py\u0060 as WHOLE FILES: 90% of the shorter file\u0027s lines also appear in the other, so this reads as one file having been copied from the other rather than as a helper waiting to be extracted. The 2 duplicated block(s) this scan matched between them are fragments of that copy, not the extent of it \u2014 treat the file pair as the unit. 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. 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":"engineering-team/skills/senior-data-scientist/scripts/experiment_designer.py"},"region":{"startLine":69}}}],"partialFingerprints":{"codehealthFindingId/v1":"08cf2afa7e3f17f3e02640c2bb322ee4f68c61a0bab35f86160e045c7cba1dcd"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (16\u201319 lines \u00D7 5): business-growth/skills/customer-success-manager/scripts/churn_risk_analyzer.py:454-469 | business-growth/skills/customer-success-manager/scripts/expansion_opportunity_scorer.py:381-396 | marketing-skill/skills/campaign-analytics/scripts/attribution_analyzer.py:298-316 | marketing-skill/skills/campaign-analytics/scripts/campaign_roi_calculator.py:414-432 | marketing-skill/skills/campaign-analytics/scripts/funnel_analyzer.py:251-269 \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. Read the line range as the matched WINDOW rather than a finished unit: at \u0060marketing-skill/skills/campaign-analytics/scripts/attribution_analyzer.py:298\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":"business-growth/skills/customer-success-manager/scripts/churn_risk_analyzer.py"},"region":{"startLine":454}}}],"partialFingerprints":{"codehealthFindingId/v1":"d35328e3aba9363d9f9be099fdc0d9aad9fda62f5aec7f4b75602e5810c01ea8"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (19 lines \u00D7 3): engineering-team/skills/senior-secops/scripts/compliance_checker.py:1058-1076 | engineering-team/skills/senior-secops/scripts/security_scanner.py:422-440 | engineering-team/skills/senior-secops/scripts/vulnerability_assessor.py:514-532 \u2014 the copies sit in sibling files of one directory, so a shared home is within easy reach: extract the block into a single shared function the call sites can all reach \u2014 a file they already depend on, or a new one alongside them \u2014 and call it from all 3 call sites, so a change lands once. Read the line range as the matched WINDOW rather than a finished unit: at \u0060engineering-team/skills/senior-secops/scripts/compliance_checker.py:1058\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":"engineering-team/skills/senior-secops/scripts/compliance_checker.py"},"region":{"startLine":1058}}}],"partialFingerprints":{"codehealthFindingId/v1":"f3986f04be7eeb48612df3b19a303cd1d0bdbdae11a3e6a49901d6f7d888257a"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (15\u201319 lines \u00D7 3): engineering/skills/tc-tracker/scripts/tc_create.py:249-264 | engineering/skills/tc-tracker/scripts/tc_init.py:164-182 | engineering/skills/tc-tracker/scripts/tc_update.py:338-352 \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":"engineering/skills/tc-tracker/scripts/tc_create.py"},"region":{"startLine":249}}}],"partialFingerprints":{"codehealthFindingId/v1":"247ada95a879610d37e687812f50b0706cb074563ddf4f4af68b4534874cb65b"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (19 lines \u00D7 3): marketing-skill/skills/analytics-tracking/scripts/tracking_plan_generator.py:355-373 | marketing-skill/skills/churn-prevention/scripts/churn_impact_calculator.py:167-185 | marketing-skill/skills/pricing-strategy/scripts/pricing_modeler.py:210-228 \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":"marketing-skill/skills/analytics-tracking/scripts/tracking_plan_generator.py"},"region":{"startLine":355}}}],"partialFingerprints":{"codehealthFindingId/v1":"e97e2f145742da935f65a767f327edfff565dbcc7b6653c8390d51bc3d7e45cc"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (19 lines \u00D7 3): ra-qm-team/skills/fda-consultant-specialist/scripts/fda_submission_tracker.py:447-465 | ra-qm-team/skills/fda-consultant-specialist/scripts/hipaa_risk_assessment.py:548-566 | ra-qm-team/skills/fda-consultant-specialist/scripts/qsr_compliance_checker.py:593-611 \u2014 the copies sit in sibling files of one directory, so a shared home is within easy reach: extract the block into a single shared function the call sites can all reach \u2014 a file they already depend on, or a new one alongside them \u2014 and call it from all 3 call sites, so a change lands once. Read the line range as the matched WINDOW rather than a finished unit: at \u0060ra-qm-team/skills/fda-consultant-specialist/scripts/fda_submission_tracker.py:447\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":"ra-qm-team/skills/fda-consultant-specialist/scripts/fda_submission_tracker.py"},"region":{"startLine":447}}}],"partialFingerprints":{"codehealthFindingId/v1":"afb863c1b6da053f6bd004fe2148d1dcc235008f56cb7233282869e805f5f117"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (15\u201319 lines \u00D7 2): business-operations/skills/capacity-planner/scripts/capacity_modeler.py:384-402 | business-operations/skills/capacity-planner/scripts/hiring_sequencer.py:311-325 \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 \u0060business-operations/skills/capacity-planner/scripts/capacity_modeler.py:384\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":"business-operations/skills/capacity-planner/scripts/capacity_modeler.py"},"region":{"startLine":384}}}],"partialFingerprints":{"codehealthFindingId/v1":"aadbd9d10081cf1313faece6b244b55cd895bd73d670434451e6593371b3a0c6"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (19 lines \u00D7 2): business-operations/skills/process-mapper/scripts/bottleneck_detector.py:131-149 | business-operations/skills/process-mapper/scripts/bottleneck_detector.py:158-176 \u2014 both copies are in the same file, so extract the block 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 \u0060business-operations/skills/process-mapper/scripts/bottleneck_detector.py:131\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":"business-operations/skills/process-mapper/scripts/bottleneck_detector.py"},"region":{"startLine":131}}}],"partialFingerprints":{"codehealthFindingId/v1":"c737ce70abd5d2739f1350586fca3f6e09e9589dd9233c06856958ec5c3cf0cc"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (19 lines \u00D7 2): c-level-advisor/general-counsel-advisor/skills/general-counsel-advisor/scripts/contract_risk_scanner.py:293-311 | c-level-advisor/skills/general-counsel-advisor/scripts/contract_risk_scanner.py:293-311 \u2014 before extracting anything, compare \u0060c-level-advisor/general-counsel-advisor/skills/general-counsel-advisor/scripts/contract_risk_scanner.py\u0060 and \u0060c-level-advisor/skills/general-counsel-advisor/scripts/contract_risk_scanner.py\u0060 as WHOLE FILES: this scan already matched 5 separate duplicated blocks between them, totalling at least 106 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"c-level-advisor/general-counsel-advisor/skills/general-counsel-advisor/scripts/contract_risk_scanner.py"},"region":{"startLine":293}}}],"partialFingerprints":{"codehealthFindingId/v1":"ad1d4774875d9300484cbb76730a85458e02fa0402ef2188fc26eb27431e42b8"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (19 lines \u00D7 2): c-level-advisor/skills/vpe-advisor/scripts/delivery_throughput_analyzer.py:154-172 | c-level-advisor/vpe-advisor/skills/vpe-advisor/scripts/delivery_throughput_analyzer.py:154-172 \u2014 before extracting anything, compare \u0060c-level-advisor/skills/vpe-advisor/scripts/delivery_throughput_analyzer.py\u0060 and \u0060c-level-advisor/vpe-advisor/skills/vpe-advisor/scripts/delivery_throughput_analyzer.py\u0060 as WHOLE FILES: this scan already matched 12 separate duplicated blocks between them, totalling at least 119 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. Read the line range as the matched WINDOW rather than a finished unit: at \u0060c-level-advisor/skills/vpe-advisor/scripts/delivery_throughput_analyzer.py:154\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."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"c-level-advisor/skills/vpe-advisor/scripts/delivery_throughput_analyzer.py"},"region":{"startLine":154}}}],"partialFingerprints":{"codehealthFindingId/v1":"71f20c012d4767acc554c16eabf9e5561f78436a2f51cbbec2d9acb33bfe3741"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (19 lines \u00D7 2): commercial/skills/commercial-policy/scripts/exception_router.py:236-254 | commercial/skills/commercial-policy/scripts/policy_linter.py:331-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. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"commercial/skills/commercial-policy/scripts/exception_router.py"},"region":{"startLine":236}}}],"partialFingerprints":{"codehealthFindingId/v1":"7d4ebf2b10ff1b8734aea1ea4bfd904a241085b735f8671cf3451909e63122e9"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (19 lines \u00D7 2): engineering-team/skills/ai-security/scripts/ai_threat_scanner.py:364-382 | engineering-team/skills/red-team/scripts/engagement_planner.py:321-339 \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 \u0060engineering-team/skills/ai-security/scripts/ai_threat_scanner.py:364\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":"engineering-team/skills/ai-security/scripts/ai_threat_scanner.py"},"region":{"startLine":364}}}],"partialFingerprints":{"codehealthFindingId/v1":"859840a8185c7aae7c58d1fc93293c681a0eb49a3bcb3a30c9c5792d12d68932"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (17\u201319 lines \u00D7 2): engineering-team/skills/senior-backend/scripts/backend_decision_engine.py:110-126 | engineering-team/skills/senior-fullstack/scripts/fullstack_decision_engine.py:106-124 \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 \u0060engineering-team/skills/senior-fullstack/scripts/fullstack_decision_engine.py:106\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":"engineering-team/skills/senior-backend/scripts/backend_decision_engine.py"},"region":{"startLine":110}}}],"partialFingerprints":{"codehealthFindingId/v1":"964940eac81a83e62d81e2138bb28455bd6f7bf24e90d9f00b499db054c3f297"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (19 lines \u00D7 2): engineering/feature-flags-architect/skills/feature-flags-architect/scripts/flag_debt_scanner.py:80-98 | engineering/skills/feature-flags-architect/scripts/flag_debt_scanner.py:80-98 \u2014 before extracting anything, compare \u0060engineering/feature-flags-architect/skills/feature-flags-architect/scripts/flag_debt_scanner.py\u0060 and \u0060engineering/skills/feature-flags-architect/scripts/flag_debt_scanner.py\u0060 as WHOLE FILES: this scan already matched 7 separate duplicated blocks between them, totalling at least 77 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The \u0060return\u0060 at the foot of the matched lines is the enclosing body\u0027s own terminal exit, not an early one: it moves with them unchanged, and each site calls the extracted unit from the position that \u0060return\u0060 occupied \u2014 no decision has to be handed back and re-acted on."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/feature-flags-architect/skills/feature-flags-architect/scripts/flag_debt_scanner.py"},"region":{"startLine":80}}}],"partialFingerprints":{"codehealthFindingId/v1":"c5cfda8519e5d6fcd22fcb5856f8ffaf3b5281123e09539fba2d80f030f855fe"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (19 lines \u00D7 2): engineering/feature-flags-architect/skills/feature-flags-architect/scripts/rollout_planner.py:101-119 | engineering/skills/feature-flags-architect/scripts/rollout_planner.py:101-119 \u2014 before extracting anything, compare \u0060engineering/feature-flags-architect/skills/feature-flags-architect/scripts/rollout_planner.py\u0060 and \u0060engineering/skills/feature-flags-architect/scripts/rollout_planner.py\u0060 as WHOLE FILES: this scan already matched 5 separate duplicated blocks between them, totalling at least 68 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/feature-flags-architect/skills/feature-flags-architect/scripts/rollout_planner.py"},"region":{"startLine":101}}}],"partialFingerprints":{"codehealthFindingId/v1":"438bd710ddc95e0bf156b2ca18b5b65f8e6221d4139f6d4ba709c315b7ea9369"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (19 lines \u00D7 2): engineering/skills/browser-automation/scripts/form_automation_builder.py:300-318 | engineering/skills/browser-automation/scripts/scraping_toolkit.py:226-244 \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. 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":"engineering/skills/browser-automation/scripts/form_automation_builder.py"},"region":{"startLine":300}}}],"partialFingerprints":{"codehealthFindingId/v1":"226499662792fbcff9dbe8db77138b7aaca2c192c29c2ca37309fc2ba828d137"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (17\u201319 lines \u00D7 2): finance/skills/financial-analyst/scripts/budget_variance_analyzer.py:145-163 | finance/skills/financial-analyst/scripts/budget_variance_analyzer.py:182-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."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"finance/skills/financial-analyst/scripts/budget_variance_analyzer.py"},"region":{"startLine":145}}}],"partialFingerprints":{"codehealthFindingId/v1":"aa0bef9b9227c38804ff658a5f4303b1ff9447ee6198291de44e89dc7cd4c6c0"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (19 lines \u00D7 2): project-management/skills/scrum-master/scripts/sprint_health_scorer.py:279-297 | project-management/skills/scrum-master/scripts/sprint_health_scorer.py:409-427 \u2014 both copies are in the same file, so extract the block 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":"project-management/skills/scrum-master/scripts/sprint_health_scorer.py"},"region":{"startLine":279}}}],"partialFingerprints":{"codehealthFindingId/v1":"f5c3ec31a4953ecddbcee0b43c88678615b6f55e4f436187eb21368d04667816"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (19 lines \u00D7 2): ra-qm-team/compliance-team-eu-ai-act/skills/eu-ai-act-specialist/scripts/ai_act_obligation_tracker.py:163-181 | ra-qm-team/skills/eu-ai-act-specialist/scripts/ai_act_obligation_tracker.py:163-181 \u2014 before extracting anything, compare \u0060ra-qm-team/compliance-team-eu-ai-act/skills/eu-ai-act-specialist/scripts/ai_act_obligation_tracker.py\u0060 and \u0060ra-qm-team/skills/eu-ai-act-specialist/scripts/ai_act_obligation_tracker.py\u0060 as WHOLE FILES: this scan already matched 11 separate duplicated blocks between them, totalling at least 122 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"ra-qm-team/compliance-team-eu-ai-act/skills/eu-ai-act-specialist/scripts/ai_act_obligation_tracker.py"},"region":{"startLine":163}}}],"partialFingerprints":{"codehealthFindingId/v1":"1b09bbb3981d10c748ffa7d4e42c9033045f2dc252d3b0bd66366ee267cef089"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (19 lines \u00D7 2): ra-qm-team/compliance-team-eu-ai-act/skills/eu-ai-act-specialist/scripts/conformity_assessment_planner.py:214-232 | ra-qm-team/skills/eu-ai-act-specialist/scripts/conformity_assessment_planner.py:214-232 \u2014 before extracting anything, compare \u0060ra-qm-team/compliance-team-eu-ai-act/skills/eu-ai-act-specialist/scripts/conformity_assessment_planner.py\u0060 and \u0060ra-qm-team/skills/eu-ai-act-specialist/scripts/conformity_assessment_planner.py\u0060 as WHOLE FILES: this scan already matched 13 separate duplicated blocks between them, totalling at least 187 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The \u0060return\u0060 at the foot of the matched lines is the enclosing body\u0027s own terminal exit, not an early one: it moves with them unchanged, and each site calls the extracted unit from the position that \u0060return\u0060 occupied \u2014 no decision has to be handed back and re-acted on."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"ra-qm-team/compliance-team-eu-ai-act/skills/eu-ai-act-specialist/scripts/conformity_assessment_planner.py"},"region":{"startLine":214}}}],"partialFingerprints":{"codehealthFindingId/v1":"17c7da551b3c55617aed150faf7c86111bd98dcf5fdf6387ccb8b8804f6629cd"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (18 lines \u00D7 6): project-management/skills/scrum-master/scripts/retrospective_analyzer.py:893-910 | project-management/skills/scrum-master/scripts/sprint_health_scorer.py:723-740 | project-management/skills/scrum-master/scripts/velocity_analyzer.py:559-576 | project-management/skills/senior-pm/scripts/project_health_dashboard.py:793-810 | project-management/skills/senior-pm/scripts/resource_capacity_planner.py:825-842 | project-management/skills/senior-pm/scripts/risk_matrix_analyzer.py:677-694 \u2014 the copies span different directories, so extracting a shared function means choosing where it lives: put it somewhere all 6 call sites can already reach \u2014 a location they all depend on today, or a new shared one if there is none \u2014 and call it from each site; until then, every change has to be made 6 times. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"project-management/skills/scrum-master/scripts/retrospective_analyzer.py"},"region":{"startLine":893}}}],"partialFingerprints":{"codehealthFindingId/v1":"c6a8893361c5b494e3840af820d3ecebe5d51d55a540eda067222c9a97549299"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (18 lines \u00D7 3): engineering/skills/tech-debt-tracker/scripts/debt_dashboard.py:939-956 | engineering/skills/tech-debt-tracker/scripts/debt_prioritizer.py:826-843 | engineering/skills/tech-debt-tracker/scripts/debt_scanner.py:653-670 \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":"engineering/skills/tech-debt-tracker/scripts/debt_dashboard.py"},"region":{"startLine":939}}}],"partialFingerprints":{"codehealthFindingId/v1":"4370be940a0a847e228bd3587b3b4700202e4e369ba5d748a8b9e12952cba94d"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (16\u201318 lines \u00D7 3): marketing/linkedin/skills/linkedin-profile/scripts/about_section_builder.py:240-256 | marketing/linkedin/skills/linkedin-profile/scripts/profile_completeness_auditor.py:243-260 | marketing/linkedin/skills/linkedin-strategy/scripts/positioning_brief.py:262-277 \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. Read the line range as the matched WINDOW rather than a finished unit: at \u0060marketing/linkedin/skills/linkedin-profile/scripts/profile_completeness_auditor.py:243\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":"marketing/linkedin/skills/linkedin-profile/scripts/about_section_builder.py"},"region":{"startLine":240}}}],"partialFingerprints":{"codehealthFindingId/v1":"6f806ed864584a45b6a39df72eeb266c5d14a3f33622e831aff5c9e38da5f620"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (15\u201318 lines \u00D7 3): marketing/linkedin/skills/linkedin-skills/scripts/linkedin_goal_router.py:131-148 | product-team/skills/product-skills/scripts/product_goal_router.py:165-179 | project-management/skills/pm-skills/scripts/pm_goal_router.py:137-151 \u2014 before extracting anything, compare \u0060marketing/linkedin/skills/linkedin-skills/scripts/linkedin_goal_router.py\u0060 and \u0060product-team/skills/product-skills/scripts/product_goal_router.py\u0060 as WHOLE FILES: this scan already matched 8 separate duplicated blocks between them, totalling at least 79 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. Read the line range as the matched WINDOW rather than a finished unit: at \u0060marketing/linkedin/skills/linkedin-skills/scripts/linkedin_goal_router.py:131\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":"marketing/linkedin/skills/linkedin-skills/scripts/linkedin_goal_router.py"},"region":{"startLine":131}}}],"partialFingerprints":{"codehealthFindingId/v1":"e4853cfa5db605bcaf0d5ea79468d43f8abf822f55f1d965d9c6603071dacb85"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (17\u201318 lines \u00D7 2): business-operations/skills/capacity-planner/scripts/hiring_sequencer.py:320-337 | business-operations/skills/capacity-planner/scripts/utilization_analyzer.py:273-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 both call sites, so a change lands once. Read the line range as the matched WINDOW rather than a finished unit: at \u0060business-operations/skills/capacity-planner/scripts/hiring_sequencer.py:320\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, \u0060business-operations/skills/capacity-planner/scripts/utilization_analyzer.py:272\u0060 calls \u0060add_argument\u0060 and \u0060business-operations/skills/capacity-planner/scripts/hiring_sequencer.py:320\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":"business-operations/skills/capacity-planner/scripts/hiring_sequencer.py"},"region":{"startLine":320}}}],"partialFingerprints":{"codehealthFindingId/v1":"77449f547c5cd493323ec38259fec9e1c2319beb579e947a18e23d692eb1ae6b"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (18 lines \u00D7 2): c-level-advisor/chief-customer-officer-advisor/skills/chief-customer-officer-advisor/scripts/retention_decomposition_analyzer.py:250-267 | c-level-advisor/skills/chief-customer-officer-advisor/scripts/retention_decomposition_analyzer.py:250-267 \u2014 before extracting anything, compare \u0060c-level-advisor/chief-customer-officer-advisor/skills/chief-customer-officer-advisor/scripts/retention_decomposition_analyzer.py\u0060 and \u0060c-level-advisor/skills/chief-customer-officer-advisor/scripts/retention_decomposition_analyzer.py\u0060 as WHOLE FILES: this scan already matched 9 separate duplicated blocks between them, totalling at least 171 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"c-level-advisor/chief-customer-officer-advisor/skills/chief-customer-officer-advisor/scripts/retention_decomposition_analyzer.py"},"region":{"startLine":250}}}],"partialFingerprints":{"codehealthFindingId/v1":"812dbf54f1bbad19100b61b53d7056cbf95ae8723639f3206fe0523335fd5751"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (18 lines \u00D7 2): c-level-advisor/chief-data-officer-advisor/skills/chief-data-officer-advisor/scripts/ai_training_data_audit.py:377-394 | c-level-advisor/skills/chief-data-officer-advisor/scripts/ai_training_data_audit.py:377-394 \u2014 before extracting anything, compare \u0060c-level-advisor/chief-data-officer-advisor/skills/chief-data-officer-advisor/scripts/ai_training_data_audit.py\u0060 and \u0060c-level-advisor/skills/chief-data-officer-advisor/scripts/ai_training_data_audit.py\u0060 as WHOLE FILES: this scan already matched 8 separate duplicated blocks between them, totalling at least 314 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The \u0060return\u0060 at the foot of the matched lines is the enclosing body\u0027s own terminal exit, not an early one: it moves with them unchanged, and each site calls the extracted unit from the position that \u0060return\u0060 occupied \u2014 no decision has to be handed back and re-acted on."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"c-level-advisor/chief-data-officer-advisor/skills/chief-data-officer-advisor/scripts/ai_training_data_audit.py"},"region":{"startLine":377}}}],"partialFingerprints":{"codehealthFindingId/v1":"072301f4ef30f153ad3b41fa9f3821931e5154234c02f03bd25744bfac18f4fc"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (18 lines \u00D7 2): c-level-advisor/general-counsel-advisor/skills/general-counsel-advisor/scripts/term_sheet_analyzer.py:344-361 | c-level-advisor/skills/general-counsel-advisor/scripts/term_sheet_analyzer.py:344-361 \u2014 before extracting anything, compare \u0060c-level-advisor/general-counsel-advisor/skills/general-counsel-advisor/scripts/term_sheet_analyzer.py\u0060 and \u0060c-level-advisor/skills/general-counsel-advisor/scripts/term_sheet_analyzer.py\u0060 as WHOLE FILES: this scan already matched 6 separate duplicated blocks between them, totalling at least 323 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"c-level-advisor/general-counsel-advisor/skills/general-counsel-advisor/scripts/term_sheet_analyzer.py"},"region":{"startLine":344}}}],"partialFingerprints":{"codehealthFindingId/v1":"9f944fab16600222b3dcabec3bee7a14eaf7ac3da3c0dd691784b64fec98c8cd"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (18 lines \u00D7 2): engineering/karpathy-coder/skills/karpathy-coder/scripts/assumption_linter.py:112-129 | engineering/karpathy-coder/skills/karpathy-coder/scripts/goal_verifier.py:167-184 \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":"engineering/karpathy-coder/skills/karpathy-coder/scripts/assumption_linter.py"},"region":{"startLine":112}}}],"partialFingerprints":{"codehealthFindingId/v1":"5022b813c65bdaf6cffca64642b7ab4be3e9c8cad0aaa2b8b547c6947d68a1ed"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (18 lines \u00D7 2): engineering/skills/slo-architect/scripts/slo_review.py:155-172 | engineering/slo-architect/skills/slo-architect/scripts/slo_review.py:155-172 \u2014 before extracting anything, compare \u0060engineering/skills/slo-architect/scripts/slo_review.py\u0060 and \u0060engineering/slo-architect/skills/slo-architect/scripts/slo_review.py\u0060 as WHOLE FILES: this scan already matched 9 separate duplicated blocks between them, totalling at least 103 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/slo-architect/scripts/slo_review.py"},"region":{"startLine":155}}}],"partialFingerprints":{"codehealthFindingId/v1":"6e2621075e4222b468b3613abd27ac4556cb02bef18085f1bf58c2bc132a1b0e"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (17\u201318 lines \u00D7 2): marketing-skill/skills/competitor-alternatives/scripts/comparison_matrix_builder.py:218-235 | marketing-skill/skills/programmatic-seo/scripts/url_pattern_generator.py:132-148 \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":"marketing-skill/skills/competitor-alternatives/scripts/comparison_matrix_builder.py"},"region":{"startLine":218}}}],"partialFingerprints":{"codehealthFindingId/v1":"e29ef5cd60c2ca25f6a8ab6b9a6cb656f4244d9bca8b377709ab48ed20505f20"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (18 lines \u00D7 2): ra-qm-team/compliance-team-iso42001/skills/iso42001-specialist/scripts/ai_risk_register_builder.py:164-181 | ra-qm-team/skills/iso42001-specialist/scripts/ai_risk_register_builder.py:164-181 \u2014 before extracting anything, compare \u0060ra-qm-team/compliance-team-iso42001/skills/iso42001-specialist/scripts/ai_risk_register_builder.py\u0060 and \u0060ra-qm-team/skills/iso42001-specialist/scripts/ai_risk_register_builder.py\u0060 as WHOLE FILES: this scan already matched 12 separate duplicated blocks between them, totalling at least 132 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"ra-qm-team/compliance-team-iso42001/skills/iso42001-specialist/scripts/ai_risk_register_builder.py"},"region":{"startLine":164}}}],"partialFingerprints":{"codehealthFindingId/v1":"0cc6a9b1da6e5927b8dc48a8ab059475966a0571ed90bbbb091f5d08f9ea0a8c"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (17 lines \u00D7 42): c-level-advisor/chief-ai-officer-advisor/skills/chief-ai-officer-advisor/scripts/ai_cost_economics.py:321-337 | c-level-advisor/chief-ai-officer-advisor/skills/chief-ai-officer-advisor/scripts/ai_risk_classifier.py:449-465 | c-level-advisor/chief-ai-officer-advisor/skills/chief-ai-officer-advisor/scripts/model_buildvsbuy_calculator.py:335-351 | c-level-advisor/chief-customer-officer-advisor/skills/chief-customer-officer-advisor/scripts/cs_coverage_calculator.py:251-267 | c-level-advisor/chief-customer-officer-advisor/skills/chief-customer-officer-advisor/scripts/customer_segmentation_designer.py:321-337 | c-level-advisor/chief-customer-officer-advisor/skills/chief-customer-officer-advisor/scripts/retention_decomposition_analyzer.py:283-299 | c-level-advisor/chief-data-officer-advisor/skills/chief-data-officer-advisor/scripts/ai_training_data_audit.py:409-425 | c-level-advisor/chief-data-officer-advisor/skills/chief-data-officer-advisor/scripts/data_asset_valuator.py:344-360 | c-level-advisor/chief-data-officer-advisor/skills/chief-data-officer-advisor/scripts/data_product_strategy_picker.py:328-344 | c-level-advisor/general-counsel-advisor/skills/general-counsel-advisor/scripts/term_sheet_analyzer.py:378-394 | c-level-advisor/skills/chief-ai-officer-advisor/scripts/ai_cost_economics.py:321-337 | c-level-advisor/skills/chief-ai-officer-advisor/scripts/ai_risk_classifier.py:449-465 | c-level-advisor/skills/chief-ai-officer-advisor/scripts/model_buildvsbuy_calculator.py:335-351 | c-level-advisor/skills/chief-customer-officer-advisor/scripts/cs_coverage_calculator.py:251-267 | c-level-advisor/skills/chief-customer-officer-advisor/scripts/customer_segmentation_designer.py:321-337 | c-level-advisor/skills/chief-customer-officer-advisor/scripts/retention_decomposition_analyzer.py:283-299 | c-level-advisor/skills/chief-data-officer-advisor/scripts/ai_training_data_audit.py:409-425 | c-level-advisor/skills/chief-data-officer-advisor/scripts/data_asset_valuator.py:344-360 | c-level-advisor/skills/chief-data-officer-advisor/scripts/data_product_strategy_picker.py:328-344 | c-level-advisor/skills/general-counsel-advisor/scripts/term_sheet_analyzer.py:378-394 | c-level-advisor/skills/vpe-advisor/scripts/delivery_throughput_analyzer.py:248-264 | c-level-advisor/skills/vpe-advisor/scripts/eng_hiring_funnel_calculator.py:253-269 | c-level-advisor/skills/vpe-advisor/scripts/eng_team_structure_designer.py:249-265 | c-level-advisor/vpe-advisor/skills/vpe-advisor/scripts/delivery_throughput_analyzer.py:248-264 | c-level-advisor/vpe-advisor/skills/vpe-advisor/scripts/eng_hiring_funnel_calculator.py:253-269 | c-level-advisor/vpe-advisor/skills/vpe-advisor/scripts/eng_team_structure_designer.py:249-265 | compliance-os/skills/compliance-os/scripts/audit_simulator.py:369-385 | compliance-os/skills/compliance-os/scripts/cross_framework_mapper.py:403-419 | compliance-os/skills/compliance-os/scripts/evidence_pool_generator.py:327-343 | compliance-os/skills/compliance-os/scripts/framework_selector.py:287-303 | ra-qm-team/compliance-team-eu-ai-act/skills/eu-ai-act-specialist/scripts/ai_act_obligation_tracker.py:246-262 | ra-qm-team/compliance-team-eu-ai-act/skills/eu-ai-act-specialist/scripts/ai_system_risk_classifier.py:311-327 | ra-qm-team/compliance-team-eu-ai-act/skills/eu-ai-act-specialist/scripts/conformity_assessment_planner.py:282-298 | ra-qm-team/compliance-team-iso42001/skills/iso42001-specialist/scripts/ai_risk_register_builder.py:230-246 | ra-qm-team/compliance-team-iso42001/skills/iso42001-specialist/scripts/aims_audit_scheduler.py:235-251 | ra-qm-team/compliance-team-iso42001/skills/iso42001-specialist/scripts/aims_gap_analyzer.py:224-240 | ra-qm-team/skills/eu-ai-act-specialist/scripts/ai_act_obligation_tracker.py:246-262 | ra-qm-team/skills/eu-ai-act-specialist/scripts/ai_system_risk_classifier.py:311-327 | ra-qm-team/skills/eu-ai-act-specialist/scripts/conformity_assessment_planner.py:282-298 | ra-qm-team/skills/iso42001-specialist/scripts/ai_risk_register_builder.py:230-246 | ra-qm-team/skills/iso42001-specialist/scripts/aims_audit_scheduler.py:235-251 | ra-qm-team/skills/iso42001-specialist/scripts/aims_gap_analyzer.py:224-240 \u2014 the copies span different directories, so extracting a shared function means choosing where it lives: put it somewhere all 42 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 42 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":"c-level-advisor/chief-ai-officer-advisor/skills/chief-ai-officer-advisor/scripts/ai_cost_economics.py"},"region":{"startLine":321}}}],"partialFingerprints":{"codehealthFindingId/v1":"a9efe72aabfbd87f877ced3e855a885cfeda4a2fe1fca5a9ecc36145114f8a3f"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (15\u201317 lines \u00D7 13): engineering-team/skills/senior-secops/scripts/compliance_checker.py:511-527 | engineering-team/skills/senior-secops/scripts/compliance_checker.py:545-561 | engineering-team/skills/senior-secops/scripts/compliance_checker.py:577-593 | engineering-team/skills/senior-secops/scripts/compliance_checker.py:605-619 | engineering-team/skills/senior-secops/scripts/compliance_checker.py:671-685 | engineering-team/skills/senior-secops/scripts/compliance_checker.py:696-710 | engineering-team/skills/senior-secops/scripts/compliance_checker.py:721-735 | engineering-team/skills/senior-secops/scripts/compliance_checker.py:746-760 | engineering-team/skills/senior-secops/scripts/compliance_checker.py:771-785 | engineering-team/skills/senior-secops/scripts/compliance_checker.py:800-816 | engineering-team/skills/senior-secops/scripts/compliance_checker.py:827-841 | engineering-team/skills/senior-secops/scripts/compliance_checker.py:896-912 | engineering-team/skills/senior-secops/scripts/compliance_checker.py:927-943 \u2014 all 13 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 \u0060engineering-team/skills/senior-secops/scripts/compliance_checker.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."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/skills/senior-secops/scripts/compliance_checker.py"},"region":{"startLine":511}}}],"partialFingerprints":{"codehealthFindingId/v1":"6810d0837ce548c1299925d7ba308a4b80385388a483f6ae13b464794f5cb984"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (16\u201317 lines \u00D7 2): business-growth/skills/sales-engineer/scripts/poc_planner.py:582-598 | business-growth/skills/sales-engineer/scripts/rfp_response_analyzer.py:418-433 \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":"business-growth/skills/sales-engineer/scripts/poc_planner.py"},"region":{"startLine":582}}}],"partialFingerprints":{"codehealthFindingId/v1":"de4768b2b9bdf30bd0e3d9f496bed4bea675564bf7061490bf3f6faea009f444"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (17 lines \u00D7 2): c-level-advisor/arquiteto-de-empresa/skills/arquiteto-de-empresa/scripts/scaffold_bundle.py:72-88 | c-level-advisor/skills/arquiteto-de-empresa/scripts/scaffold_bundle.py:72-88 \u2014 before extracting anything, compare \u0060c-level-advisor/arquiteto-de-empresa/skills/arquiteto-de-empresa/scripts/scaffold_bundle.py\u0060 and \u0060c-level-advisor/skills/arquiteto-de-empresa/scripts/scaffold_bundle.py\u0060 as WHOLE FILES: this scan already matched 7 separate duplicated blocks between them, totalling at least 108 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"c-level-advisor/arquiteto-de-empresa/skills/arquiteto-de-empresa/scripts/scaffold_bundle.py"},"region":{"startLine":72}}}],"partialFingerprints":{"codehealthFindingId/v1":"3e14bc6bd733c837c776e990a9e9846c3035320fddec89794e0761d9602ec1d4"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (17 lines \u00D7 2): c-level-advisor/skills/chro-advisor/scripts/comp_benchmarker.py:579-595 | c-level-advisor/skills/chro-advisor/scripts/hiring_plan_modeler.py:538-554 \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":"c-level-advisor/skills/chro-advisor/scripts/comp_benchmarker.py"},"region":{"startLine":579}}}],"partialFingerprints":{"codehealthFindingId/v1":"316cd720d9cdf0368e3a07bb32830f421b633c0428b59c92729b23ceaf9b73ff"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (17 lines \u00D7 2): engineering-team/skills/code-reviewer/scripts/review_report_generator.py:52-68 | engineering-team/skills/code-reviewer/scripts/review_report_generator.py:72-88 \u2014 both copies are in the same file, so extract the block 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":"engineering-team/skills/code-reviewer/scripts/review_report_generator.py"},"region":{"startLine":52}}}],"partialFingerprints":{"codehealthFindingId/v1":"18b2b391bc075d210740604aab51e85e7585bd5fa5f628714699bb6ba976752f"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (15\u201317 lines \u00D7 2): engineering-team/skills/senior-architect/scripts/architecture_diagram_generator.py:304-320 | engineering-team/skills/senior-architect/scripts/architecture_diagram_generator.py:402-416 \u2014 both copies are in the same file, so extract the block 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 \u0060engineering-team/skills/senior-architect/scripts/architecture_diagram_generator.py:402\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":"engineering-team/skills/senior-architect/scripts/architecture_diagram_generator.py"},"region":{"startLine":304}}}],"partialFingerprints":{"codehealthFindingId/v1":"1c6b4df3716dd8e3de2a069f239e61ac5dd8b9b3eae6116889e66dcd4489a770"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (17 lines \u00D7 2): engineering-team/skills/senior-data-engineer/scripts/data_quality_validator.py:1616-1632 | engineering-team/skills/senior-data-engineer/scripts/etl_performance_optimizer.py:1665-1681 \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":"engineering-team/skills/senior-data-engineer/scripts/data_quality_validator.py"},"region":{"startLine":1616}}}],"partialFingerprints":{"codehealthFindingId/v1":"8d4dc2af4b7bbe6921a81518720474bfcdd632e652ae5d115836b4c3ba2d7f65"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (17 lines \u00D7 2): engineering-team/skills/senior-qa/scripts/coverage_analyzer.py:209-228 | engineering-team/skills/tdd-guide/scripts/coverage_analyzer.py:58-74 \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":"engineering-team/skills/senior-qa/scripts/coverage_analyzer.py"},"region":{"startLine":209}}}],"partialFingerprints":{"codehealthFindingId/v1":"c7edbffd7fd4f093922f715aa39167ee34e973bea681996f5e46d0ad30a647b8"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (15\u201317 lines \u00D7 2): engineering/skills/skill-tester/scripts/script_tester.py:636-652 | engineering/skills/skill-tester/scripts/skill_validator.py:611-625 \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":"engineering/skills/skill-tester/scripts/script_tester.py"},"region":{"startLine":636}}}],"partialFingerprints":{"codehealthFindingId/v1":"661224d6596e205d537a357ce7505374f4733c690526a66b16cd92f1e7d1cbb6"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (11\u201317 lines \u00D7 2): finance/skills/stock-analysis/scripts/score.py:1264-1274 | finance/skills/stock-analysis/scripts/score.py:1398-1414 \u2014 both copies are in the same file, so extract the block 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":"finance/skills/stock-analysis/scripts/score.py"},"region":{"startLine":1264}}}],"partialFingerprints":{"codehealthFindingId/v1":"4702a0843be7f62eb1c409741fe307e5d3ea5a1f6d325e3d7575ef3cc05822f2"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (17 lines \u00D7 2): marketing-skill/skills/schema-markup/scripts/schema_validator.py:393-409 | marketing-skill/skills/site-architecture/scripts/sitemap_analyzer.py:331-347 \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":"marketing-skill/skills/schema-markup/scripts/schema_validator.py"},"region":{"startLine":393}}}],"partialFingerprints":{"codehealthFindingId/v1":"31498832df2885d63191c5e9985931f3abedd65c5e82c03527e65cae6fd90b1f"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (17 lines \u00D7 2): ra-qm-team/compliance-team-eu-ai-act/skills/eu-ai-act-specialist/scripts/ai_system_risk_classifier.py:275-291 | ra-qm-team/skills/eu-ai-act-specialist/scripts/ai_system_risk_classifier.py:275-291 \u2014 before extracting anything, compare \u0060ra-qm-team/compliance-team-eu-ai-act/skills/eu-ai-act-specialist/scripts/ai_system_risk_classifier.py\u0060 and \u0060ra-qm-team/skills/eu-ai-act-specialist/scripts/ai_system_risk_classifier.py\u0060 as WHOLE FILES: this scan already matched 7 separate duplicated blocks between them, totalling at least 156 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"ra-qm-team/compliance-team-eu-ai-act/skills/eu-ai-act-specialist/scripts/ai_system_risk_classifier.py"},"region":{"startLine":275}}}],"partialFingerprints":{"codehealthFindingId/v1":"e974c2381f0bcf2c52fd538abfd39aabf9484b4df541c92fcc90704af758f59a"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (16 lines \u00D7 14): engineering-team/skills/senior-secops/scripts/compliance_checker.py:483-498 | engineering-team/skills/senior-secops/scripts/compliance_checker.py:515-530 | engineering-team/skills/senior-secops/scripts/compliance_checker.py:549-564 | engineering-team/skills/senior-secops/scripts/compliance_checker.py:581-596 | engineering-team/skills/senior-secops/scripts/compliance_checker.py:607-622 | engineering-team/skills/senior-secops/scripts/compliance_checker.py:673-688 | engineering-team/skills/senior-secops/scripts/compliance_checker.py:698-713 | engineering-team/skills/senior-secops/scripts/compliance_checker.py:723-738 | engineering-team/skills/senior-secops/scripts/compliance_checker.py:748-763 | engineering-team/skills/senior-secops/scripts/compliance_checker.py:773-788 | engineering-team/skills/senior-secops/scripts/compliance_checker.py:804-819 | engineering-team/skills/senior-secops/scripts/compliance_checker.py:829-844 | engineering-team/skills/senior-secops/scripts/compliance_checker.py:900-915 | engineering-team/skills/senior-secops/scripts/compliance_checker.py:931-946 \u2014 all 14 copies are in the same file, so extract the block into one function there and call it from every one of those sites \u2014 resolving only two of them leaves the rest to drift apart the first time one is edited. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/skills/senior-secops/scripts/compliance_checker.py"},"region":{"startLine":483}}}],"partialFingerprints":{"codehealthFindingId/v1":"ffd10ab7676e0170a6d2f73f6c6bcb1d7b8ab684f5e00a9a962b8dcaf94c2dd3"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (16 lines \u00D7 4): engineering/docker-development/skills/docker-development/scripts/compose_validator.py:359-374 | engineering/docker-development/skills/docker-development/scripts/dockerfile_analyzer.py:379-394 | engineering/helm-chart-builder/skills/helm-chart-builder/scripts/chart_analyzer.py:504-519 | engineering/helm-chart-builder/skills/helm-chart-builder/scripts/values_validator.py:411-426 \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."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/docker-development/skills/docker-development/scripts/compose_validator.py"},"region":{"startLine":359}}}],"partialFingerprints":{"codehealthFindingId/v1":"3dd1917f73b2f0b9834bb8bcf293e32a0e594700fa4916a02ab006f53268128c"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (15\u201316 lines \u00D7 3): business-operations/skills/internal-comms/scripts/change_announcement_builder.py:304-319 | business-operations/skills/internal-comms/scripts/comms_calendar_builder.py:263-277 | business-operations/skills/internal-comms/scripts/comms_template_filler.py:316-330 \u2014 the copies sit in sibling files of one directory, so a shared home is within easy reach: extract the block into a single shared function the call sites can all reach \u2014 a file they already depend on, or a new one alongside them \u2014 and call it from all 3 call sites, so a change lands once. Read the line range as the matched WINDOW rather than a finished unit: at \u0060business-operations/skills/internal-comms/scripts/change_announcement_builder.py:304\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":"business-operations/skills/internal-comms/scripts/change_announcement_builder.py"},"region":{"startLine":304}}}],"partialFingerprints":{"codehealthFindingId/v1":"101ce7e8dfdc0739e9faf7099c888ed7490f7ef27056638fa2a992ef503eb980"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (15\u201316 lines \u00D7 3): business-operations/skills/procurement-optimizer/scripts/purchasing_cycle_analyzer.py:261-275 | business-operations/skills/procurement-optimizer/scripts/spend_categorizer.py:368-383 | business-operations/skills/procurement-optimizer/scripts/supplier_consolidation.py:368-383 \u2014 the copies sit in sibling files of one directory, so a shared home is within easy reach: extract the block into a single shared function the call sites can all reach \u2014 a file they already depend on, or a new one alongside them \u2014 and call it from all 3 call sites, so a change lands once. Read the line range as the matched WINDOW rather than a finished unit: at \u0060business-operations/skills/procurement-optimizer/scripts/spend_categorizer.py:368\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":"business-operations/skills/procurement-optimizer/scripts/purchasing_cycle_analyzer.py"},"region":{"startLine":261}}}],"partialFingerprints":{"codehealthFindingId/v1":"c42e45f0a84ce22363cdd09ea737c81ede7e6d6956cc92ec8db6cf32871d473b"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (15\u201316 lines \u00D7 3): research/grants/skills/grants/scripts/citation_tracker.py:176-190 | research/litreview/skills/litreview/scripts/citation_tracker.py:140-155 | research/pulse/skills/pulse/scripts/citation_tracker.py:395-409 \u2014 before extracting anything, compare \u0060research/grants/skills/grants/scripts/citation_tracker.py\u0060 and \u0060research/litreview/skills/litreview/scripts/citation_tracker.py\u0060 as WHOLE FILES: this scan already matched 7 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. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"research/grants/skills/grants/scripts/citation_tracker.py"},"region":{"startLine":176}}}],"partialFingerprints":{"codehealthFindingId/v1":"b8feb9d76053bc9fc83e753ba76a8352503c6396611a2609859ef140d474a4ce"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (15\u201316 lines \u00D7 2): business-operations/skills/capacity-planner/scripts/capacity_modeler.py:404-419 | business-operations/skills/capacity-planner/scripts/hiring_sequencer.py:327-341 \u2014 the copies sit in sibling files of one directory, so a shared home is within easy reach: extract the block into a single shared function the call sites can all reach \u2014 a file they already depend on, or a new one alongside them \u2014 and call it from both call sites, so a change lands once. Read the line range as the matched WINDOW rather than a finished unit: at \u0060business-operations/skills/capacity-planner/scripts/capacity_modeler.py:404\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, \u0060business-operations/skills/capacity-planner/scripts/hiring_sequencer.py:325\u0060 calls \u0060add_argument\u0060, \u0060parse_args\u0060 and \u0060business-operations/skills/capacity-planner/scripts/capacity_modeler.py:404\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":"business-operations/skills/capacity-planner/scripts/capacity_modeler.py"},"region":{"startLine":404}}}],"partialFingerprints":{"codehealthFindingId/v1":"79bbd72a59fc2fd90ce5b3fe082d0e11c568b31cef491743195aab2e252c80a0"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (16 lines \u00D7 2): c-level-advisor/chief-customer-officer-advisor/skills/chief-customer-officer-advisor/scripts/cs_coverage_calculator.py:77-92 | c-level-advisor/skills/chief-customer-officer-advisor/scripts/cs_coverage_calculator.py:77-92 \u2014 before extracting anything, compare \u0060c-level-advisor/chief-customer-officer-advisor/skills/chief-customer-officer-advisor/scripts/cs_coverage_calculator.py\u0060 and \u0060c-level-advisor/skills/chief-customer-officer-advisor/scripts/cs_coverage_calculator.py\u0060 as WHOLE FILES: this scan already matched 8 separate duplicated blocks between them, totalling at least 188 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"c-level-advisor/chief-customer-officer-advisor/skills/chief-customer-officer-advisor/scripts/cs_coverage_calculator.py"},"region":{"startLine":77}}}],"partialFingerprints":{"codehealthFindingId/v1":"b77dd1e60778b080f622e057248621ac1692402cac9950bac301d57c6cbec80f"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (16 lines \u00D7 2): c-level-advisor/skills/coo-advisor/scripts/okr_tracker.py:240-255 | c-level-advisor/skills/coo-advisor/scripts/okr_tracker.py:258-273 \u2014 both copies are in the same file, so extract the block 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":"c-level-advisor/skills/coo-advisor/scripts/okr_tracker.py"},"region":{"startLine":240}}}],"partialFingerprints":{"codehealthFindingId/v1":"b7c004dc773397455fff2e1bf89bd422c3fade3d336602227f57e2012b5a27c4"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (16 lines \u00D7 2): c-level-advisor/skills/coo-advisor/scripts/okr_tracker.py:727-742 | c-level-advisor/skills/coo-advisor/scripts/ops_efficiency_analyzer.py:798-813 \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 \u0060c-level-advisor/skills/coo-advisor/scripts/okr_tracker.py:727\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":"c-level-advisor/skills/coo-advisor/scripts/okr_tracker.py"},"region":{"startLine":727}}}],"partialFingerprints":{"codehealthFindingId/v1":"6b5037355d13c346bee704cce1f452bdb08302ec6add4baaab8e3b139f355cb4"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (15\u201316 lines \u00D7 2): commercial/skills/rfp-responder/scripts/response_drafter.py:263-277 | commercial/skills/rfp-responder/scripts/winrate_predictor.py:230-245 \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 \u0060commercial/skills/rfp-responder/scripts/winrate_predictor.py:230\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":"commercial/skills/rfp-responder/scripts/response_drafter.py"},"region":{"startLine":263}}}],"partialFingerprints":{"codehealthFindingId/v1":"f79f4149eeeeede9a61db6c9cfeae9c4a00d934a19f62b3ee466e4c6892531c1"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (16 lines \u00D7 2): engineering-team/skills/aws-solution-architect/scripts/cost_optimizer.py:153-169 | engineering-team/skills/gcp-cloud-architect/scripts/cost_optimizer.py:177-192 \u2014 before extracting anything, compare \u0060engineering-team/skills/aws-solution-architect/scripts/cost_optimizer.py\u0060 and \u0060engineering-team/skills/gcp-cloud-architect/scripts/cost_optimizer.py\u0060 as WHOLE FILES: this scan already matched 6 separate duplicated blocks between them, totalling at least 200 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/skills/aws-solution-architect/scripts/cost_optimizer.py"},"region":{"startLine":153}}}],"partialFingerprints":{"codehealthFindingId/v1":"f047a0c2eaa354966263e1f4026b706dfb4709730d3b340ee4047500b6a1e0d8"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (16 lines \u00D7 2): engineering-team/skills/aws-solution-architect/scripts/cost_optimizer.py:173-188 | engineering-team/skills/gcp-cloud-architect/scripts/cost_optimizer.py:195-210 \u2014 before extracting anything, compare \u0060engineering-team/skills/aws-solution-architect/scripts/cost_optimizer.py\u0060 and \u0060engineering-team/skills/gcp-cloud-architect/scripts/cost_optimizer.py\u0060 as WHOLE FILES: this scan already matched 6 separate duplicated blocks between them, totalling at least 200 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/skills/aws-solution-architect/scripts/cost_optimizer.py"},"region":{"startLine":173}}}],"partialFingerprints":{"codehealthFindingId/v1":"bafc4c7fe8a8db8573858c49f9c900eaba065c5c3cd79e99688baea4dcc8505d"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (16 lines \u00D7 2): engineering-team/skills/senior-architect/scripts/architecture_diagram_generator.py:405-420 | engineering-team/skills/senior-architect/scripts/architecture_diagram_generator.py:524-539 \u2014 both copies are in the same file, so extract the block 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 \u0060engineering-team/skills/senior-architect/scripts/architecture_diagram_generator.py:405\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":"engineering-team/skills/senior-architect/scripts/architecture_diagram_generator.py"},"region":{"startLine":405}}}],"partialFingerprints":{"codehealthFindingId/v1":"8af7b18b9364b39070f7163814b4cf2507a9fbc47337c2d171c39dabfc934129"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (16 lines \u00D7 2): engineering/agenthub/skills/agenthub/scripts/board_manager.py:222-237 | engineering/agenthub/skills/agenthub/scripts/session_manager.py:264-279 \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 \u0060engineering/agenthub/skills/agenthub/scripts/board_manager.py:222\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":"engineering/agenthub/skills/agenthub/scripts/board_manager.py"},"region":{"startLine":222}}}],"partialFingerprints":{"codehealthFindingId/v1":"83c059d7edd5756d7bf2d597efc522183508ce94a2ba9cd01b36c9539ec18aa8"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (16 lines \u00D7 2): engineering/chaos-engineering/skills/chaos-engineering/scripts/blast_radius_calculator.py:53-68 | engineering/skills/chaos-engineering/scripts/blast_radius_calculator.py:53-68 \u2014 before extracting anything, compare \u0060engineering/chaos-engineering/skills/chaos-engineering/scripts/blast_radius_calculator.py\u0060 and \u0060engineering/skills/chaos-engineering/scripts/blast_radius_calculator.py\u0060 as WHOLE FILES: this scan already matched 3 separate duplicated blocks between them, totalling at least 85 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/chaos-engineering/skills/chaos-engineering/scripts/blast_radius_calculator.py"},"region":{"startLine":53}}}],"partialFingerprints":{"codehealthFindingId/v1":"4b4c25b13eff9e4c765d8cffb901f66cb24335504647df2e8c8804bc7f49860e"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (16 lines \u00D7 2): engineering/chaos-engineering/skills/chaos-engineering/scripts/experiment_postmortem.py:125-140 | engineering/skills/chaos-engineering/scripts/experiment_postmortem.py:125-140 \u2014 before extracting anything, compare \u0060engineering/chaos-engineering/skills/chaos-engineering/scripts/experiment_postmortem.py\u0060 and \u0060engineering/skills/chaos-engineering/scripts/experiment_postmortem.py\u0060 as WHOLE FILES: this scan already matched 4 separate duplicated blocks between them, totalling at least 63 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/chaos-engineering/skills/chaos-engineering/scripts/experiment_postmortem.py"},"region":{"startLine":125}}}],"partialFingerprints":{"codehealthFindingId/v1":"21cd0dc17aa8aec94b033ea2137a4c6c84a6ffba28fbee48a6e66fa4bbf1f04c"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (16 lines \u00D7 2): engineering/feature-flags-architect/skills/feature-flags-architect/scripts/kill_switch_audit.py:49-64 | engineering/skills/feature-flags-architect/scripts/kill_switch_audit.py:49-64 \u2014 before extracting anything, compare \u0060engineering/feature-flags-architect/skills/feature-flags-architect/scripts/kill_switch_audit.py\u0060 and \u0060engineering/skills/feature-flags-architect/scripts/kill_switch_audit.py\u0060 as WHOLE FILES: this scan already matched 6 separate duplicated blocks between them, totalling at least 94 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The \u0060return\u0060 at the foot of the matched lines is the enclosing body\u0027s own terminal exit, not an early one: it moves with them unchanged, and each site calls the extracted unit from the position that \u0060return\u0060 occupied \u2014 no decision has to be handed back and re-acted on."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/feature-flags-architect/skills/feature-flags-architect/scripts/kill_switch_audit.py"},"region":{"startLine":49}}}],"partialFingerprints":{"codehealthFindingId/v1":"efe81553340e3cbbb78daca69eadc6975b1f8ad0bf92f3eb9b51cb81f19f7ac0"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (16 lines \u00D7 2): engineering/skill-doctor/skills/skill-doctor/scripts/collect_sessions.py:673-688 | engineering/skill-doctor/skills/skill-doctor/scripts/collect_sessions.py:699-714 \u2014 both copies are in the same file, so extract the block 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":"engineering/skill-doctor/skills/skill-doctor/scripts/collect_sessions.py"},"region":{"startLine":673}}}],"partialFingerprints":{"codehealthFindingId/v1":"67aa90d1cfb23691cae5024902e8a20895f39358533586a80a965d9bc21a94f7"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (14\u201316 lines \u00D7 2): engineering/skills/browser-automation/scripts/anti_detection_checker.py:247-262 | engineering/skills/browser-automation/scripts/anti_detection_checker.py:282-295 \u2014 both copies are in the same file, so extract the block 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 \u0060engineering/skills/browser-automation/scripts/anti_detection_checker.py:247\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":"engineering/skills/browser-automation/scripts/anti_detection_checker.py"},"region":{"startLine":247}}}],"partialFingerprints":{"codehealthFindingId/v1":"28d063e7cb3905f7e38431e77b04911828864a757c18996c1f3484ac9cc3afdf"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (16 lines \u00D7 2): finance/skills/stock-analysis/scripts/valuation.py:847-862 | finance/skills/stock-analysis/scripts/verify_data.py:1615-1630 \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":"finance/skills/stock-analysis/scripts/valuation.py"},"region":{"startLine":847}}}],"partialFingerprints":{"codehealthFindingId/v1":"7e350bd02d049fd9a93bdfc0f16f0d6891cfce371a8ae8114690a7bd224f7edc"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (16 lines \u00D7 2): productivity/reflect/skills/reflect/scripts/bias_pattern_detector.py:174-189 | productivity/reflect/skills/reflect/scripts/conversation_depth_analyzer.py:173-188 \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":"productivity/reflect/skills/reflect/scripts/bias_pattern_detector.py"},"region":{"startLine":174}}}],"partialFingerprints":{"codehealthFindingId/v1":"5050623a7b32aa886cb8848c12383fa0b5d2d98955345b26eefef45041af657c"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (16 lines \u00D7 2): ra-qm-team/compliance-team-eu-ai-act/skills/eu-ai-act-specialist/scripts/ai_act_obligation_tracker.py:144-159 | ra-qm-team/skills/eu-ai-act-specialist/scripts/ai_act_obligation_tracker.py:144-159 \u2014 before extracting anything, compare \u0060ra-qm-team/compliance-team-eu-ai-act/skills/eu-ai-act-specialist/scripts/ai_act_obligation_tracker.py\u0060 and \u0060ra-qm-team/skills/eu-ai-act-specialist/scripts/ai_act_obligation_tracker.py\u0060 as WHOLE FILES: this scan already matched 11 separate duplicated blocks between them, totalling at least 122 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"ra-qm-team/compliance-team-eu-ai-act/skills/eu-ai-act-specialist/scripts/ai_act_obligation_tracker.py"},"region":{"startLine":144}}}],"partialFingerprints":{"codehealthFindingId/v1":"14dc531e68d3418cfcd42b56bd2ec078159a996d6ab185e4ed21006bce4bf65a"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (16 lines \u00D7 2): ra-qm-team/compliance-team-iso42001/skills/iso42001-specialist/scripts/ai_risk_register_builder.py:205-220 | ra-qm-team/skills/iso42001-specialist/scripts/ai_risk_register_builder.py:205-220 \u2014 before extracting anything, compare \u0060ra-qm-team/compliance-team-iso42001/skills/iso42001-specialist/scripts/ai_risk_register_builder.py\u0060 and \u0060ra-qm-team/skills/iso42001-specialist/scripts/ai_risk_register_builder.py\u0060 as WHOLE FILES: this scan already matched 12 separate duplicated blocks between them, totalling at least 132 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The \u0060return\u0060 at the foot of the matched lines is the enclosing body\u0027s own terminal exit, not an early one: it moves with them unchanged, and each site calls the extracted unit from the position that \u0060return\u0060 occupied \u2014 no decision has to be handed back and re-acted on."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"ra-qm-team/compliance-team-iso42001/skills/iso42001-specialist/scripts/ai_risk_register_builder.py"},"region":{"startLine":205}}}],"partialFingerprints":{"codehealthFindingId/v1":"104ff2dbbb0c930f6a4c3dc1f93ffe59a2ea455a0c0bc046dba20230b4f187e2"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (16 lines \u00D7 2): scripts/sync-hermes-skills.py:132-147 | scripts/sync-vibe-skills.py:145-160 \u2014 before extracting anything, compare \u0060scripts/sync-hermes-skills.py\u0060 and \u0060scripts/sync-vibe-skills.py\u0060 as WHOLE FILES: this scan already matched 6 separate duplicated blocks between them, totalling at least 165 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":"scripts/sync-hermes-skills.py"},"region":{"startLine":132}}}],"partialFingerprints":{"codehealthFindingId/v1":"595e7e17ce91625fd6af98edeab61bb859d4ed9a7148c82109110571dddcd9a5"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (15 lines \u00D7 5): project-management/skills/scrum-master/scripts/retrospective_analyzer.py:768-782 | project-management/skills/scrum-master/scripts/velocity_analyzer.py:438-452 | project-management/skills/senior-pm/scripts/project_health_dashboard.py:636-650 | project-management/skills/senior-pm/scripts/resource_capacity_planner.py:647-661 | project-management/skills/senior-pm/scripts/risk_matrix_analyzer.py:517-531 \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 \u0060result\u0060 to \u0060RetroAnalysisResult\u0060 in one and \u0060PortfolioHealthResult\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. \u2605 These copies have DRIFTED, and that is worth reading before extracting anything: just after the matched lines, \u0060project-management/skills/scrum-master/scripts/velocity_analyzer.py:455\u0060 calls \u0060get\u0060 and \u0060project-management/skills/scrum-master/scripts/retrospective_analyzer.py:784\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":"project-management/skills/scrum-master/scripts/retrospective_analyzer.py"},"region":{"startLine":768}}}],"partialFingerprints":{"codehealthFindingId/v1":"4a6ea3b42e561a3be5438a8158ca4e737fb5a4d71a8981671b3ac3c17e7454cb"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (15 lines \u00D7 4): c-level-advisor/chief-ai-officer-advisor/skills/chief-ai-officer-advisor/scripts/ai_cost_economics.py:262-276 | c-level-advisor/chief-ai-officer-advisor/skills/chief-ai-officer-advisor/scripts/model_buildvsbuy_calculator.py:284-298 | c-level-advisor/skills/chief-ai-officer-advisor/scripts/ai_cost_economics.py:262-276 | c-level-advisor/skills/chief-ai-officer-advisor/scripts/model_buildvsbuy_calculator.py:284-298 \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."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"c-level-advisor/chief-ai-officer-advisor/skills/chief-ai-officer-advisor/scripts/ai_cost_economics.py"},"region":{"startLine":262}}}],"partialFingerprints":{"codehealthFindingId/v1":"b03effffaa6fd01403c325636c3ac149847c90018cd35756e27d2ed847fcfe38"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (15 lines \u00D7 4): engineering-team/skills/senior-secops/scripts/compliance_checker.py:250-264 | engineering-team/skills/senior-secops/scripts/compliance_checker.py:367-381 | engineering-team/skills/senior-secops/scripts/compliance_checker.py:648-662 | engineering-team/skills/senior-secops/scripts/compliance_checker.py:869-883 \u2014 all 4 copies are in the same file, so extract the block into one function there and call it from every one of those sites \u2014 resolving only two of them leaves the rest to drift apart the first time one is edited. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/skills/senior-secops/scripts/compliance_checker.py"},"region":{"startLine":250}}}],"partialFingerprints":{"codehealthFindingId/v1":"c8737eb1e08879f6d8dad160f497291c3199586b5a2b805ecf59a2eac80651e0"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (14\u201315 lines \u00D7 3): engineering-team/skills/senior-architect/scripts/dependency_analyzer.py:558-571 | engineering-team/skills/senior-architect/scripts/project_architect.py:684-697 | ra-qm-team/skills/gdpr-dsgvo-expert/scripts/gdpr_compliance_checker.py:408-422 \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. Read the line range as the matched WINDOW rather than a finished unit: at \u0060engineering-team/skills/senior-architect/scripts/dependency_analyzer.py:558\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":"engineering-team/skills/senior-architect/scripts/dependency_analyzer.py"},"region":{"startLine":558}}}],"partialFingerprints":{"codehealthFindingId/v1":"b7d35ad53d7ca441d3f7823bef6036b18bfcad78f922659e00374f74e367cc39"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (14\u201315 lines \u00D7 3): engineering-team/skills/senior-backend/scripts/backend_decision_engine.py:337-350 | engineering-team/skills/senior-frontend/scripts/frontend_decision_engine.py:272-285 | engineering-team/skills/senior-fullstack/scripts/fullstack_decision_engine.py:338-352 \u2014 before extracting anything, compare \u0060engineering-team/skills/senior-backend/scripts/backend_decision_engine.py\u0060 and \u0060engineering-team/skills/senior-frontend/scripts/frontend_decision_engine.py\u0060 as WHOLE FILES: this scan already matched 6 separate duplicated blocks between them, totalling at least 99 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. Read the line range as the matched WINDOW rather than a finished unit: at \u0060engineering-team/skills/senior-backend/scripts/backend_decision_engine.py:337\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":"engineering-team/skills/senior-backend/scripts/backend_decision_engine.py"},"region":{"startLine":337}}}],"partialFingerprints":{"codehealthFindingId/v1":"5046b429f3b019df43c27f9adaf7b5b2c72c56a2591fd9d7cf0bfb43268d31d6"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (15 lines \u00D7 3): engineering/skills/dependency-auditor/scripts/dep_scanner.py:482-496 | engineering/skills/dependency-auditor/scripts/dep_scanner.py:568-582 | engineering/skills/dependency-auditor/scripts/dep_scanner.py:624-638 \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 \u0060engineering/skills/dependency-auditor/scripts/dep_scanner.py:482\u0060 it begins part-way through the construct above it, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that. The \u0060return\u0060 at the foot of the matched lines is the enclosing body\u0027s own terminal exit, not an early one: it moves with them unchanged, and each site calls the extracted unit from the position that \u0060return\u0060 occupied \u2014 no decision has to be handed back and re-acted on."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/dependency-auditor/scripts/dep_scanner.py"},"region":{"startLine":482}}}],"partialFingerprints":{"codehealthFindingId/v1":"69b802d8353487f59d10bd9763982a10b600cfc623e29e15f3668fef4b7f04a4"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (15 lines \u00D7 2): business-operations/skills/knowledge-ops/scripts/kb_ingester.py:315-329 | business-operations/skills/knowledge-ops/scripts/kb_ingester.py:351-365 \u2014 both copies are in the same file, so extract the block 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 \u0060business-operations/skills/knowledge-ops/scripts/kb_ingester.py:315\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":"business-operations/skills/knowledge-ops/scripts/kb_ingester.py"},"region":{"startLine":315}}}],"partialFingerprints":{"codehealthFindingId/v1":"32bc30fb109ee5009639d67f38c735b005508bbcb739fbbbda69db6dbd014fac"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (15 lines \u00D7 2): c-level-advisor/chief-ai-officer-advisor/skills/chief-ai-officer-advisor/scripts/ai_risk_classifier.py:420-434 | c-level-advisor/skills/chief-ai-officer-advisor/scripts/ai_risk_classifier.py:420-434 \u2014 before extracting anything, compare \u0060c-level-advisor/chief-ai-officer-advisor/skills/chief-ai-officer-advisor/scripts/ai_risk_classifier.py\u0060 and \u0060c-level-advisor/skills/chief-ai-officer-advisor/scripts/ai_risk_classifier.py\u0060 as WHOLE FILES: this scan already matched 11 separate duplicated blocks between them, totalling at least 356 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The \u0060return\u0060 at the foot of the matched lines is the enclosing body\u0027s own terminal exit, not an early one: it moves with them unchanged, and each site calls the extracted unit from the position that \u0060return\u0060 occupied \u2014 no decision has to be handed back and re-acted on."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"c-level-advisor/chief-ai-officer-advisor/skills/chief-ai-officer-advisor/scripts/ai_risk_classifier.py"},"region":{"startLine":420}}}],"partialFingerprints":{"codehealthFindingId/v1":"d13676a5399509a57b5e0e30b71958ef459d7f844fc266cb18ef69c9700f4cc1"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (15 lines \u00D7 2): c-level-advisor/chief-data-officer-advisor/skills/chief-data-officer-advisor/scripts/data_asset_valuator.py:315-329 | c-level-advisor/skills/chief-data-officer-advisor/scripts/data_asset_valuator.py:315-329 \u2014 before extracting anything, compare \u0060c-level-advisor/chief-data-officer-advisor/skills/chief-data-officer-advisor/scripts/data_asset_valuator.py\u0060 and \u0060c-level-advisor/skills/chief-data-officer-advisor/scripts/data_asset_valuator.py\u0060 as WHOLE FILES: this scan already matched 12 separate duplicated blocks between them, totalling at least 283 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The \u0060return\u0060 at the foot of the matched lines is the enclosing body\u0027s own terminal exit, not an early one: it moves with them unchanged, and each site calls the extracted unit from the position that \u0060return\u0060 occupied \u2014 no decision has to be handed back and re-acted on."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"c-level-advisor/chief-data-officer-advisor/skills/chief-data-officer-advisor/scripts/data_asset_valuator.py"},"region":{"startLine":315}}}],"partialFingerprints":{"codehealthFindingId/v1":"6d8a8e122f6a11ffdb3af00a24edec11b0a4aa924655f31360804a2448645091"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (15 lines \u00D7 2): c-level-advisor/skills/cro-advisor/scripts/churn_analyzer.py:685-699 | c-level-advisor/skills/cro-advisor/scripts/revenue_forecast_model.py:523-537 \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 \u0060c-level-advisor/skills/cro-advisor/scripts/churn_analyzer.py:685\u0060 it begins part-way through the construct above it, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"c-level-advisor/skills/cro-advisor/scripts/churn_analyzer.py"},"region":{"startLine":685}}}],"partialFingerprints":{"codehealthFindingId/v1":"90ca5e45f8d5ec3ddcb5648a90414d3020711e09261d464c60bc7dd5b31a9d22"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (15 lines \u00D7 2): engineering-team/skills/senior-architect/scripts/dependency_analyzer.py:173-187 | engineering-team/skills/senior-architect/scripts/dependency_analyzer.py:258-272 \u2014 both copies are in the same file, so extract the block 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":"engineering-team/skills/senior-architect/scripts/dependency_analyzer.py"},"region":{"startLine":173}}}],"partialFingerprints":{"codehealthFindingId/v1":"8896e97d24190f6261da0f59eff8b8d4dbc7650664497dc3f5dac49cff0d653a"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (15 lines \u00D7 2): engineering-team/skills/senior-architect/scripts/dependency_analyzer.py:597-611 | engineering-team/skills/senior-architect/scripts/project_architect.py:731-745 \u2014 the copies sit in sibling files of one directory, so a shared home is within easy reach: extract the block into a single shared function the call sites can all reach \u2014 a file they already depend on, or a new one alongside them \u2014 and call it from both call sites, so a change lands once."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/skills/senior-architect/scripts/dependency_analyzer.py"},"region":{"startLine":597}}}],"partialFingerprints":{"codehealthFindingId/v1":"c41008481571e0a4d9ce462af1a585473f1942ca6d5e06dee5c6df4178fcc619"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (15 lines \u00D7 2): engineering/agenthub/skills/agenthub/scripts/hub_init.py:145-159 | engineering/agenthub/skills/agenthub/scripts/session_manager.py:231-245 \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":"engineering/agenthub/skills/agenthub/scripts/hub_init.py"},"region":{"startLine":145}}}],"partialFingerprints":{"codehealthFindingId/v1":"6be39ec4ab33192d829c690a37e91a8c4bd34a8dd4516698503a5e974d1e569c"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (15 lines \u00D7 2): engineering/caveman/skills/caveman/scripts/caveman_compressor.py:215-229 | engineering/caveman/skills/caveman/scripts/caveman_lint.py:160-174 \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":"engineering/caveman/skills/caveman/scripts/caveman_compressor.py"},"region":{"startLine":215}}}],"partialFingerprints":{"codehealthFindingId/v1":"de9d88b406e667fca4df7741985da168cfebfc9d6eb8564a6f138207ed2ac7d2"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (15 lines \u00D7 2): engineering/feature-flags-architect/skills/feature-flags-architect/scripts/flag_debt_scanner.py:122-136 | engineering/skills/feature-flags-architect/scripts/flag_debt_scanner.py:122-136 \u2014 before extracting anything, compare \u0060engineering/feature-flags-architect/skills/feature-flags-architect/scripts/flag_debt_scanner.py\u0060 and \u0060engineering/skills/feature-flags-architect/scripts/flag_debt_scanner.py\u0060 as WHOLE FILES: this scan already matched 7 separate duplicated blocks between them, totalling at least 77 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The \u0060return\u0060 at the foot of the matched lines is the enclosing body\u0027s own terminal exit, not an early one: it moves with them unchanged, and each site calls the extracted unit from the position that \u0060return\u0060 occupied \u2014 no decision has to be handed back and re-acted on."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/feature-flags-architect/skills/feature-flags-architect/scripts/flag_debt_scanner.py"},"region":{"startLine":122}}}],"partialFingerprints":{"codehealthFindingId/v1":"642ae5f0273399eddbd64010832c097817b9886662ba29d65284069cb4edf694"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (15 lines \u00D7 2): engineering/grill-me/skills/grill-me/scripts/decision_tree_extractor.py:131-145 | engineering/grill-me/skills/grill-me/scripts/question_generator.py:124-138 \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":"engineering/grill-me/skills/grill-me/scripts/decision_tree_extractor.py"},"region":{"startLine":131}}}],"partialFingerprints":{"codehealthFindingId/v1":"5b54bca400ce4663d337acb8d0c7c30a6c0df2103acb3452b8a280517edf8b38"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (15 lines \u00D7 2): engineering/kubernetes-operator/skills/kubernetes-operator/scripts/operator_capability_audit.py:115-129 | engineering/skills/kubernetes-operator/scripts/operator_capability_audit.py:115-129 \u2014 before extracting anything, compare \u0060engineering/kubernetes-operator/skills/kubernetes-operator/scripts/operator_capability_audit.py\u0060 and \u0060engineering/skills/kubernetes-operator/scripts/operator_capability_audit.py\u0060 as WHOLE FILES: this scan already matched 5 separate duplicated blocks between them, totalling at least 75 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/kubernetes-operator/skills/kubernetes-operator/scripts/operator_capability_audit.py"},"region":{"startLine":115}}}],"partialFingerprints":{"codehealthFindingId/v1":"dd542aa510ca37fa334deba7464b505f6e5af4738a0d1ee4684de0d1630d02b2"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (13\u201315 lines \u00D7 2): engineering/skills/agent-designer/agent_evaluator.py:1147-1161 | engineering/skills/agent-designer/tool_schema_generator.py:904-916 \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":"engineering/skills/agent-designer/agent_evaluator.py"},"region":{"startLine":1147}}}],"partialFingerprints":{"codehealthFindingId/v1":"dba8ab84337e06660a591dba041d0b70363ecdba97f322a0824129eb0eebaac4"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (15 lines \u00D7 2): engineering/skills/dependency-auditor/scripts/dep_scanner.py:511-525 | engineering/skills/dependency-auditor/scripts/dep_scanner.py:543-557 \u2014 both copies are in the same file, so extract the block 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 \u0060engineering/skills/dependency-auditor/scripts/dep_scanner.py:543\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":"engineering/skills/dependency-auditor/scripts/dep_scanner.py"},"region":{"startLine":511}}}],"partialFingerprints":{"codehealthFindingId/v1":"391b81c24669b893ca2659756049f8885b7e453cbd6ea5be24a73c274911e19b"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (15 lines \u00D7 2): engineering/universal-scraping-architect/skills/universal-scraping-architect/scripts/firecrawl_example.py:73-87 | engineering/universal-scraping-architect/skills/universal-scraping-architect/scripts/local_bs4_example.py:72-86 \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":"engineering/universal-scraping-architect/skills/universal-scraping-architect/scripts/firecrawl_example.py"},"region":{"startLine":73}}}],"partialFingerprints":{"codehealthFindingId/v1":"55f51065d2cdb0914e3047c7eee30c620b4a1b0a6fd404ee227bf724cb638d0f"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (15 lines \u00D7 2): marketing-skill/skills/app-store-optimization/scripts/aso_scorer.py:179-194 | marketing-skill/skills/app-store-optimization/scripts/aso_scorer.py:280-294 \u2014 both copies are in the same file, so extract the block 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":"marketing-skill/skills/app-store-optimization/scripts/aso_scorer.py"},"region":{"startLine":179}}}],"partialFingerprints":{"codehealthFindingId/v1":"cbb7d7695d0cbe7fdf587a2ebda1a938c9533cba2872acf74607b2b8e398b315"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (4\u201315 lines \u00D7 4): marketing-skill/skills/app-store-optimization/scripts/aso_scorer.py:210-224 | marketing-skill/skills/app-store-optimization/scripts/aso_scorer.py:249-252 | marketing-skill/skills/app-store-optimization/scripts/aso_scorer.py:259-262 | marketing-skill/skills/app-store-optimization/scripts/aso_scorer.py:296-309 \u2014 all 4 copies are in the same file, so extract the block into one function there and call it from every one of those sites \u2014 resolving only two of them leaves the rest to drift apart the first time one is edited. Note that the copies do not run to the end of the range shown: their LAST lines are different code, not the same code under different names \u2014 the matched region ends inside that line. Extract the lines above it, and read the last line of each site separately."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"marketing-skill/skills/app-store-optimization/scripts/aso_scorer.py"},"region":{"startLine":210}}}],"partialFingerprints":{"codehealthFindingId/v1":"229808d8c41004a1f871512e78cbe0a137bf7e0c026a6e31d67bc0dae51139c9"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (14\u201315 lines \u00D7 2): marketing-skill/skills/app-store-optimization/scripts/launch_checklist.py:447-461 | marketing-skill/skills/app-store-optimization/scripts/launch_checklist.py:476-489 \u2014 both copies are in the same file, so extract the block into one function there and call it from each site \u2014 the copies drift apart the first time only one of them is edited."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"marketing-skill/skills/app-store-optimization/scripts/launch_checklist.py"},"region":{"startLine":447}}}],"partialFingerprints":{"codehealthFindingId/v1":"12d1b50d94a0f3bde3ee6272449a49d67010d24e94df18b5cc171fd42295f4bb"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (15 lines \u00D7 2): product-team/research-summarizer/skills/research-summarizer/scripts/extract_citations.py:273-287 | product-team/research-summarizer/skills/research-summarizer/scripts/format_summary.py:214-228 \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 \u0060product-team/research-summarizer/skills/research-summarizer/scripts/extract_citations.py:273\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":"product-team/research-summarizer/skills/research-summarizer/scripts/extract_citations.py"},"region":{"startLine":273}}}],"partialFingerprints":{"codehealthFindingId/v1":"bc150223d8f4fbc91053c2774e6aaac2efa3833a7566b3f45957560f48cbad39"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (14\u201315 lines \u00D7 2): ra-qm-team/skills/capa-officer/scripts/capa_tracker.py:389-403 | ra-qm-team/skills/qms-audit-expert/scripts/audit_schedule_optimizer.py:305-318 \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":"ra-qm-team/skills/capa-officer/scripts/capa_tracker.py"},"region":{"startLine":389}}}],"partialFingerprints":{"codehealthFindingId/v1":"67a9d08690432cd413dbaaa1523fcd52b954d32bc4d3b9cdbf49194d1e3d79e6"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (15 lines \u00D7 2): research/dossier/skills/dossier/scripts/citation_tracker.py:233-247 | research/grants/skills/grants/scripts/citation_tracker.py:243-257 \u2014 the copies span different directories, so extracting a shared function means choosing where it lives: put it somewhere both call sites can already reach \u2014 a location they all depend on today, or a new shared one if there is none \u2014 and call it from each site; until then, every change has to be made twice. \u2605 These copies have DRIFTED, and that is worth reading before extracting anything: just after the matched lines, \u0060research/grants/skills/grants/scripts/citation_tracker.py:259\u0060 calls \u0060add_argument\u0060 and \u0060research/dossier/skills/dossier/scripts/citation_tracker.py:249\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":"research/dossier/skills/dossier/scripts/citation_tracker.py"},"region":{"startLine":233}}}],"partialFingerprints":{"codehealthFindingId/v1":"df7b542eeace232a3f958ec28cd489b0feaa3aea3d336dd47c1ae8bbf43dd01f"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (15 lines \u00D7 2): scripts/sync-hermes-skills.py:206-220 | scripts/sync-vibe-skills.py:247-261 \u2014 before extracting anything, compare \u0060scripts/sync-hermes-skills.py\u0060 and \u0060scripts/sync-vibe-skills.py\u0060 as WHOLE FILES: this scan already matched 6 separate duplicated blocks between them, totalling at least 165 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 \u0060scripts/sync-hermes-skills.py:206\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":"scripts/sync-hermes-skills.py"},"region":{"startLine":206}}}],"partialFingerprints":{"codehealthFindingId/v1":"658e5b9120b8961dba63cb0831eea107e97b6a368236dda89b70335bbc69b48e"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (14 lines \u00D7 4): finance/skills/financial-analyst/scripts/budget_variance_analyzer.py:394-407 | finance/skills/financial-analyst/scripts/dcf_valuation.py:421-434 | finance/skills/financial-analyst/scripts/forecast_builder.py:485-498 | finance/skills/financial-analyst/scripts/ratio_calculator.py:414-427 \u2014 the copies sit in sibling files of one directory, so a shared home is within easy reach: extract the block into a single shared function the call sites can all reach \u2014 a file they already depend on, or a new one alongside them \u2014 and call it from all 4 call sites, so a change lands once. Read the line range as the matched WINDOW rather than a finished unit: at \u0060finance/skills/financial-analyst/scripts/budget_variance_analyzer.py:394\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":"finance/skills/financial-analyst/scripts/budget_variance_analyzer.py"},"region":{"startLine":394}}}],"partialFingerprints":{"codehealthFindingId/v1":"4d9343161cf728493d346b39223188a6294f38618bb92718e6e7e33b462ba1cf"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (11\u201314 lines \u00D7 3): commercial/skills/pricing-strategist/scripts/wtp_analyzer.py:193-203 | engineering-team/skills/senior-architect/scripts/architecture_diagram_generator.py:409-421 | engineering-team/skills/senior-architect/scripts/architecture_diagram_generator.py:528-541 \u2014 there are 3 copies across 2 file(s) \u2014 more copies than files, so at least one file holds the block twice. Extract it once into a single shared function every call site can reach and call it from all 3 sites; resolving a subset leaves the remainder to drift apart. Read the line range as the matched WINDOW rather than a finished unit: at \u0060engineering-team/skills/senior-architect/scripts/architecture_diagram_generator.py:409\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":"commercial/skills/pricing-strategist/scripts/wtp_analyzer.py"},"region":{"startLine":193}}}],"partialFingerprints":{"codehealthFindingId/v1":"c464a97640307386bc0e1f3535d67e34e9d691347341a7125631d522f0829153"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (14 lines \u00D7 3): engineering-team/skills/senior-data-engineer/scripts/data_quality_validator.py:1373-1386 | engineering-team/skills/senior-data-engineer/scripts/data_quality_validator.py:1473-1486 | engineering-team/skills/senior-data-engineer/scripts/etl_performance_optimizer.py:1362-1375 \u2014 there are 3 copies across 2 file(s) \u2014 more copies than files, so at least one file holds the block twice. Extract it once into a single shared function every call site can reach and call it from all 3 sites; resolving a subset leaves the remainder to drift apart."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/skills/senior-data-engineer/scripts/data_quality_validator.py"},"region":{"startLine":1373}}}],"partialFingerprints":{"codehealthFindingId/v1":"045f29d7ac5535ab9e2a81cff8b657d103c359365e152f567c01d57fb7ba57a6"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (14 lines \u00D7 2): c-level-advisor/arquiteto-de-empresa/skills/arquiteto-de-empresa/scripts/scaffold_bundle.py:142-155 | c-level-advisor/skills/arquiteto-de-empresa/scripts/scaffold_bundle.py:142-155 \u2014 before extracting anything, compare \u0060c-level-advisor/arquiteto-de-empresa/skills/arquiteto-de-empresa/scripts/scaffold_bundle.py\u0060 and \u0060c-level-advisor/skills/arquiteto-de-empresa/scripts/scaffold_bundle.py\u0060 as WHOLE FILES: this scan already matched 7 separate duplicated blocks between them, totalling at least 108 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"c-level-advisor/arquiteto-de-empresa/skills/arquiteto-de-empresa/scripts/scaffold_bundle.py"},"region":{"startLine":142}}}],"partialFingerprints":{"codehealthFindingId/v1":"d6bf2f6b19f668b447d96f377b4e63b92257a443c0b384b6c3d644027ca22ee0"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (14 lines \u00D7 2): c-level-advisor/chief-ai-officer-advisor/skills/chief-ai-officer-advisor/scripts/model_buildvsbuy_calculator.py:80-93 | c-level-advisor/skills/chief-ai-officer-advisor/scripts/model_buildvsbuy_calculator.py:80-93 \u2014 before extracting anything, compare \u0060c-level-advisor/chief-ai-officer-advisor/skills/chief-ai-officer-advisor/scripts/model_buildvsbuy_calculator.py\u0060 and \u0060c-level-advisor/skills/chief-ai-officer-advisor/scripts/model_buildvsbuy_calculator.py\u0060 as WHOLE FILES: this scan already matched 12 separate duplicated blocks between them, totalling at least 251 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The \u0060return\u0060 at the foot of the matched lines is the enclosing body\u0027s own terminal exit, not an early one: it moves with them unchanged, and each site calls the extracted unit from the position that \u0060return\u0060 occupied \u2014 no decision has to be handed back and re-acted on."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"c-level-advisor/chief-ai-officer-advisor/skills/chief-ai-officer-advisor/scripts/model_buildvsbuy_calculator.py"},"region":{"startLine":80}}}],"partialFingerprints":{"codehealthFindingId/v1":"6536fb5a615bcb03f69b1aba3e7bb1f10889c334f68554a6df7c9a24633b3157"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (12\u201314 lines \u00D7 2): commercial/skills/commercial-forecaster/scripts/bookings_forecaster.py:406-417 | commercial/skills/pricing-strategist/scripts/pricing_model_picker.py:260-273 \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":"commercial/skills/commercial-forecaster/scripts/bookings_forecaster.py"},"region":{"startLine":406}}}],"partialFingerprints":{"codehealthFindingId/v1":"1b04a95e229003d54a858610698f170d35082774cbdcd9bdf000b91e226daf37"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (13\u201314 lines \u00D7 2): engineering-team/skills/senior-architect/scripts/dependency_analyzer.py:158-171 | engineering-team/skills/senior-architect/scripts/dependency_analyzer.py:245-257 \u2014 both copies are in the same file, so extract the block 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 \u0060engineering-team/skills/senior-architect/scripts/dependency_analyzer.py:158\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":"engineering-team/skills/senior-architect/scripts/dependency_analyzer.py"},"region":{"startLine":158}}}],"partialFingerprints":{"codehealthFindingId/v1":"af75663941eaf448c5724b3b71947acae5645303fd2c2a3c26422225a0cd5304"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (14 lines \u00D7 2): engineering-team/skills/senior-secops/scripts/security_scanner.py:155-168 | engineering-team/skills/senior-secops/scripts/vulnerability_assessor.py:157-170 \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":"engineering-team/skills/senior-secops/scripts/security_scanner.py"},"region":{"startLine":155}}}],"partialFingerprints":{"codehealthFindingId/v1":"ccad4fd5584301b1541a4e54ec90eec5fbcba5f781e8d6238f553ece68bdb403"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (14 lines \u00D7 2): engineering/data-quality-auditor/skills/data-quality-auditor/scripts/data_profiler.py:233-246 | engineering/data-quality-auditor/skills/data-quality-auditor/scripts/outlier_detector.py:235-248 \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":"engineering/data-quality-auditor/skills/data-quality-auditor/scripts/data_profiler.py"},"region":{"startLine":233}}}],"partialFingerprints":{"codehealthFindingId/v1":"804c8f3996a833bfcb753292b8b50a40302e9b2adfdce67be1b0e83d1e9f25b3"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (14 lines \u00D7 2): engineering/feature-flags-architect/skills/feature-flags-architect/scripts/flag_debt_scanner.py:48-61 | engineering/skills/feature-flags-architect/scripts/flag_debt_scanner.py:48-61 \u2014 before extracting anything, compare \u0060engineering/feature-flags-architect/skills/feature-flags-architect/scripts/flag_debt_scanner.py\u0060 and \u0060engineering/skills/feature-flags-architect/scripts/flag_debt_scanner.py\u0060 as WHOLE FILES: this scan already matched 7 separate duplicated blocks between them, totalling at least 77 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/feature-flags-architect/skills/feature-flags-architect/scripts/flag_debt_scanner.py"},"region":{"startLine":48}}}],"partialFingerprints":{"codehealthFindingId/v1":"3cdd3b9c9c4ab2b940a28e30c596e5a354dd46986a8e7b98743f66ad82dc1294"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (14 lines \u00D7 2): engineering/feature-flags-architect/skills/feature-flags-architect/scripts/kill_switch_audit.py:129-142 | engineering/skills/feature-flags-architect/scripts/kill_switch_audit.py:129-142 \u2014 before extracting anything, compare \u0060engineering/feature-flags-architect/skills/feature-flags-architect/scripts/kill_switch_audit.py\u0060 and \u0060engineering/skills/feature-flags-architect/scripts/kill_switch_audit.py\u0060 as WHOLE FILES: this scan already matched 6 separate duplicated blocks between them, totalling at least 94 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/feature-flags-architect/skills/feature-flags-architect/scripts/kill_switch_audit.py"},"region":{"startLine":129}}}],"partialFingerprints":{"codehealthFindingId/v1":"9d2bd4023ddf74d51c29b8f48edb3a03a26840b6d061e133f4d4b2e8f8635ccd"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (14 lines \u00D7 2): engineering/skills/api-design-reviewer/scripts/breaking_change_detector.py:143-156 | engineering/skills/api-design-reviewer/scripts/breaking_change_detector.py:159-172 \u2014 both copies are in the same file, so extract the block 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":"engineering/skills/api-design-reviewer/scripts/breaking_change_detector.py"},"region":{"startLine":143}}}],"partialFingerprints":{"codehealthFindingId/v1":"311b8b2269043e8db17c98aaa50098fce4b64664dbdaa92d13f1320f130ce646"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (14 lines \u00D7 2): engineering/skills/dependency-auditor/scripts/dep_scanner.py:420-433 | engineering/skills/dependency-auditor/scripts/dep_scanner.py:532-545 \u2014 both copies are in the same file, so extract the block 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 \u0060engineering/skills/dependency-auditor/scripts/dep_scanner.py:420\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":"engineering/skills/dependency-auditor/scripts/dep_scanner.py"},"region":{"startLine":420}}}],"partialFingerprints":{"codehealthFindingId/v1":"0edbfe89c2ee61c454fba80e24da99fd5bb8f499020394a4fcdffef8ee7f56db"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (12\u201314 lines \u00D7 2): engineering/skills/interview-system-designer/hiring_calibrator.py:284-295 | engineering/skills/interview-system-designer/hiring_calibrator.py:345-358 \u2014 both copies are in the same file, so extract the block 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":"engineering/skills/interview-system-designer/hiring_calibrator.py"},"region":{"startLine":284}}}],"partialFingerprints":{"codehealthFindingId/v1":"98301d5ceea7a9be377243bf498c6e050eb2deac9c0a01732e90d71076844c4d"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (14 lines \u00D7 2): finance/skills/stock-analysis/scripts/score.py:1371-1384 | finance/skills/stock-analysis/scripts/score.py:1531-1544 \u2014 both copies are in the same file, so extract the block 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":"finance/skills/stock-analysis/scripts/score.py"},"region":{"startLine":1371}}}],"partialFingerprints":{"codehealthFindingId/v1":"617a621053b6aa0e886e6a313b0b970ba10089987f8a6cf40aabad2073d64ad1"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (14 lines \u00D7 2): ra-qm-team/compliance-team-eu-ai-act/skills/eu-ai-act-specialist/scripts/ai_act_obligation_tracker.py:185-198 | ra-qm-team/skills/eu-ai-act-specialist/scripts/ai_act_obligation_tracker.py:185-198 \u2014 before extracting anything, compare \u0060ra-qm-team/compliance-team-eu-ai-act/skills/eu-ai-act-specialist/scripts/ai_act_obligation_tracker.py\u0060 and \u0060ra-qm-team/skills/eu-ai-act-specialist/scripts/ai_act_obligation_tracker.py\u0060 as WHOLE FILES: this scan already matched 11 separate duplicated blocks between them, totalling at least 122 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"ra-qm-team/compliance-team-eu-ai-act/skills/eu-ai-act-specialist/scripts/ai_act_obligation_tracker.py"},"region":{"startLine":185}}}],"partialFingerprints":{"codehealthFindingId/v1":"d34809c7e5d332f48f5331430dc5180edfba95811cdbfd5a6933133f59c97b80"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (12\u201314 lines \u00D7 2): scripts/smoke_json_output.py:153-164 | scripts/smoke_scripts.py:105-118 \u2014 before extracting anything, compare \u0060scripts/smoke_json_output.py\u0060 and \u0060scripts/smoke_scripts.py\u0060 as WHOLE FILES: this scan already matched 3 separate duplicated blocks between them, totalling at least 33 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 \u0060scripts/smoke_scripts.py:105\u0060 it begins part-way through the construct above it, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that. The \u0060return\u0060 at the foot of the matched lines is the enclosing body\u0027s own terminal exit, not an early one: it moves with them unchanged, and each site calls the extracted unit from the position that \u0060return\u0060 occupied \u2014 no decision has to be handed back and re-acted on."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"scripts/smoke_json_output.py"},"region":{"startLine":153}}}],"partialFingerprints":{"codehealthFindingId/v1":"e2a5ab57639210980817a17aa1b7ec09b6237e8130bfde3a70086b9c6dc3dd0e"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (12\u201313 lines \u00D7 5): engineering/skills/ci-cd-pipeline-builder/scripts/pipeline_generator.py:46-58 | engineering/skills/ci-cd-pipeline-builder/scripts/stack_detector.py:46-58 | engineering/skills/git-worktree-manager/scripts/worktree_cleanup.py:42-53 | engineering/skills/git-worktree-manager/scripts/worktree_manager.py:53-65 | marketing-skill/skills/prompt-engineer-toolkit/scripts/prompt_versioner.py:74-86 \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."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/ci-cd-pipeline-builder/scripts/pipeline_generator.py"},"region":{"startLine":46}}}],"partialFingerprints":{"codehealthFindingId/v1":"c87d2f1812df9fe8e7b57a5942f197b7e84fad13ad9e50870c25b2862611f2b6"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (12\u201313 lines \u00D7 5): markdown-html/skills/design-system/scripts/onboard.py:196-208 | research-ops/skills/clinical-research/scripts/onboard.py:109-121 | research-ops/skills/market-research/scripts/onboard.py:84-95 | research-ops/skills/product-research/scripts/onboard.py:93-104 | research-ops/skills/research-finance/scripts/onboard.py:87-98 \u2014 before extracting anything, compare \u0060research-ops/skills/market-research/scripts/onboard.py\u0060 and \u0060research-ops/skills/product-research/scripts/onboard.py\u0060 as WHOLE FILES: this scan already matched 5 separate duplicated blocks between them, totalling at least 60 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. Read the line range as the matched WINDOW rather than a finished unit: at \u0060research-ops/skills/market-research/scripts/onboard.py:84\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":"markdown-html/skills/design-system/scripts/onboard.py"},"region":{"startLine":196}}}],"partialFingerprints":{"codehealthFindingId/v1":"2dad5c238617725cd128172d54376a60ebfe1bedfdca17bea354a6cca78a86fa"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (12\u201313 lines \u00D7 4): research-ops/skills/clinical-research/scripts/ar_evaluator.py:52-64 | research-ops/skills/market-research/scripts/ar_evaluator.py:47-58 | research-ops/skills/product-research/scripts/ar_evaluator.py:48-59 | research-ops/skills/research-finance/scripts/ar_evaluator.py:49-60 \u2014 the copies span different directories, so extracting a shared function means choosing where it lives: put it somewhere all 4 call sites can already reach \u2014 a location they all depend on today, or a new shared one if there is none \u2014 and call it from each site; until then, every change has to be made 4 times. Read the line range as the matched WINDOW rather than a finished unit: at \u0060research-ops/skills/clinical-research/scripts/ar_evaluator.py:52\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":"research-ops/skills/clinical-research/scripts/ar_evaluator.py"},"region":{"startLine":52}}}],"partialFingerprints":{"codehealthFindingId/v1":"462246303d31648352809bd81b303bdd49c982511caddceded78b947406b2dfe"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (13 lines \u00D7 3): engineering-team/skills/tdd-guide/scripts/framework_adapter.py:260-272 | engineering-team/skills/tdd-guide/scripts/framework_adapter.py:290-302 | engineering-team/skills/tdd-guide/scripts/framework_adapter.py:305-317 \u2014 all 3 copies are in the same file, so extract the block into one function there and call it from every one of those sites \u2014 resolving only two of them leaves the rest to drift apart the first time one is edited. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/skills/tdd-guide/scripts/framework_adapter.py"},"region":{"startLine":260}}}],"partialFingerprints":{"codehealthFindingId/v1":"05b8794cbce896ff2103435730a99d3502b04e3f8747a4bc87ae7288bc4c1fe6"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (13 lines \u00D7 3): engineering/skills/interview-system-designer/hiring_calibrator.py:1269-1281 | engineering/skills/interview-system-designer/loop_designer.py:881-893 | engineering/skills/interview-system-designer/question_bank_generator.py:1033-1045 \u2014 the copies sit in sibling files of one directory, so a shared home is within easy reach: extract the block into a single shared function the call sites can all reach \u2014 a file they already depend on, or a new one alongside them \u2014 and call it from all 3 call sites, so a change lands once. \u2605 These copies have DRIFTED, and that is worth reading before extracting anything: just before the matched lines, \u0060engineering/skills/interview-system-designer/loop_designer.py:879\u0060 calls \u0060join\u0060, \u0060lower\u0060, \u0060isalnum\u0060 and \u0060engineering/skills/interview-system-designer/hiring_calibrator.py:1267\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":"engineering/skills/interview-system-designer/hiring_calibrator.py"},"region":{"startLine":1269}}}],"partialFingerprints":{"codehealthFindingId/v1":"739ff5deaca56f831181e646fbc797031328a0f3591d695cd3fcd25c95ea2cc4"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (13 lines \u00D7 3): engineering/skills/skill-tester/scripts/quality_scorer.py:1166-1178 | engineering/skills/skill-tester/scripts/script_tester.py:715-727 | engineering/skills/skill-tester/scripts/skill_validator.py:681-693 \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":"engineering/skills/skill-tester/scripts/quality_scorer.py"},"region":{"startLine":1166}}}],"partialFingerprints":{"codehealthFindingId/v1":"b938ac4aa0c6534522c52b76fb5430f8697af417db9c0aaf3a35548063c647cc"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (11\u201313 lines \u00D7 3): marketing-skill/skills/competitor-alternatives/scripts/comparison_matrix_builder.py:218-230 | marketing-skill/skills/form-cro/scripts/form_field_analyzer.py:206-216 | marketing-skill/skills/programmatic-seo/scripts/url_pattern_generator.py:132-143 \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":"marketing-skill/skills/competitor-alternatives/scripts/comparison_matrix_builder.py"},"region":{"startLine":218}}}],"partialFingerprints":{"codehealthFindingId/v1":"1eb47f5812e97dd128c669939f505f94e42292d61441c1c0dcc6235e821e9da5"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (11\u201313 lines \u00D7 3): marketing/landing/skills/landing/scripts/html_validator.py:121-133 | marketing/landing/skills/landing/scripts/html_validator.py:143-153 | marketing/landing/skills/landing/scripts/html_validator.py:172-182 \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 \u0060marketing/landing/skills/landing/scripts/html_validator.py:121\u0060 it does not close everything it opens, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that. Note that the copies do not run to the end of the range shown: their LAST lines are different code, not the same code under different names \u2014 the matched region ends inside that line. Extract the lines above it, and read the last line of each site separately. \u2605 These copies have DRIFTED, and that is worth reading before extracting anything: just after the matched lines, \u0060marketing/landing/skills/landing/scripts/html_validator.py:133\u0060 calls \u0060add\u0060, \u0060search\u0060 and \u0060marketing/landing/skills/landing/scripts/html_validator.py:182\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":"marketing/landing/skills/landing/scripts/html_validator.py"},"region":{"startLine":121}}}],"partialFingerprints":{"codehealthFindingId/v1":"6a85b4fc56b3499266b9b4bc6a209bf0a072e716e27aa1abc9f3a820cb21442b"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9\u201313 lines \u00D7 2): business-growth/skills/revenue-operations/scripts/forecast_accuracy_tracker.py:475-487 | business-growth/skills/revenue-operations/scripts/gtm_efficiency_calculator.py:601-609 \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 \u0060business-growth/skills/revenue-operations/scripts/forecast_accuracy_tracker.py:475\u0060 it begins part-way through the construct above it, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that. The \u0060return\u0060 at the foot of the matched lines is the enclosing body\u0027s own terminal exit, not an early one: it moves with them unchanged, and each site calls the extracted unit from the position that \u0060return\u0060 occupied \u2014 no decision has to be handed back and re-acted on."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"business-growth/skills/revenue-operations/scripts/forecast_accuracy_tracker.py"},"region":{"startLine":475}}}],"partialFingerprints":{"codehealthFindingId/v1":"01d6b3846a4816f236612f66368bdd87feb312055489d580ca6c8cbb2572cfa9"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (13 lines \u00D7 2): c-level-advisor/chief-ai-officer-advisor/skills/chief-ai-officer-advisor/scripts/model_buildvsbuy_calculator.py:304-316 | c-level-advisor/skills/chief-ai-officer-advisor/scripts/model_buildvsbuy_calculator.py:304-316 \u2014 before extracting anything, compare \u0060c-level-advisor/chief-ai-officer-advisor/skills/chief-ai-officer-advisor/scripts/model_buildvsbuy_calculator.py\u0060 and \u0060c-level-advisor/skills/chief-ai-officer-advisor/scripts/model_buildvsbuy_calculator.py\u0060 as WHOLE FILES: this scan already matched 12 separate duplicated blocks between them, totalling at least 251 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The \u0060return\u0060 at the foot of the matched lines is the enclosing body\u0027s own terminal exit, not an early one: it moves with them unchanged, and each site calls the extracted unit from the position that \u0060return\u0060 occupied \u2014 no decision has to be handed back and re-acted on."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"c-level-advisor/chief-ai-officer-advisor/skills/chief-ai-officer-advisor/scripts/model_buildvsbuy_calculator.py"},"region":{"startLine":304}}}],"partialFingerprints":{"codehealthFindingId/v1":"cdd42cdcc82bc7a505cb4d2f2fb361a3a936c046093156dbe22ac70456faa29c"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (13 lines \u00D7 2): c-level-advisor/chief-customer-officer-advisor/skills/chief-customer-officer-advisor/scripts/customer_segmentation_designer.py:293-305 | c-level-advisor/skills/chief-customer-officer-advisor/scripts/customer_segmentation_designer.py:293-305 \u2014 before extracting anything, compare \u0060c-level-advisor/chief-customer-officer-advisor/skills/chief-customer-officer-advisor/scripts/customer_segmentation_designer.py\u0060 and \u0060c-level-advisor/skills/chief-customer-officer-advisor/scripts/customer_segmentation_designer.py\u0060 as WHOLE FILES: this scan already matched 11 separate duplicated blocks between them, totalling at least 146 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"c-level-advisor/chief-customer-officer-advisor/skills/chief-customer-officer-advisor/scripts/customer_segmentation_designer.py"},"region":{"startLine":293}}}],"partialFingerprints":{"codehealthFindingId/v1":"01dd8c45650839fc2d050020129c07bfb89d2d15f6aa151370f31885754ef0b9"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (13 lines \u00D7 2): c-level-advisor/skills/vpe-advisor/scripts/eng_hiring_funnel_calculator.py:195-207 | c-level-advisor/vpe-advisor/skills/vpe-advisor/scripts/eng_hiring_funnel_calculator.py:195-207 \u2014 before extracting anything, compare \u0060c-level-advisor/skills/vpe-advisor/scripts/eng_hiring_funnel_calculator.py\u0060 and \u0060c-level-advisor/vpe-advisor/skills/vpe-advisor/scripts/eng_hiring_funnel_calculator.py\u0060 as WHOLE FILES: this scan already matched 7 separate duplicated blocks between them, totalling at least 151 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"c-level-advisor/skills/vpe-advisor/scripts/eng_hiring_funnel_calculator.py"},"region":{"startLine":195}}}],"partialFingerprints":{"codehealthFindingId/v1":"1aa77dcff507a0c4200df10c3b68270fd42cc6b1931b73b0fd584b8a0ccc4d4d"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (13 lines \u00D7 2): engineering-team/skills/cloud-security/scripts/cloud_posture_check.py:541-553 | engineering-team/skills/cloud-security/scripts/cloud_posture_check.py:753-765 \u2014 both copies are in the same file, so extract the block 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":"engineering-team/skills/cloud-security/scripts/cloud_posture_check.py"},"region":{"startLine":541}}}],"partialFingerprints":{"codehealthFindingId/v1":"6f922288a8728018465328d67a1f6160c6a0e319f58a0815b3958ebd5e52d5b2"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (11\u201313 lines \u00D7 2): engineering-team/skills/senior-frontend/scripts/frontend_decision_engine.py:183-193 | engineering-team/skills/senior-fullstack/scripts/fullstack_decision_engine.py:226-238 \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 \u0060engineering-team/skills/senior-fullstack/scripts/fullstack_decision_engine.py:226\u0060 it begins part-way through the construct above it, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that. \u2605 These copies have DRIFTED, and that is worth reading before extracting anything: just before the matched lines, \u0060engineering-team/skills/senior-fullstack/scripts/fullstack_decision_engine.py:223\u0060 calls \u0060abs\u0060 and \u0060engineering-team/skills/senior-frontend/scripts/frontend_decision_engine.py:183\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":"engineering-team/skills/senior-frontend/scripts/frontend_decision_engine.py"},"region":{"startLine":183}}}],"partialFingerprints":{"codehealthFindingId/v1":"7f65148de6e8417a7b22616d152cf215b6f0f70b29206c40364c2a2b50aabdf6"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (13 lines \u00D7 2): engineering/data-quality-auditor/skills/data-quality-auditor/scripts/data_profiler.py:33-45 | engineering/data-quality-auditor/skills/data-quality-auditor/scripts/missing_value_analyzer.py:113-125 \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":"engineering/data-quality-auditor/skills/data-quality-auditor/scripts/data_profiler.py"},"region":{"startLine":33}}}],"partialFingerprints":{"codehealthFindingId/v1":"e01e8cbc8a50db31a157f2772a5b57e321f18d60653ce4ce439f3a82b01b6d7e"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (13 lines \u00D7 2): engineering/kubernetes-operator/skills/kubernetes-operator/scripts/operator_capability_audit.py:134-146 | engineering/skills/kubernetes-operator/scripts/operator_capability_audit.py:134-146 \u2014 before extracting anything, compare \u0060engineering/kubernetes-operator/skills/kubernetes-operator/scripts/operator_capability_audit.py\u0060 and \u0060engineering/skills/kubernetes-operator/scripts/operator_capability_audit.py\u0060 as WHOLE FILES: this scan already matched 5 separate duplicated blocks between them, totalling at least 75 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/kubernetes-operator/skills/kubernetes-operator/scripts/operator_capability_audit.py"},"region":{"startLine":134}}}],"partialFingerprints":{"codehealthFindingId/v1":"8caa8eb4f4cfc5f5b32c131413b7e9e8a57edb9233ebb4caf524e9f9bcbf2deb"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (13 lines \u00D7 2): engineering/skills/agent-designer/agent_evaluator.py:1116-1128 | engineering/skills/agent-designer/tool_schema_generator.py:854-866 \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":"engineering/skills/agent-designer/agent_evaluator.py"},"region":{"startLine":1116}}}],"partialFingerprints":{"codehealthFindingId/v1":"2a0717bd60050ca5c457a654f651f82dc6544bb77aaf5d4ee9de34c91408facb"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (13 lines \u00D7 2): engineering/skills/api-design-reviewer/scripts/api_scorecard.py:285-297 | engineering/skills/api-design-reviewer/scripts/api_scorecard.py:339-351 \u2014 both copies are in the same file, so extract the block 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":"engineering/skills/api-design-reviewer/scripts/api_scorecard.py"},"region":{"startLine":285}}}],"partialFingerprints":{"codehealthFindingId/v1":"41ad7c9f7c4291d2f71382f2ef6f5bf8af46f468e5e43add76ef5f325ec4dfa2"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (13 lines \u00D7 2): engineering/skills/api-design-reviewer/scripts/api_scorecard.py:1299-1311 | engineering/skills/api-design-reviewer/scripts/api_scorecard.py:1383-1395 \u2014 both copies are in the same file, so extract the block 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":"engineering/skills/api-design-reviewer/scripts/api_scorecard.py"},"region":{"startLine":1299}}}],"partialFingerprints":{"codehealthFindingId/v1":"8edff980eec189022b60f454148b7a78110902b5969888302bf83f7a6730127b"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (13 lines \u00D7 2): engineering/skills/ci-cd-pipeline-builder/scripts/pipeline_generator.py:108-123 | engineering/skills/ci-cd-pipeline-builder/scripts/pipeline_generator.py:192-204 \u2014 both copies are in the same file, so extract the block into one function there and call it from each site \u2014 the copies drift apart the first time only one of them is edited. \u2605 These copies have DRIFTED, and that is worth reading before extracting anything: just after the matched lines, \u0060engineering/skills/ci-cd-pipeline-builder/scripts/pipeline_generator.py:205\u0060 calls \u0060select_node_install\u0060 and \u0060engineering/skills/ci-cd-pipeline-builder/scripts/pipeline_generator.py:124\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":"engineering/skills/ci-cd-pipeline-builder/scripts/pipeline_generator.py"},"region":{"startLine":108}}}],"partialFingerprints":{"codehealthFindingId/v1":"bdfa80b1bb76ab5b8d918c7d9edf0c95b6b0b73ecabc97e411e8cc3ddc0f9f2c"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (13 lines \u00D7 2): engineering/skills/git-worktree-manager/scripts/worktree_cleanup.py:59-71 | engineering/skills/git-worktree-manager/scripts/worktree_manager.py:71-83 \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":"engineering/skills/git-worktree-manager/scripts/worktree_cleanup.py"},"region":{"startLine":59}}}],"partialFingerprints":{"codehealthFindingId/v1":"2beb8c7302c799c0e390670df0e3fd9ec3488cacd6a2af24873ec7340c5f325a"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (13 lines \u00D7 2): engineering/skills/migration-architect/scripts/compatibility_checker.py:212-224 | engineering/skills/migration-architect/scripts/compatibility_checker.py:309-321 \u2014 both copies are in the same file, so extract the block into one function there and call it from each site \u2014 the copies drift apart the first time only one of them is edited. Read the line range as the matched WINDOW rather than a finished unit: at \u0060engineering/skills/migration-architect/scripts/compatibility_checker.py:212\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":"engineering/skills/migration-architect/scripts/compatibility_checker.py"},"region":{"startLine":212}}}],"partialFingerprints":{"codehealthFindingId/v1":"3d7b71205cc109efaa955733109c6e08b6f751138062e9a54f52b2f9820323f1"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (12\u201313 lines \u00D7 2): finance/skills/stock-analysis/scripts/score.py:1324-1336 | finance/skills/stock-analysis/scripts/score.py:1462-1473 \u2014 both copies are in the same file, so extract the block into one function there and call it from each site \u2014 the copies drift apart the first time only one of them is edited."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"finance/skills/stock-analysis/scripts/score.py"},"region":{"startLine":1324}}}],"partialFingerprints":{"codehealthFindingId/v1":"6db59bd5eb162782b52e1a27456eab35c6ed2fbfa37b6fba27d10bd79d721cc0"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (13 lines \u00D7 2): marketing-skill/skills/page-cro/scripts/conversion_audit.py:358-370 | marketing-skill/skills/seo-audit/scripts/seo_checker.py:306-318 \u2014 the copies span different directories, so extracting a shared function means choosing where it lives: put it somewhere both call sites can already reach \u2014 a location they all depend on today, or a new shared one if there is none \u2014 and call it from each site; until then, every change has to be made twice. \u2605 These copies have DRIFTED, and that is worth reading before extracting anything: just before the matched lines, \u0060marketing-skill/skills/seo-audit/scripts/seo_checker.py:305\u0060 calls \u0060add_argument\u0060 and \u0060marketing-skill/skills/page-cro/scripts/conversion_audit.py:357\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":"marketing-skill/skills/page-cro/scripts/conversion_audit.py"},"region":{"startLine":358}}}],"partialFingerprints":{"codehealthFindingId/v1":"edac41d009d8651013c16f8b7b530c35fac4b57b58ee215ce8d5de6c9abe320a"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (13 lines \u00D7 2): productivity/andreessen/skills/andreessen/scripts/market_first_evaluator.py:146-158 | productivity/andreessen/skills/andreessen/scripts/pmf_signal_scorer.py:154-166 \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":"productivity/andreessen/skills/andreessen/scripts/market_first_evaluator.py"},"region":{"startLine":146}}}],"partialFingerprints":{"codehealthFindingId/v1":"ed991f5a3ad6dbde5432a773892af1d520b15f2c0fefeeff0a31a74a54c280ad"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (12\u201313 lines \u00D7 2): project-management/skills/scrum-master/scripts/retrospective_analyzer.py:437-448 | project-management/skills/scrum-master/scripts/velocity_analyzer.py:130-142 \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":"project-management/skills/scrum-master/scripts/retrospective_analyzer.py"},"region":{"startLine":437}}}],"partialFingerprints":{"codehealthFindingId/v1":"e5efe367903aa7ef6d51911f024ee604de94a204137a8ee5759e7be16cf44903"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (13 lines \u00D7 2): ra-qm-team/compliance-team-eu-ai-act/skills/eu-ai-act-specialist/scripts/ai_act_obligation_tracker.py:215-227 | ra-qm-team/skills/eu-ai-act-specialist/scripts/ai_act_obligation_tracker.py:215-227 \u2014 before extracting anything, compare \u0060ra-qm-team/compliance-team-eu-ai-act/skills/eu-ai-act-specialist/scripts/ai_act_obligation_tracker.py\u0060 and \u0060ra-qm-team/skills/eu-ai-act-specialist/scripts/ai_act_obligation_tracker.py\u0060 as WHOLE FILES: this scan already matched 11 separate duplicated blocks between them, totalling at least 122 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"ra-qm-team/compliance-team-eu-ai-act/skills/eu-ai-act-specialist/scripts/ai_act_obligation_tracker.py"},"region":{"startLine":215}}}],"partialFingerprints":{"codehealthFindingId/v1":"3597ba5de01c1866f8878824092f29588c818032c20627395d45488909fe8321"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (13 lines \u00D7 2): ra-qm-team/compliance-team-eu-ai-act/skills/eu-ai-act-specialist/scripts/conformity_assessment_planner.py:186-198 | ra-qm-team/skills/eu-ai-act-specialist/scripts/conformity_assessment_planner.py:186-198 \u2014 before extracting anything, compare \u0060ra-qm-team/compliance-team-eu-ai-act/skills/eu-ai-act-specialist/scripts/conformity_assessment_planner.py\u0060 and \u0060ra-qm-team/skills/eu-ai-act-specialist/scripts/conformity_assessment_planner.py\u0060 as WHOLE FILES: this scan already matched 13 separate duplicated blocks between them, totalling at least 187 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The \u0060return\u0060 at the foot of the matched lines is the enclosing body\u0027s own terminal exit, not an early one: it moves with them unchanged, and each site calls the extracted unit from the position that \u0060return\u0060 occupied \u2014 no decision has to be handed back and re-acted on."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"ra-qm-team/compliance-team-eu-ai-act/skills/eu-ai-act-specialist/scripts/conformity_assessment_planner.py"},"region":{"startLine":186}}}],"partialFingerprints":{"codehealthFindingId/v1":"1e5f97d60bba050a6b903fc14f5193604b6a285bbd05c62a8d6e55e18eab8181"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (13 lines \u00D7 2): scripts/sync-hermes-skills.py:230-242 | scripts/sync-vibe-skills.py:280-292 \u2014 before extracting anything, compare \u0060scripts/sync-hermes-skills.py\u0060 and \u0060scripts/sync-vibe-skills.py\u0060 as WHOLE FILES: this scan already matched 6 separate duplicated blocks between them, totalling at least 165 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. If that is what happened, the fix is to keep one copy and have the other call it (or delete it), which resolves this row and its siblings together \u2014 extracting one helper per block leaves the fork in place. \u2605 These copies have DRIFTED, and that is worth reading before extracting anything: just before the matched lines, \u0060scripts/sync-vibe-skills.py:278\u0060 calls \u0060assign_flat_names\u0060 and \u0060scripts/sync-hermes-skills.py:228\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":"scripts/sync-hermes-skills.py"},"region":{"startLine":230}}}],"partialFingerprints":{"codehealthFindingId/v1":"9794e4ae39c29010fe549c15ca7bb857357a462ce96c615af8e2dd9163c50b6c"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (12 lines \u00D7 4): c-level-advisor/arquiteto-de-empresa/skills/arquiteto-de-empresa/scripts/index_generator.py:141-152 | c-level-advisor/arquiteto-de-empresa/skills/arquiteto-de-empresa/scripts/okf_linter.py:157-168 | c-level-advisor/skills/arquiteto-de-empresa/scripts/index_generator.py:141-152 | c-level-advisor/skills/arquiteto-de-empresa/scripts/okf_linter.py:157-168 \u2014 before extracting anything, compare \u0060c-level-advisor/arquiteto-de-empresa/skills/arquiteto-de-empresa/scripts/index_generator.py\u0060 and \u0060c-level-advisor/skills/arquiteto-de-empresa/scripts/index_generator.py\u0060 as WHOLE FILES: this scan already matched 10 separate duplicated blocks between them, totalling at least 135 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. \u2605 These copies have DRIFTED, and that is worth reading before extracting anything: just after the matched lines, \u0060c-level-advisor/arquiteto-de-empresa/skills/arquiteto-de-empresa/scripts/index_generator.py:153\u0060 calls \u0060add_argument\u0060 and \u0060c-level-advisor/arquiteto-de-empresa/skills/arquiteto-de-empresa/scripts/okf_linter.py:169\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":"c-level-advisor/arquiteto-de-empresa/skills/arquiteto-de-empresa/scripts/index_generator.py"},"region":{"startLine":141}}}],"partialFingerprints":{"codehealthFindingId/v1":"28f667111f088b7f92c9e27654350b08e00b46945fcbd7db3f1676c8ff22f894"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (10\u201312 lines \u00D7 4): commercial/skills/channel-economics/scripts/cost_to_serve_calculator.py:168-177 | marketing-skill/skills/competitor-alternatives/scripts/comparison_matrix_builder.py:221-232 | marketing-skill/skills/form-cro/scripts/form_field_analyzer.py:208-218 | marketing-skill/skills/programmatic-seo/scripts/url_pattern_generator.py:135-145 \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."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"commercial/skills/channel-economics/scripts/cost_to_serve_calculator.py"},"region":{"startLine":168}}}],"partialFingerprints":{"codehealthFindingId/v1":"cb79fb240ba87494d0eb9d40f49ed7c639066250d58b80fb4a1e25ed80072a8b"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (11\u201312 lines \u00D7 4): commercial/skills/commercial-forecaster/scripts/bookings_forecaster.py:411-422 | commercial/skills/commercial-forecaster/scripts/cohort_arr_projector.py:253-263 | commercial/skills/commercial-forecaster/scripts/funnel_confidence_scorer.py:165-175 | commercial/skills/pricing-strategist/scripts/pricing_model_picker.py:267-278 \u2014 the copies span different directories, so extracting a shared function means choosing where it lives: put it somewhere all 4 call sites can already reach \u2014 a location they all depend on today, or a new shared one if there is none \u2014 and call it from each site; until then, every change has to be made 4 times. Read the line range as the matched WINDOW rather than a finished unit: at \u0060commercial/skills/commercial-forecaster/scripts/bookings_forecaster.py:411\u0060 it begins part-way through the construct above it, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that. The \u0060return\u0060 at the foot of the matched lines is the enclosing body\u0027s own terminal exit, not an early one: it moves with them unchanged, and each site calls the extracted unit from the position that \u0060return\u0060 occupied \u2014 no decision has to be handed back and re-acted on."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"commercial/skills/commercial-forecaster/scripts/bookings_forecaster.py"},"region":{"startLine":411}}}],"partialFingerprints":{"codehealthFindingId/v1":"6db7f3abd147fa87b9a8feeac20359d982740d68a39db780c662fbd88ce9af8e"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (12 lines \u00D7 4): engineering-team/skills/senior-backend/scripts/api_load_tester.py:585-596 | engineering-team/skills/senior-secops/scripts/compliance_checker.py:1086-1097 | engineering-team/skills/senior-secops/scripts/security_scanner.py:450-461 | engineering-team/skills/senior-secops/scripts/vulnerability_assessor.py:542-553 \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."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/skills/senior-backend/scripts/api_load_tester.py"},"region":{"startLine":585}}}],"partialFingerprints":{"codehealthFindingId/v1":"31d8bda9781acae7d1e96aac509bc61883f285161187afc997bef41c685f8f3a"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (11\u201312 lines \u00D7 4): engineering/skills/api-design-reviewer/scripts/api_scorecard.py:622-633 | engineering/skills/api-design-reviewer/scripts/api_scorecard.py:693-704 | engineering/skills/api-design-reviewer/scripts/api_scorecard.py:726-737 | engineering/skills/api-design-reviewer/scripts/api_scorecard.py:1221-1231 \u2014 all 4 copies are in the same file, so extract the block into one function there and call it from every one of those sites \u2014 resolving only two of them leaves the rest to drift apart the first time one is edited. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/api-design-reviewer/scripts/api_scorecard.py"},"region":{"startLine":622}}}],"partialFingerprints":{"codehealthFindingId/v1":"31073c48e902618e8734dea75c2ff8e4c0255052243b905cd82af87c0658fc6f"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (12 lines \u00D7 4): research-ops/skills/clinical-research/scripts/onboard.py:129-140 | research-ops/skills/market-research/scripts/onboard.py:102-113 | research-ops/skills/product-research/scripts/onboard.py:109-120 | research-ops/skills/research-finance/scripts/onboard.py:105-116 \u2014 before extracting anything, compare \u0060research-ops/skills/market-research/scripts/onboard.py\u0060 and \u0060research-ops/skills/product-research/scripts/onboard.py\u0060 as WHOLE FILES: this scan already matched 5 separate duplicated blocks between them, totalling at least 60 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. Read the line range as the matched WINDOW rather than a finished unit: at \u0060research-ops/skills/clinical-research/scripts/onboard.py:129\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":"research-ops/skills/clinical-research/scripts/onboard.py"},"region":{"startLine":129}}}],"partialFingerprints":{"codehealthFindingId/v1":"50a28ac870dcce82c3d56b4706652253bfb3d9007995e3eaa557915111cfbcf0"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (12 lines \u00D7 3): c-level-advisor/general-counsel-advisor/skills/general-counsel-advisor/scripts/contract_risk_scanner.py:372-383 | c-level-advisor/skills/general-counsel-advisor/scripts/contract_risk_scanner.py:372-383 | engineering/write-a-skill/skills/write-a-skill/scripts/skill_description_validator.py:231-242 \u2014 before extracting anything, compare \u0060c-level-advisor/general-counsel-advisor/skills/general-counsel-advisor/scripts/contract_risk_scanner.py\u0060 and \u0060c-level-advisor/skills/general-counsel-advisor/scripts/contract_risk_scanner.py\u0060 as WHOLE FILES: this scan already matched 5 separate duplicated blocks between them, totalling at least 106 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"c-level-advisor/general-counsel-advisor/skills/general-counsel-advisor/scripts/contract_risk_scanner.py"},"region":{"startLine":372}}}],"partialFingerprints":{"codehealthFindingId/v1":"d65ccf7dc6e2fa0f310342b5d36e0daa4b8ee841316f2f3106dae19f306cc76c"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (12 lines \u00D7 3): engineering-team/skills/senior-architect/scripts/architecture_diagram_generator.py:605-616 | engineering-team/skills/senior-architect/scripts/dependency_analyzer.py:563-574 | engineering-team/skills/senior-architect/scripts/project_architect.py:689-700 \u2014 the copies sit in sibling files of one directory, so a shared home is within easy reach: extract the block into a single shared function the call sites can all reach \u2014 a file they already depend on, or a new one alongside them \u2014 and call it from all 3 call sites, so a change lands once. Read the line range as the matched WINDOW rather than a finished unit: at \u0060engineering-team/skills/senior-architect/scripts/architecture_diagram_generator.py:605\u0060 it runs out through the closing brace of the declaration holding it and carries on into the declaration that follows \u2014 the window is the tail of one member plus the head of the next, so no call can be substituted for those exact lines, and the smallest declaration that contains all of them is the type they sit in. The repeated unit is the member each site sits in: where those members\u0027 bodies are the same, move one whole member to the shared location and have the others delegate to it; where the copies are a run of near-identical overloads or wrappers that differ only in their signatures, the repetition IS the run \u2014 a one-line delegation has no helper inside it to lift \u2014 so generate the run from the set it enumerates, or accept it and keep each member\u0027s own documentation with it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/skills/senior-architect/scripts/architecture_diagram_generator.py"},"region":{"startLine":605}}}],"partialFingerprints":{"codehealthFindingId/v1":"34113bf049239afd971fcb1d325ac41c52a9551b5ce622dbe7a9728876d93301"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (12 lines \u00D7 3): engineering/caveman/skills/caveman/scripts/caveman_compressor.py:223-234 | engineering/caveman/skills/caveman/scripts/caveman_lint.py:168-179 | engineering/caveman/skills/caveman/scripts/token_savings_estimator.py:114-125 \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. \u2605 These copies have DRIFTED, and that is worth reading before extracting anything: just before the matched lines, \u0060engineering/caveman/skills/caveman/scripts/token_savings_estimator.py:113\u0060 calls \u0060add_argument\u0060 and \u0060engineering/caveman/skills/caveman/scripts/caveman_compressor.py:222\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":"engineering/caveman/skills/caveman/scripts/caveman_compressor.py"},"region":{"startLine":223}}}],"partialFingerprints":{"codehealthFindingId/v1":"722fc1423295ce35c6fb7006cec9b6ff4c5d82c0cfeea58a1805c132a0719174"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (12 lines \u00D7 3): engineering/data-quality-auditor/skills/data-quality-auditor/scripts/data_profiler.py:229-240 | engineering/data-quality-auditor/skills/data-quality-auditor/scripts/missing_value_analyzer.py:204-215 | engineering/data-quality-auditor/skills/data-quality-auditor/scripts/outlier_detector.py:231-242 \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":"engineering/data-quality-auditor/skills/data-quality-auditor/scripts/data_profiler.py"},"region":{"startLine":229}}}],"partialFingerprints":{"codehealthFindingId/v1":"650c73d3f20b6c584619d7fdbd1a884b14ca98ec565f59aeaa91abd91a743028"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (12 lines \u00D7 3): engineering/skills/api-design-reviewer/scripts/api_scorecard.py:624-635 | engineering/skills/api-design-reviewer/scripts/api_scorecard.py:757-768 | engineering/skills/api-design-reviewer/scripts/api_scorecard.py:1222-1233 \u2014 all 3 copies are in the same file, so extract the block into one function there and call it from every one of those sites \u2014 resolving only two of them leaves the rest to drift apart the first time one is edited. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/api-design-reviewer/scripts/api_scorecard.py"},"region":{"startLine":624}}}],"partialFingerprints":{"codehealthFindingId/v1":"d6cf18b56922040d645ba49bfccbd1f1fad78453211684f0cc0900c74471b07b"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (12 lines \u00D7 3): engineering/skills/observability-designer/scripts/alert_optimizer.py:347-358 | project-management/skills/atlassian-admin/scripts/permission_audit_tool.py:341-352 | project-management/skills/scrum-master/scripts/sprint_health_scorer.py:591-602 \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":"engineering/skills/observability-designer/scripts/alert_optimizer.py"},"region":{"startLine":347}}}],"partialFingerprints":{"codehealthFindingId/v1":"b785f6a1ac763c6de95f613d0e057af3a242a280a9bff3387f04f89edc2957d9"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (12 lines \u00D7 3): engineering/skills/tc-tracker/scripts/tc_create.py:58-69 | engineering/skills/tc-tracker/scripts/tc_update.py:103-114 | engineering/skills/tc-tracker/scripts/tc_validator.py:288-299 \u2014 the copies sit in sibling files of one directory, so a shared home is within easy reach: extract the block into a single shared function the call sites can all reach \u2014 a file they already depend on, or a new one alongside them \u2014 and call it from all 3 call sites, so a change lands once. The \u0060return\u0060 at the foot of the matched lines is the enclosing body\u0027s own terminal exit, not an early one: it moves with them unchanged, and each site calls the extracted unit from the position that \u0060return\u0060 occupied \u2014 no decision has to be handed back and re-acted on."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/tc-tracker/scripts/tc_create.py"},"region":{"startLine":58}}}],"partialFingerprints":{"codehealthFindingId/v1":"833fca059ba88a860a2aa1824328be097db88200cc0dbc3ab56679a18af2ce1a"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (12 lines \u00D7 3): marketing-skill/skills/competitor-alternatives/scripts/comparison_matrix_builder.py:328-339 | marketing-skill/skills/launch-strategy/scripts/launch_readiness_scorer.py:264-275 | marketing-skill/skills/signup-flow-cro/scripts/funnel_drop_analyzer.py:284-295 \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":"marketing-skill/skills/competitor-alternatives/scripts/comparison_matrix_builder.py"},"region":{"startLine":328}}}],"partialFingerprints":{"codehealthFindingId/v1":"371cd85f2bdd8ef48d662376702a2c2fcbfd0fceafbfefdede4307ca820b1ced"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (11\u201312 lines \u00D7 3): productivity/handoff/hooks/session_end.py:44-54 | productivity/handoff/hooks/session_start.py:47-58 | productivity/handoff/skills/handoff/scripts/handoff_template_generator.py:70-80 \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":"productivity/handoff/hooks/session_end.py"},"region":{"startLine":44}}}],"partialFingerprints":{"codehealthFindingId/v1":"7d5ee23ede0747e0b636ef9ad6619411c70bf5c985d44340ada6ceba48c64a6a"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (12 lines \u00D7 2): business-growth/skills/revenue-operations/scripts/gtm_efficiency_calculator.py:94-105 | business-growth/skills/revenue-operations/scripts/gtm_efficiency_calculator.py:108-119 \u2014 both copies are in the same file, so extract the block 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":"business-growth/skills/revenue-operations/scripts/gtm_efficiency_calculator.py"},"region":{"startLine":94}}}],"partialFingerprints":{"codehealthFindingId/v1":"1f23b39f9a7cbf18d244f00d778b3e4159c681b1922aa79d7b55f8125d0abaa5"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (12 lines \u00D7 2): c-level-advisor/chief-customer-officer-advisor/skills/chief-customer-officer-advisor/scripts/customer_segmentation_designer.py:261-272 | c-level-advisor/skills/chief-customer-officer-advisor/scripts/customer_segmentation_designer.py:261-272 \u2014 before extracting anything, compare \u0060c-level-advisor/chief-customer-officer-advisor/skills/chief-customer-officer-advisor/scripts/customer_segmentation_designer.py\u0060 and \u0060c-level-advisor/skills/chief-customer-officer-advisor/scripts/customer_segmentation_designer.py\u0060 as WHOLE FILES: this scan already matched 11 separate duplicated blocks between them, totalling at least 146 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"c-level-advisor/chief-customer-officer-advisor/skills/chief-customer-officer-advisor/scripts/customer_segmentation_designer.py"},"region":{"startLine":261}}}],"partialFingerprints":{"codehealthFindingId/v1":"4238d732d09fd0cf7d8e4e2d487a332571ec1468cd92ed9e22585b2a9cffd964"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (12 lines \u00D7 2): c-level-advisor/executive-mentor/skills/executive-mentor/scripts/decision_matrix_scorer.py:300-311 | c-level-advisor/executive-mentor/skills/executive-mentor/scripts/stakeholder_mapper.py:373-384 \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":"c-level-advisor/executive-mentor/skills/executive-mentor/scripts/decision_matrix_scorer.py"},"region":{"startLine":300}}}],"partialFingerprints":{"codehealthFindingId/v1":"60aa8e3cd2c3ae9f4ea5fa0312fc819b64196375aaaf0238629eb267d803a9a6"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (12 lines \u00D7 2): engineering-team/skills/senior-architect/scripts/architecture_diagram_generator.py:412-423 | engineering-team/skills/tdd-guide/scripts/tdd_workflow.py:379-390 \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 \u0060engineering-team/skills/senior-architect/scripts/architecture_diagram_generator.py:412\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":"engineering-team/skills/senior-architect/scripts/architecture_diagram_generator.py"},"region":{"startLine":412}}}],"partialFingerprints":{"codehealthFindingId/v1":"3dbb86c1feddd641f1bee70691a450023e392a45858c7b813e81e426208a59eb"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (12 lines \u00D7 2): engineering-team/skills/tech-stack-evaluator/scripts/ecosystem_analyzer.py:68-79 | engineering-team/skills/tech-stack-evaluator/scripts/ecosystem_analyzer.py:136-147 \u2014 both copies are in the same file, so extract the block 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":"engineering-team/skills/tech-stack-evaluator/scripts/ecosystem_analyzer.py"},"region":{"startLine":68}}}],"partialFingerprints":{"codehealthFindingId/v1":"34de0757e98b310aa61816e5bb6b64efc1502bddf87b5c6dcea602b4f88e78ab"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (12 lines \u00D7 2): engineering/chaos-engineering/skills/chaos-engineering/scripts/experiment_postmortem.py:35-46 | engineering/skills/chaos-engineering/scripts/experiment_postmortem.py:35-46 \u2014 before extracting anything, compare \u0060engineering/chaos-engineering/skills/chaos-engineering/scripts/experiment_postmortem.py\u0060 and \u0060engineering/skills/chaos-engineering/scripts/experiment_postmortem.py\u0060 as WHOLE FILES: this scan already matched 4 separate duplicated blocks between them, totalling at least 63 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/chaos-engineering/skills/chaos-engineering/scripts/experiment_postmortem.py"},"region":{"startLine":35}}}],"partialFingerprints":{"codehealthFindingId/v1":"14c5c708bc0f17202b3f894917e50fc0a9466c8d7ff4ee04c8e1cd166d00e2cf"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (12 lines \u00D7 2): engineering/kubernetes-operator/skills/kubernetes-operator/scripts/crd_validator.py:119-130 | engineering/skills/kubernetes-operator/scripts/crd_validator.py:119-130 \u2014 before extracting anything, compare \u0060engineering/kubernetes-operator/skills/kubernetes-operator/scripts/crd_validator.py\u0060 and \u0060engineering/skills/kubernetes-operator/scripts/crd_validator.py\u0060 as WHOLE FILES: this scan already matched 8 separate duplicated blocks between them, totalling at least 79 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/kubernetes-operator/skills/kubernetes-operator/scripts/crd_validator.py"},"region":{"startLine":119}}}],"partialFingerprints":{"codehealthFindingId/v1":"92a4b6c805ea2ed601989a86e1bcc1c36f4514fc2651be96635682a679012155"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (12 lines \u00D7 2): engineering/kubernetes-operator/skills/kubernetes-operator/scripts/operator_capability_audit.py:61-72 | engineering/skills/kubernetes-operator/scripts/operator_capability_audit.py:61-72 \u2014 before extracting anything, compare \u0060engineering/kubernetes-operator/skills/kubernetes-operator/scripts/operator_capability_audit.py\u0060 and \u0060engineering/skills/kubernetes-operator/scripts/operator_capability_audit.py\u0060 as WHOLE FILES: this scan already matched 5 separate duplicated blocks between them, totalling at least 75 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/kubernetes-operator/skills/kubernetes-operator/scripts/operator_capability_audit.py"},"region":{"startLine":61}}}],"partialFingerprints":{"codehealthFindingId/v1":"76fc23e680d71de575861c4b28fe75e647af435a5949ee27531c5d5b63dae13a"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (12 lines \u00D7 2): engineering/kubernetes-operator/skills/kubernetes-operator/scripts/operator_capability_audit.py:102-113 | engineering/skills/kubernetes-operator/scripts/operator_capability_audit.py:102-113 \u2014 before extracting anything, compare \u0060engineering/kubernetes-operator/skills/kubernetes-operator/scripts/operator_capability_audit.py\u0060 and \u0060engineering/skills/kubernetes-operator/scripts/operator_capability_audit.py\u0060 as WHOLE FILES: this scan already matched 5 separate duplicated blocks between them, totalling at least 75 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/kubernetes-operator/skills/kubernetes-operator/scripts/operator_capability_audit.py"},"region":{"startLine":102}}}],"partialFingerprints":{"codehealthFindingId/v1":"37320598c111e5653caa8f5b3f1f6d11a708c239e98309995fe90e55f976ac86"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (12 lines \u00D7 2): engineering/kubernetes-operator/skills/kubernetes-operator/scripts/reconcile_lint.py:162-173 | engineering/skills/kubernetes-operator/scripts/reconcile_lint.py:162-173 \u2014 before extracting anything, compare \u0060engineering/kubernetes-operator/skills/kubernetes-operator/scripts/reconcile_lint.py\u0060 and \u0060engineering/skills/kubernetes-operator/scripts/reconcile_lint.py\u0060 as WHOLE FILES: this scan already matched 9 separate duplicated blocks between them, totalling at least 127 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/kubernetes-operator/skills/kubernetes-operator/scripts/reconcile_lint.py"},"region":{"startLine":162}}}],"partialFingerprints":{"codehealthFindingId/v1":"fa35f02806a276f6109a2d568ecc868088d394d068608bb80e38d98c49a39b8e"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (12 lines \u00D7 2): engineering/skills/api-design-reviewer/scripts/api_scorecard.py:361-372 | engineering/skills/api-design-reviewer/scripts/api_scorecard.py:698-709 \u2014 both copies are in the same file, so extract the block 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":"engineering/skills/api-design-reviewer/scripts/api_scorecard.py"},"region":{"startLine":361}}}],"partialFingerprints":{"codehealthFindingId/v1":"85e814af5764281508a708628c18378032f3949633cac8b97eeee3c1e222287a"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (12 lines \u00D7 2): engineering/skills/api-design-reviewer/scripts/api_scorecard.py:510-521 | engineering/skills/api-design-reviewer/scripts/api_scorecard.py:1091-1102 \u2014 both copies are in the same file, so extract the block 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":"engineering/skills/api-design-reviewer/scripts/api_scorecard.py"},"region":{"startLine":510}}}],"partialFingerprints":{"codehealthFindingId/v1":"c943d13e62842cd47a80eebd97763117f6591e79e49dd5ed0127cbdc894971d9"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (12 lines \u00D7 2): engineering/skills/api-design-reviewer/scripts/api_scorecard.py:728-739 | engineering/skills/api-design-reviewer/scripts/api_scorecard.py:1042-1053 \u2014 both copies are in the same file, so extract the block 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":"engineering/skills/api-design-reviewer/scripts/api_scorecard.py"},"region":{"startLine":728}}}],"partialFingerprints":{"codehealthFindingId/v1":"eddb673ab8cf4ed5833240852a4c93ea7733fe81a00ba5d05aefd2c9b53ff9b2"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (12 lines \u00D7 2): engineering/skills/database-designer/index_optimizer.py:796-807 | engineering/skills/database-designer/schema_analyzer.py:829-840 \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":"engineering/skills/database-designer/index_optimizer.py"},"region":{"startLine":796}}}],"partialFingerprints":{"codehealthFindingId/v1":"b2884d23f810f3eea890a676ce79ebc3e06c1f2bdf821fea4d0608a3fcd82170"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (12 lines \u00D7 2): engineering/skills/skill-security-auditor/scripts/skill_security_auditor.py:750-761 | engineering/skills/skill-security-auditor/scripts/skill_security_auditor.py:762-773 \u2014 both copies are in the same file, so extract the block 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":"engineering/skills/skill-security-auditor/scripts/skill_security_auditor.py"},"region":{"startLine":750}}}],"partialFingerprints":{"codehealthFindingId/v1":"be832a0d8847411b0e1c0e66af7ca6bec1d43ab07cc3f5e560243abe61030ec1"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (12 lines \u00D7 2): engineering/skills/skill-tester/scripts/skill_validator.py:655-666 | ra-qm-team/skills/fda-consultant-specialist/scripts/hipaa_risk_assessment.py:543-561 \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 \u0060engineering/skills/skill-tester/scripts/skill_validator.py:655\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":"engineering/skills/skill-tester/scripts/skill_validator.py"},"region":{"startLine":655}}}],"partialFingerprints":{"codehealthFindingId/v1":"e7060f390fbda089ce08f2bf750143fd13c51c6cf6cf828bc5c8917828400946"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (12 lines \u00D7 2): markdown-html/skills/md-review/scripts/diff_parser.py:279-290 | markdown-html/skills/md-slides/scripts/slide_splitter.py:248-259 \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 \u0060markdown-html/skills/md-review/scripts/diff_parser.py:279\u0060 it begins part-way through the construct above it, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that. The \u0060return\u0060 at the foot of the matched lines is the enclosing body\u0027s own terminal exit, not an early one: it moves with them unchanged, and each site calls the extracted unit from the position that \u0060return\u0060 occupied \u2014 no decision has to be handed back and re-acted on."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"markdown-html/skills/md-review/scripts/diff_parser.py"},"region":{"startLine":279}}}],"partialFingerprints":{"codehealthFindingId/v1":"b883abb04507ef2a670c20db4be4215a88522c75e9bc4106044b8eaaebe6353d"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (12 lines \u00D7 2): project-management/skills/atlassian-admin/scripts/permission_audit_tool.py:368-379 | project-management/skills/confluence-expert/scripts/content_audit_analyzer.py:356-367 \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":"project-management/skills/atlassian-admin/scripts/permission_audit_tool.py"},"region":{"startLine":368}}}],"partialFingerprints":{"codehealthFindingId/v1":"8a9859d227c5d2e2cb30c1d1a885efd999ccc36b28210b8e0a50892fed822115"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (12 lines \u00D7 2): scripts/check_frontmatter.py:183-194 | scripts/check_paths.py:180-191 \u2014 the copies sit in sibling files of one directory, so a shared home is within easy reach: extract the block into a single shared function the call sites can all reach \u2014 a file they already depend on, or a new one alongside them \u2014 and call it from both call sites, so a change lands once. The \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, \u0060scripts/check_frontmatter.py:181\u0060 calls \u0060add_argument\u0060 and \u0060scripts/check_paths.py:178\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":"scripts/check_frontmatter.py"},"region":{"startLine":183}}}],"partialFingerprints":{"codehealthFindingId/v1":"01f9078a9a4727e4b8586ff9669a4ec8a91d503fcc3fa7ce20485c9a5887b7dd"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (11 lines \u00D7 6): c-level-advisor/chief-ai-officer-advisor/skills/chief-ai-officer-advisor/scripts/ai_cost_economics.py:265-275 | c-level-advisor/chief-ai-officer-advisor/skills/chief-ai-officer-advisor/scripts/model_buildvsbuy_calculator.py:287-297 | c-level-advisor/chief-data-officer-advisor/skills/chief-data-officer-advisor/scripts/data_product_strategy_picker.py:285-295 | c-level-advisor/skills/chief-ai-officer-advisor/scripts/ai_cost_economics.py:265-275 | c-level-advisor/skills/chief-ai-officer-advisor/scripts/model_buildvsbuy_calculator.py:287-297 | c-level-advisor/skills/chief-data-officer-advisor/scripts/data_product_strategy_picker.py:285-295 \u2014 the copies span different directories, so extracting a shared function means choosing where it lives: put it somewhere all 6 call sites can already reach \u2014 a location they all depend on today, or a new shared one if there is none \u2014 and call it from each site; until then, every change has to be made 6 times."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"c-level-advisor/chief-ai-officer-advisor/skills/chief-ai-officer-advisor/scripts/ai_cost_economics.py"},"region":{"startLine":265}}}],"partialFingerprints":{"codehealthFindingId/v1":"0467e785f4826f3a24a54bcf94562269f37b4982b75c1ebd19015edd3ddef65c"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (11 lines \u00D7 4): engineering-team/skills/senior-architect/scripts/architecture_diagram_generator.py:411-422 | engineering-team/skills/tdd-guide/scripts/tdd_workflow.py:378-389 | engineering/skillopt-sleep/skillopt_sleep/experiments/report.py:98-108 | marketing-skill/skills/local-seo-manager/scripts/service_area_generator.py:132-142 \u2014 the copies span different directories, so extracting a shared function means choosing where it lives: put it somewhere all 4 call sites can already reach \u2014 a location they all depend on today, or a new shared one if there is none \u2014 and call it from each site; until then, every change has to be made 4 times. Read the line range as the matched WINDOW rather than a finished unit: at \u0060engineering-team/skills/senior-architect/scripts/architecture_diagram_generator.py:411\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":"engineering-team/skills/senior-architect/scripts/architecture_diagram_generator.py"},"region":{"startLine":411}}}],"partialFingerprints":{"codehealthFindingId/v1":"c5ab7154d36a6cde56e306ee3f375dd2e90a85780092c2b2d1b30c4fee199178"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (11 lines \u00D7 4): engineering/grill-me/skills/grill-me/scripts/decision_tree_extractor.py:127-137 | engineering/grill-me/skills/grill-me/scripts/question_generator.py:120-130 | engineering/handoff/skills/handoff/scripts/artifact_deduplicator.py:222-232 | engineering/handoff/skills/handoff/scripts/skill_recommender.py:163-173 \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":"engineering/grill-me/skills/grill-me/scripts/decision_tree_extractor.py"},"region":{"startLine":127}}}],"partialFingerprints":{"codehealthFindingId/v1":"f284d479097faf411532839721695d6a76f7cccdc7e806991967a80f9fdafdcf"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9\u201311 lines \u00D7 3): engineering/skills/agent-designer/agent_evaluator.py:1117-1125 | engineering/skills/agent-designer/tool_schema_generator.py:855-863 | engineering/skills/dependency-auditor/scripts/license_checker.py:961-971 \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. Read the line range as the matched WINDOW rather than a finished unit: at \u0060engineering/skills/dependency-auditor/scripts/license_checker.py:961\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":"engineering/skills/agent-designer/agent_evaluator.py"},"region":{"startLine":1117}}}],"partialFingerprints":{"codehealthFindingId/v1":"45c0108821274e45077c7954dd1be045ae4442718ef000ee3fff3cde44290afe"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (11 lines \u00D7 3): engineering/skills/skill-tester/scripts/quality_scorer.py:517-527 | engineering/skills/skill-tester/scripts/quality_scorer.py:803-813 | engineering/skills/skill-tester/scripts/quality_scorer.py:962-972 \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":"engineering/skills/skill-tester/scripts/quality_scorer.py"},"region":{"startLine":517}}}],"partialFingerprints":{"codehealthFindingId/v1":"16fff2fdb6b4d6452f1745484b2f145027c0787dfd0f3b2ef0eb74564996363e"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (11 lines \u00D7 3): marketing/linkedin/skills/linkedin-skills/scripts/linkedin_goal_router.py:119-129 | product-team/skills/product-skills/scripts/product_goal_router.py:152-162 | project-management/skills/pm-skills/scripts/pm_goal_router.py:124-134 \u2014 before extracting anything, compare \u0060marketing/linkedin/skills/linkedin-skills/scripts/linkedin_goal_router.py\u0060 and \u0060product-team/skills/product-skills/scripts/product_goal_router.py\u0060 as WHOLE FILES: this scan already matched 8 separate duplicated blocks between them, totalling at least 79 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"marketing/linkedin/skills/linkedin-skills/scripts/linkedin_goal_router.py"},"region":{"startLine":119}}}],"partialFingerprints":{"codehealthFindingId/v1":"0d292a0f1dcb60683c608f5783898707e69e7586ef8e37150e664045179ae447"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (10\u201311 lines \u00D7 2): business-growth/skills/customer-success-manager/scripts/churn_risk_analyzer.py:367-376 | business-growth/skills/customer-success-manager/scripts/health_score_calculator.py:326-336 \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":"business-growth/skills/customer-success-manager/scripts/churn_risk_analyzer.py"},"region":{"startLine":367}}}],"partialFingerprints":{"codehealthFindingId/v1":"18c4de945de397a6dc4745659313e4850050bad04ee40d44b65103457c8ba508"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (10\u201311 lines \u00D7 2): business-growth/skills/revenue-operations/scripts/gtm_efficiency_calculator.py:634-644 | business-growth/skills/revenue-operations/scripts/pipeline_analyzer.py:505-514 \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 \u0060business-growth/skills/revenue-operations/scripts/gtm_efficiency_calculator.py:634\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":"business-growth/skills/revenue-operations/scripts/gtm_efficiency_calculator.py"},"region":{"startLine":634}}}],"partialFingerprints":{"codehealthFindingId/v1":"457be8efce0ee7a4a3c4affd659060ce36e089641d4ff4303ef209bde1f43e76"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (11 lines \u00D7 2): c-level-advisor/arquiteto-de-empresa/skills/arquiteto-de-empresa/scripts/okf_linter.py:40-50 | c-level-advisor/skills/arquiteto-de-empresa/scripts/okf_linter.py:40-50 \u2014 before extracting anything, compare \u0060c-level-advisor/arquiteto-de-empresa/skills/arquiteto-de-empresa/scripts/okf_linter.py\u0060 and \u0060c-level-advisor/skills/arquiteto-de-empresa/scripts/okf_linter.py\u0060 as WHOLE FILES: this scan already matched 7 separate duplicated blocks between them, totalling at least 147 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"c-level-advisor/arquiteto-de-empresa/skills/arquiteto-de-empresa/scripts/okf_linter.py"},"region":{"startLine":40}}}],"partialFingerprints":{"codehealthFindingId/v1":"bc309684c72eddba15110886eff10ed95b8b107545335325af7d852fdd21748f"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (11 lines \u00D7 2): c-level-advisor/arquiteto-de-empresa/skills/arquiteto-de-empresa/scripts/scaffold_bundle.py:128-138 | c-level-advisor/skills/arquiteto-de-empresa/scripts/scaffold_bundle.py:128-138 \u2014 before extracting anything, compare \u0060c-level-advisor/arquiteto-de-empresa/skills/arquiteto-de-empresa/scripts/scaffold_bundle.py\u0060 and \u0060c-level-advisor/skills/arquiteto-de-empresa/scripts/scaffold_bundle.py\u0060 as WHOLE FILES: this scan already matched 7 separate duplicated blocks between them, totalling at least 108 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"c-level-advisor/arquiteto-de-empresa/skills/arquiteto-de-empresa/scripts/scaffold_bundle.py"},"region":{"startLine":128}}}],"partialFingerprints":{"codehealthFindingId/v1":"fca5329a6bace94bfa7b89859eb29a679204a596b174771d8660b8517feb612d"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (11 lines \u00D7 2): c-level-advisor/chief-ai-officer-advisor/skills/chief-ai-officer-advisor/scripts/model_buildvsbuy_calculator.py:107-117 | c-level-advisor/skills/chief-ai-officer-advisor/scripts/model_buildvsbuy_calculator.py:107-117 \u2014 before extracting anything, compare \u0060c-level-advisor/chief-ai-officer-advisor/skills/chief-ai-officer-advisor/scripts/model_buildvsbuy_calculator.py\u0060 and \u0060c-level-advisor/skills/chief-ai-officer-advisor/scripts/model_buildvsbuy_calculator.py\u0060 as WHOLE FILES: this scan already matched 12 separate duplicated blocks between them, totalling at least 251 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The \u0060return\u0060 at the foot of the matched lines is the enclosing body\u0027s own terminal exit, not an early one: it moves with them unchanged, and each site calls the extracted unit from the position that \u0060return\u0060 occupied \u2014 no decision has to be handed back and re-acted on."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"c-level-advisor/chief-ai-officer-advisor/skills/chief-ai-officer-advisor/scripts/model_buildvsbuy_calculator.py"},"region":{"startLine":107}}}],"partialFingerprints":{"codehealthFindingId/v1":"257739e00036e6c19e0f062f41a99e72613115018880b1a781077c5ce0f94de2"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (11 lines \u00D7 2): c-level-advisor/chief-customer-officer-advisor/skills/chief-customer-officer-advisor/scripts/cs_coverage_calculator.py:207-217 | c-level-advisor/skills/chief-customer-officer-advisor/scripts/cs_coverage_calculator.py:207-217 \u2014 before extracting anything, compare \u0060c-level-advisor/chief-customer-officer-advisor/skills/chief-customer-officer-advisor/scripts/cs_coverage_calculator.py\u0060 and \u0060c-level-advisor/skills/chief-customer-officer-advisor/scripts/cs_coverage_calculator.py\u0060 as WHOLE FILES: this scan already matched 8 separate duplicated blocks between them, totalling at least 188 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"c-level-advisor/chief-customer-officer-advisor/skills/chief-customer-officer-advisor/scripts/cs_coverage_calculator.py"},"region":{"startLine":207}}}],"partialFingerprints":{"codehealthFindingId/v1":"95000f96aa0d0b954afe4435eebc21682d033096c8f08ec8470091ef54247466"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (11 lines \u00D7 2): c-level-advisor/chief-customer-officer-advisor/skills/chief-customer-officer-advisor/scripts/retention_decomposition_analyzer.py:234-244 | c-level-advisor/skills/chief-customer-officer-advisor/scripts/retention_decomposition_analyzer.py:234-244 \u2014 before extracting anything, compare \u0060c-level-advisor/chief-customer-officer-advisor/skills/chief-customer-officer-advisor/scripts/retention_decomposition_analyzer.py\u0060 and \u0060c-level-advisor/skills/chief-customer-officer-advisor/scripts/retention_decomposition_analyzer.py\u0060 as WHOLE FILES: this scan already matched 9 separate duplicated blocks between them, totalling at least 171 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"c-level-advisor/chief-customer-officer-advisor/skills/chief-customer-officer-advisor/scripts/retention_decomposition_analyzer.py"},"region":{"startLine":234}}}],"partialFingerprints":{"codehealthFindingId/v1":"37d605be6f9cd113d2a8cd3b80b14bf935ff9653623fbc943a44b7339d26bcd6"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (11 lines \u00D7 2): c-level-advisor/chief-data-officer-advisor/skills/chief-data-officer-advisor/scripts/ai_training_data_audit.py:359-369 | c-level-advisor/skills/chief-data-officer-advisor/scripts/ai_training_data_audit.py:359-369 \u2014 before extracting anything, compare \u0060c-level-advisor/chief-data-officer-advisor/skills/chief-data-officer-advisor/scripts/ai_training_data_audit.py\u0060 and \u0060c-level-advisor/skills/chief-data-officer-advisor/scripts/ai_training_data_audit.py\u0060 as WHOLE FILES: this scan already matched 8 separate duplicated blocks between them, totalling at least 314 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"c-level-advisor/chief-data-officer-advisor/skills/chief-data-officer-advisor/scripts/ai_training_data_audit.py"},"region":{"startLine":359}}}],"partialFingerprints":{"codehealthFindingId/v1":"bfc55b6520935446a76949a5b6de758affb0ed9064e61e782484bbb61d9ca19e"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (11 lines \u00D7 2): c-level-advisor/chief-data-officer-advisor/skills/chief-data-officer-advisor/scripts/data_asset_valuator.py:247-257 | c-level-advisor/skills/chief-data-officer-advisor/scripts/data_asset_valuator.py:247-257 \u2014 before extracting anything, compare \u0060c-level-advisor/chief-data-officer-advisor/skills/chief-data-officer-advisor/scripts/data_asset_valuator.py\u0060 and \u0060c-level-advisor/skills/chief-data-officer-advisor/scripts/data_asset_valuator.py\u0060 as WHOLE FILES: this scan already matched 12 separate duplicated blocks between them, totalling at least 283 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"c-level-advisor/chief-data-officer-advisor/skills/chief-data-officer-advisor/scripts/data_asset_valuator.py"},"region":{"startLine":247}}}],"partialFingerprints":{"codehealthFindingId/v1":"3c6ad6849163a51ed86abf05d624997b086bd59bbea98b4c91cd335b4980fc81"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (11 lines \u00D7 2): c-level-advisor/skills/chro-advisor/scripts/hiring_plan_modeler.py:348-358 | c-level-advisor/skills/chro-advisor/scripts/hiring_plan_modeler.py:359-369 \u2014 both copies are in the same file, so extract the block 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":"c-level-advisor/skills/chro-advisor/scripts/hiring_plan_modeler.py"},"region":{"startLine":348}}}],"partialFingerprints":{"codehealthFindingId/v1":"dc7d6b757d33f817c347da98db88312c839e7bc87ca4593b743e2ace68bb8b7f"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (11 lines \u00D7 2): c-level-advisor/skills/vpe-advisor/scripts/delivery_throughput_analyzer.py:114-124 | c-level-advisor/vpe-advisor/skills/vpe-advisor/scripts/delivery_throughput_analyzer.py:114-124 \u2014 before extracting anything, compare \u0060c-level-advisor/skills/vpe-advisor/scripts/delivery_throughput_analyzer.py\u0060 and \u0060c-level-advisor/vpe-advisor/skills/vpe-advisor/scripts/delivery_throughput_analyzer.py\u0060 as WHOLE FILES: this scan already matched 12 separate duplicated blocks between them, totalling at least 119 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"c-level-advisor/skills/vpe-advisor/scripts/delivery_throughput_analyzer.py"},"region":{"startLine":114}}}],"partialFingerprints":{"codehealthFindingId/v1":"cb7a570e1ec2b632e1fd0a85c31acdb70d2b0babd4d0c89a3443cc44c94103c9"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (11 lines \u00D7 2): commercial/skills/partnerships-architect/scripts/partner_tier_classifier.py:195-205 | commercial/skills/partnerships-architect/scripts/partner_tier_classifier.py:235-245 \u2014 both copies are in the same file, so extract the block into one function there and call it from each site \u2014 the copies drift apart the first time only one of them is edited. \u2605 These copies have DRIFTED, and that is worth reading before extracting anything: just before the matched lines, \u0060commercial/skills/partnerships-architect/scripts/partner_tier_classifier.py:234\u0060 calls \u0060get\u0060, \u0060lower\u0060 and \u0060commercial/skills/partnerships-architect/scripts/partner_tier_classifier.py:194\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":"commercial/skills/partnerships-architect/scripts/partner_tier_classifier.py"},"region":{"startLine":195}}}],"partialFingerprints":{"codehealthFindingId/v1":"6b834f9ebb191c185e7609e6d71e40620c2541b88e730f032fb843475d43a531"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (11 lines \u00D7 2): engineering-team/skills/aws-solution-architect/scripts/architecture_designer.py:24-34 | engineering-team/skills/gcp-cloud-architect/scripts/architecture_designer.py:27-37 \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":"engineering-team/skills/aws-solution-architect/scripts/architecture_designer.py"},"region":{"startLine":24}}}],"partialFingerprints":{"codehealthFindingId/v1":"7fc6ffd1038a3fb42f40f11cf87df6f7fd5676cb95da53d427dee964aa8fb6ad"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (11 lines \u00D7 2): engineering-team/skills/threat-detection/scripts/threat_signal_analyzer.py:490-500 | engineering-team/skills/threat-detection/scripts/threat_signal_analyzer.py:523-533 \u2014 both copies are in the same file, so extract the block 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, \u0060engineering-team/skills/threat-detection/scripts/threat_signal_analyzer.py:503\u0060 calls \u0060get\u0060 and \u0060engineering-team/skills/threat-detection/scripts/threat_signal_analyzer.py:536\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":"engineering-team/skills/threat-detection/scripts/threat_signal_analyzer.py"},"region":{"startLine":490}}}],"partialFingerprints":{"codehealthFindingId/v1":"78f669d87aaeb4ebfec05c6e32c82685c592b9f266fdc6db640f53624c3dbddc"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (8\u201311 lines \u00D7 2): engineering-team/snowflake-development/skills/snowflake-development/scripts/snowflake_query_helper.py:174-184 | engineering-team/snowflake-development/skills/snowflake-development/scripts/snowflake_query_helper.py:188-195 \u2014 both copies are in the same file, so extract the block 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 \u0060engineering-team/snowflake-development/skills/snowflake-development/scripts/snowflake_query_helper.py:174\u0060 it begins part-way through the construct above it, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that. \u2605 These copies have DRIFTED, and that is worth reading before extracting anything: just before the matched lines, \u0060engineering-team/snowflake-development/skills/snowflake-development/scripts/snowflake_query_helper.py:186\u0060 calls \u0060add_argument\u0060 and \u0060engineering-team/snowflake-development/skills/snowflake-development/scripts/snowflake_query_helper.py:174\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":"engineering-team/snowflake-development/skills/snowflake-development/scripts/snowflake_query_helper.py"},"region":{"startLine":174}}}],"partialFingerprints":{"codehealthFindingId/v1":"51837bd1d435a494547326f3b6cae5b1f85633f5622ba6f485729230b94ba663"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (11 lines \u00D7 2): engineering/autoresearch-agent/skills/autoresearch-agent/scripts/log_results.py:222-232 | engineering/autoresearch-agent/skills/autoresearch-agent/scripts/log_results.py:287-297 \u2014 both copies are in the same file, so extract the block 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":"engineering/autoresearch-agent/skills/autoresearch-agent/scripts/log_results.py"},"region":{"startLine":222}}}],"partialFingerprints":{"codehealthFindingId/v1":"6f59fec218928fc0ea565a4ce48f8fd6264482e4912f8c70678955ae9448e4d8"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (11 lines \u00D7 2): engineering/feature-flags-architect/skills/feature-flags-architect/scripts/kill_switch_audit.py:35-45 | engineering/skills/feature-flags-architect/scripts/kill_switch_audit.py:35-45 \u2014 before extracting anything, compare \u0060engineering/feature-flags-architect/skills/feature-flags-architect/scripts/kill_switch_audit.py\u0060 and \u0060engineering/skills/feature-flags-architect/scripts/kill_switch_audit.py\u0060 as WHOLE FILES: this scan already matched 6 separate duplicated blocks between them, totalling at least 94 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/feature-flags-architect/skills/feature-flags-architect/scripts/kill_switch_audit.py"},"region":{"startLine":35}}}],"partialFingerprints":{"codehealthFindingId/v1":"64322823f94118d45d44f0fb8f4b15ce2b4baf353f69af58cf2a177003c959be"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (11 lines \u00D7 2): engineering/kubernetes-operator/skills/kubernetes-operator/scripts/crd_validator.py:104-114 | engineering/skills/kubernetes-operator/scripts/crd_validator.py:104-114 \u2014 before extracting anything, compare \u0060engineering/kubernetes-operator/skills/kubernetes-operator/scripts/crd_validator.py\u0060 and \u0060engineering/skills/kubernetes-operator/scripts/crd_validator.py\u0060 as WHOLE FILES: this scan already matched 8 separate duplicated blocks between them, totalling at least 79 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/kubernetes-operator/skills/kubernetes-operator/scripts/crd_validator.py"},"region":{"startLine":104}}}],"partialFingerprints":{"codehealthFindingId/v1":"280dacca3b36a0efc3eaa67986db105830b1abcb2935cc5a55b213ad301983ba"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (10\u201311 lines \u00D7 2): engineering/llm-wiki/skills/llm-wiki/scripts/graph_analyzer.py:50-59 | engineering/llm-wiki/skills/llm-wiki/scripts/lint_wiki.py:68-78 \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":"engineering/llm-wiki/skills/llm-wiki/scripts/graph_analyzer.py"},"region":{"startLine":50}}}],"partialFingerprints":{"codehealthFindingId/v1":"7617f89eaafd4c60eaaa912a50c749ece8d95d31e4a7bd5519f343fb41195e7a"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (11 lines \u00D7 2): engineering/skills/agent-designer/tool_schema_generator.py:309-319 | engineering/skills/agent-designer/tool_schema_generator.py:323-333 \u2014 both copies are in the same file, so extract the block 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":"engineering/skills/agent-designer/tool_schema_generator.py"},"region":{"startLine":309}}}],"partialFingerprints":{"codehealthFindingId/v1":"f7b0d53b7e037100575da3a66a6f77d1d8d9b0b8255ae2b4a331dcdc4cde4913"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (10\u201311 lines \u00D7 2): engineering/skills/changelog-generator/scripts/commit_linter.py:68-77 | engineering/skills/changelog-generator/scripts/generate_changelog.py:104-114 \u2014 the copies sit in sibling files of one directory, so a shared home is within easy reach: extract the block into a single shared function the call sites can all reach \u2014 a file they already depend on, or a new one alongside them \u2014 and call it from both call sites, so a change lands once. 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":"engineering/skills/changelog-generator/scripts/commit_linter.py"},"region":{"startLine":68}}}],"partialFingerprints":{"codehealthFindingId/v1":"5a650946f3f65b1d29a3c09169120bbfe76f52cabe37b744d0438ca2dc0febcc"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (11 lines \u00D7 2): engineering/skills/database-designer/migration_generator.py:664-674 | engineering/skills/database-designer/migration_generator.py:688-698 \u2014 both copies are in the same file, so extract the block 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 \u0060engineering/skills/database-designer/migration_generator.py:664\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":"engineering/skills/database-designer/migration_generator.py"},"region":{"startLine":664}}}],"partialFingerprints":{"codehealthFindingId/v1":"f9bb51d10a7c875bb18aa4ac198acf334c9f0f54a59ee32199bd37d5f37169f8"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (11 lines \u00D7 2): engineering/skills/slo-architect/scripts/error_budget_calculator.py:91-101 | engineering/slo-architect/skills/slo-architect/scripts/error_budget_calculator.py:91-101 \u2014 before extracting anything, compare \u0060engineering/skills/slo-architect/scripts/error_budget_calculator.py\u0060 and \u0060engineering/slo-architect/skills/slo-architect/scripts/error_budget_calculator.py\u0060 as WHOLE FILES: this scan already matched 7 separate duplicated blocks between them, totalling at least 89 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/slo-architect/scripts/error_budget_calculator.py"},"region":{"startLine":91}}}],"partialFingerprints":{"codehealthFindingId/v1":"a1767b1459f9de66e5a33a0a3af2489eeae3b440521db35d59a6f9086f193c8e"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (11 lines \u00D7 2): engineering/skills/slo-architect/scripts/slo_review.py:140-150 | engineering/slo-architect/skills/slo-architect/scripts/slo_review.py:140-150 \u2014 before extracting anything, compare \u0060engineering/skills/slo-architect/scripts/slo_review.py\u0060 and \u0060engineering/slo-architect/skills/slo-architect/scripts/slo_review.py\u0060 as WHOLE FILES: this scan already matched 9 separate duplicated blocks between them, totalling at least 103 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/slo-architect/scripts/slo_review.py"},"region":{"startLine":140}}}],"partialFingerprints":{"codehealthFindingId/v1":"7dd2478e8f5a7b29d76fe0f7dc9e4895e2b207abbd1eef0c5746e860e216f534"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (11 lines \u00D7 2): engineering/skills/tc-tracker/scripts/tc_create.py:160-170 | engineering/skills/tc-tracker/scripts/tc_update.py:152-162 \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":"engineering/skills/tc-tracker/scripts/tc_create.py"},"region":{"startLine":160}}}],"partialFingerprints":{"codehealthFindingId/v1":"7965c4a15682ebcff49913ab1df01c41270e19fa0c1ef5dfaf41833017886c9e"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (10\u201311 lines \u00D7 2): engineering/write-a-skill/skills/write-a-skill/scripts/skill_review_checklist_runner.py:248-257 | engineering/write-a-skill/skills/write-a-skill/scripts/skill_structure_validator.py:256-266 \u2014 the copies sit in sibling files of one directory, so a shared home is within easy reach: extract the block into a single shared function the call sites can all reach \u2014 a file they already depend on, or a new one alongside them \u2014 and call it from both call sites, so a change lands once. 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":"engineering/write-a-skill/skills/write-a-skill/scripts/skill_review_checklist_runner.py"},"region":{"startLine":248}}}],"partialFingerprints":{"codehealthFindingId/v1":"80b9a887a7ae3c7a2c643dbb2a1848bf3f0376d4f648e182562bc33203056482"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (11 lines \u00D7 2): markdown-html/skills/design-system/scripts/config_loader.py:90-100 | research-ops/skills/clinical-research/scripts/config_loader.py:70-80 \u2014 before extracting anything, compare \u0060markdown-html/skills/design-system/scripts/config_loader.py\u0060 and \u0060research-ops/skills/clinical-research/scripts/config_loader.py\u0060 as WHOLE FILES: this scan already matched 6 separate duplicated blocks between them, totalling at least 60 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"markdown-html/skills/design-system/scripts/config_loader.py"},"region":{"startLine":90}}}],"partialFingerprints":{"codehealthFindingId/v1":"74ba8599ad4083e9ab11e687b96083cc09a630e235158a079a2c0045139cbac4"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (10\u201311 lines \u00D7 2): marketing-skill/skills/campaign-analytics/scripts/attribution_analyzer.py:209-218 | marketing-skill/skills/campaign-analytics/scripts/campaign_roi_calculator.py:300-310 \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":"marketing-skill/skills/campaign-analytics/scripts/attribution_analyzer.py"},"region":{"startLine":209}}}],"partialFingerprints":{"codehealthFindingId/v1":"9b65b71ba740a8d3fa05264eb2543702a86fe634c203f0daa2c762d88ffd6c4b"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (11 lines \u00D7 2): marketing-skill/skills/churn-prevention/scripts/churn_impact_calculator.py:121-131 | marketing-skill/skills/pricing-strategy/scripts/pricing_modeler.py:147-157 \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":"marketing-skill/skills/churn-prevention/scripts/churn_impact_calculator.py"},"region":{"startLine":121}}}],"partialFingerprints":{"codehealthFindingId/v1":"abf9387f22305c02568e85ee7da0d89fd763e068af252a2da9acd7213ff40a4f"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9\u201311 lines \u00D7 2): productivity/reflect/skills/reflect/scripts/bias_pattern_detector.py:157-167 | research/grants/skills/grants/scripts/mechanism_matcher.py:175-183 \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":"productivity/reflect/skills/reflect/scripts/bias_pattern_detector.py"},"region":{"startLine":157}}}],"partialFingerprints":{"codehealthFindingId/v1":"73a5784e0ba7e3016892ed28d2ded943b30cc4ab3f5dadef759f169727a460b2"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (10 lines \u00D7 50): c-level-advisor/chief-ai-officer-advisor/skills/chief-ai-officer-advisor/scripts/ai_cost_economics.py:315-324 | c-level-advisor/chief-ai-officer-advisor/skills/chief-ai-officer-advisor/scripts/ai_risk_classifier.py:443-452 | c-level-advisor/chief-ai-officer-advisor/skills/chief-ai-officer-advisor/scripts/model_buildvsbuy_calculator.py:329-338 | c-level-advisor/chief-customer-officer-advisor/skills/chief-customer-officer-advisor/scripts/cs_coverage_calculator.py:245-254 | c-level-advisor/chief-customer-officer-advisor/skills/chief-customer-officer-advisor/scripts/customer_segmentation_designer.py:315-324 | c-level-advisor/chief-customer-officer-advisor/skills/chief-customer-officer-advisor/scripts/retention_decomposition_analyzer.py:277-286 | c-level-advisor/chief-data-officer-advisor/skills/chief-data-officer-advisor/scripts/ai_training_data_audit.py:403-412 | c-level-advisor/chief-data-officer-advisor/skills/chief-data-officer-advisor/scripts/data_asset_valuator.py:338-347 | c-level-advisor/chief-data-officer-advisor/skills/chief-data-officer-advisor/scripts/data_product_strategy_picker.py:322-331 | c-level-advisor/general-counsel-advisor/skills/general-counsel-advisor/scripts/contract_risk_scanner.py:366-375 | c-level-advisor/general-counsel-advisor/skills/general-counsel-advisor/scripts/term_sheet_analyzer.py:372-381 | c-level-advisor/skills/chief-ai-officer-advisor/scripts/ai_cost_economics.py:315-324 | c-level-advisor/skills/chief-ai-officer-advisor/scripts/ai_risk_classifier.py:443-452 | c-level-advisor/skills/chief-ai-officer-advisor/scripts/model_buildvsbuy_calculator.py:329-338 | c-level-advisor/skills/chief-customer-officer-advisor/scripts/cs_coverage_calculator.py:245-254 | c-level-advisor/skills/chief-customer-officer-advisor/scripts/customer_segmentation_designer.py:315-324 | c-level-advisor/skills/chief-customer-officer-advisor/scripts/retention_decomposition_analyzer.py:277-286 | c-level-advisor/skills/chief-data-officer-advisor/scripts/ai_training_data_audit.py:403-412 | c-level-advisor/skills/chief-data-officer-advisor/scripts/data_asset_valuator.py:338-347 | c-level-advisor/skills/chief-data-officer-advisor/scripts/data_product_strategy_picker.py:322-331 | c-level-advisor/skills/general-counsel-advisor/scripts/contract_risk_scanner.py:366-375 | c-level-advisor/skills/general-counsel-advisor/scripts/term_sheet_analyzer.py:372-381 | c-level-advisor/skills/vpe-advisor/scripts/delivery_throughput_analyzer.py:242-251 | c-level-advisor/skills/vpe-advisor/scripts/eng_hiring_funnel_calculator.py:247-256 | c-level-advisor/skills/vpe-advisor/scripts/eng_team_structure_designer.py:243-252 | c-level-advisor/vpe-advisor/skills/vpe-advisor/scripts/delivery_throughput_analyzer.py:242-251 | c-level-advisor/vpe-advisor/skills/vpe-advisor/scripts/eng_hiring_funnel_calculator.py:247-256 | c-level-advisor/vpe-advisor/skills/vpe-advisor/scripts/eng_team_structure_designer.py:243-252 | compliance-os/skills/compliance-os/scripts/audit_simulator.py:363-372 | compliance-os/skills/compliance-os/scripts/cross_framework_mapper.py:397-406 | compliance-os/skills/compliance-os/scripts/evidence_pool_generator.py:321-330 | compliance-os/skills/compliance-os/scripts/framework_selector.py:281-290 | engineering/grill-me/skills/grill-me/scripts/decision_tree_extractor.py:121-130 | engineering/grill-me/skills/grill-me/scripts/question_generator.py:114-123 | engineering/handoff/skills/handoff/scripts/artifact_deduplicator.py:216-225 | engineering/handoff/skills/handoff/scripts/skill_recommender.py:157-166 | engineering/write-a-skill/skills/write-a-skill/scripts/skill_description_validator.py:225-234 | engineering/write-a-skill/skills/write-a-skill/scripts/skill_review_checklist_runner.py:241-250 | ra-qm-team/compliance-team-eu-ai-act/skills/eu-ai-act-specialist/scripts/ai_act_obligation_tracker.py:240-249 | ra-qm-team/compliance-team-eu-ai-act/skills/eu-ai-act-specialist/scripts/ai_system_risk_classifier.py:305-314 | ra-qm-team/compliance-team-eu-ai-act/skills/eu-ai-act-specialist/scripts/conformity_assessment_planner.py:276-285 | ra-qm-team/compliance-team-iso42001/skills/iso42001-specialist/scripts/ai_risk_register_builder.py:224-233 | ra-qm-team/compliance-team-iso42001/skills/iso42001-specialist/scripts/aims_audit_scheduler.py:229-238 | ra-qm-team/compliance-team-iso42001/skills/iso42001-specialist/scripts/aims_gap_analyzer.py:218-227 | ra-qm-team/skills/eu-ai-act-specialist/scripts/ai_act_obligation_tracker.py:240-249 | ra-qm-team/skills/eu-ai-act-specialist/scripts/ai_system_risk_classifier.py:305-314 | ra-qm-team/skills/eu-ai-act-specialist/scripts/conformity_assessment_planner.py:276-285 | ra-qm-team/skills/iso42001-specialist/scripts/ai_risk_register_builder.py:224-233 | ra-qm-team/skills/iso42001-specialist/scripts/aims_audit_scheduler.py:229-238 | ra-qm-team/skills/iso42001-specialist/scripts/aims_gap_analyzer.py:218-227 \u2014 the copies span different directories, so extracting a shared function means choosing where it lives: put it somewhere all 50 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 50 times."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"c-level-advisor/chief-ai-officer-advisor/skills/chief-ai-officer-advisor/scripts/ai_cost_economics.py"},"region":{"startLine":315}}}],"partialFingerprints":{"codehealthFindingId/v1":"b984f3e4fe900f33f7790221479d32dd16509874da8ba86cf07bbb31a85b63b9"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9\u201310 lines \u00D7 6): engineering/skills/ci-cd-pipeline-builder/scripts/pipeline_generator.py:49-58 | engineering/skills/ci-cd-pipeline-builder/scripts/stack_detector.py:49-58 | engineering/skills/git-worktree-manager/scripts/worktree_cleanup.py:45-53 | engineering/skills/git-worktree-manager/scripts/worktree_manager.py:56-65 | marketing-skill/skills/prompt-engineer-toolkit/scripts/prompt_tester.py:70-79 | marketing-skill/skills/prompt-engineer-toolkit/scripts/prompt_versioner.py:77-86 \u2014 the copies span different directories, so extracting a shared function means choosing where it lives: put it somewhere all 6 call sites can already reach \u2014 a location they all depend on today, or a new shared one if there is none \u2014 and call it from each site; until then, every change has to be made 6 times. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/ci-cd-pipeline-builder/scripts/pipeline_generator.py"},"region":{"startLine":49}}}],"partialFingerprints":{"codehealthFindingId/v1":"650dbcee9a449def83354132fb687510270812976fa8fb7e4259c55c5cd3bc03"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (10 lines \u00D7 6): project-management/skills/scrum-master/scripts/retrospective_analyzer.py:839-848 | project-management/skills/scrum-master/scripts/sprint_health_scorer.py:669-678 | project-management/skills/scrum-master/scripts/velocity_analyzer.py:505-514 | project-management/skills/senior-pm/scripts/project_health_dashboard.py:723-732 | project-management/skills/senior-pm/scripts/resource_capacity_planner.py:746-755 | project-management/skills/senior-pm/scripts/risk_matrix_analyzer.py:601-610 \u2014 the copies span different directories, so extracting a shared function means choosing where it lives: put it somewhere all 6 call sites can already reach \u2014 a location they all depend on today, or a new shared one if there is none \u2014 and call it from each site; until then, every change has to be made 6 times. 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 \u0060result\u0060 to \u0060RetroAnalysisResult\u0060 in one and \u0060HealthScoreResult\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. \u2605 These copies have DRIFTED, and that is worth reading before extracting anything: just after the matched lines, \u0060project-management/skills/senior-pm/scripts/resource_capacity_planner.py:761\u0060 calls \u0060serialize_resource\u0060, \u0060hasattr\u0060 and \u0060project-management/skills/scrum-master/scripts/retrospective_analyzer.py:853\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":"project-management/skills/scrum-master/scripts/retrospective_analyzer.py"},"region":{"startLine":839}}}],"partialFingerprints":{"codehealthFindingId/v1":"e1505f39abda5006a04193f82cc61a3069287aaa53037ee78ce749ce0c710797"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (10 lines \u00D7 5): business-growth/skills/customer-success-manager/scripts/churn_risk_analyzer.py:467-476 | business-growth/skills/customer-success-manager/scripts/expansion_opportunity_scorer.py:394-403 | business-growth/skills/customer-success-manager/scripts/health_score_calculator.py:457-466 | marketing-skill/skills/campaign-analytics/scripts/attribution_analyzer.py:314-323 | marketing-skill/skills/campaign-analytics/scripts/campaign_roi_calculator.py:430-439 \u2014 the copies span different directories, so extracting a shared function means choosing where it lives: put it somewhere all 5 call sites can already reach \u2014 a location they all depend on today, or a new shared one if there is none \u2014 and call it from each site; until then, every change has to be made 5 times."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"business-growth/skills/customer-success-manager/scripts/churn_risk_analyzer.py"},"region":{"startLine":467}}}],"partialFingerprints":{"codehealthFindingId/v1":"ec2b779a2c192f920c84c166870f1297a687ea3cda8ffb5c61f62b48e168ff5b"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (10 lines \u00D7 5): productivity/andreessen/skills/andreessen/scripts/market_first_evaluator.py:164-173 | productivity/andreessen/skills/andreessen/scripts/pmf_signal_scorer.py:133-142 | productivity/roast/skills/roast/scripts/brief_builder.py:83-92 | productivity/roast/skills/roast/scripts/cheapest_test_designer.py:129-138 | productivity/roast/skills/roast/scripts/verdict_synthesizer.py:167-176 \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 \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":"productivity/andreessen/skills/andreessen/scripts/market_first_evaluator.py"},"region":{"startLine":164}}}],"partialFingerprints":{"codehealthFindingId/v1":"8e05ea7ff064d876d763b39aa74d8ef8e160cee27f20224c2bf43956e99121ee"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (10 lines \u00D7 4): c-level-advisor/skills/cpo-advisor/scripts/pmf_scorer.py:228-238 | c-level-advisor/skills/cpo-advisor/scripts/pmf_scorer.py:242-251 | c-level-advisor/skills/cpo-advisor/scripts/pmf_scorer.py:333-342 | c-level-advisor/skills/cpo-advisor/scripts/pmf_scorer.py:346-355 \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 \u0060c-level-advisor/skills/cpo-advisor/scripts/pmf_scorer.py:228\u0060 it begins part-way through the construct above it, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"c-level-advisor/skills/cpo-advisor/scripts/pmf_scorer.py"},"region":{"startLine":228}}}],"partialFingerprints":{"codehealthFindingId/v1":"0a7d1ea5e931a58a7c6b6e36e5a5ee5022964060fcd8f33d86210da303e3e3c3"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9\u201310 lines \u00D7 4): research/grants/skills/grants/scripts/mechanism_matcher.py:203-212 | research/notebooklm/skills/notebooklm/scripts/action_router.py:259-267 | research/notebooklm/skills/notebooklm/scripts/async_action_classifier.py:249-258 | research/notebooklm/skills/notebooklm/scripts/custom_prompt_template_generator.py:257-266 \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 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":"research/grants/skills/grants/scripts/mechanism_matcher.py"},"region":{"startLine":203}}}],"partialFingerprints":{"codehealthFindingId/v1":"4607f93e6f022978613efb63e0e510bdd9b95583a95bceec3827f17498c3ccfd"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (10 lines \u00D7 3): engineering-team/skills/incident-commander/scripts/pir_generator.py:1323-1332 | engineering-team/skills/senior-architect/scripts/architecture_diagram_generator.py:413-423 | engineering-team/skills/tdd-guide/scripts/tdd_workflow.py:380-390 \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. Read the line range as the matched WINDOW rather than a finished unit: at \u0060engineering-team/skills/senior-architect/scripts/architecture_diagram_generator.py:413\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":"engineering-team/skills/incident-commander/scripts/pir_generator.py"},"region":{"startLine":1323}}}],"partialFingerprints":{"codehealthFindingId/v1":"faf02fbca8e11e67d26c59e4d66a82e9d6e7ffe457ed687ecb636f4d365d47e4"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (10 lines \u00D7 3): engineering-team/skills/senior-backend/scripts/backend_decision_engine.py:234-243 | engineering-team/skills/senior-frontend/scripts/frontend_decision_engine.py:187-196 | engineering-team/skills/senior-fullstack/scripts/fullstack_decision_engine.py:232-241 \u2014 before extracting anything, compare \u0060engineering-team/skills/senior-backend/scripts/backend_decision_engine.py\u0060 and \u0060engineering-team/skills/senior-frontend/scripts/frontend_decision_engine.py\u0060 as WHOLE FILES: this scan already matched 6 separate duplicated blocks between them, totalling at least 99 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/skills/senior-backend/scripts/backend_decision_engine.py"},"region":{"startLine":234}}}],"partialFingerprints":{"codehealthFindingId/v1":"29ce73063d05bf6d453330fb0c3f6739169a4f1cc6c38ac52b3ef133c43f4e5b"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (10 lines \u00D7 3): engineering-team/skills/senior-frontend/scripts/bundle_analyzer.py:373-382 | ra-qm-team/skills/fda-consultant-specialist/scripts/hipaa_risk_assessment.py:556-566 | ra-qm-team/skills/fda-consultant-specialist/scripts/qsr_compliance_checker.py:601-611 \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. Read the line range as the matched WINDOW rather than a finished unit: at \u0060engineering-team/skills/senior-frontend/scripts/bundle_analyzer.py:373\u0060 it begins part-way through the construct above it, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/skills/senior-frontend/scripts/bundle_analyzer.py"},"region":{"startLine":373}}}],"partialFingerprints":{"codehealthFindingId/v1":"aaa0455024dd88fcbd1658902f8e80727701905b8914d9e21b4ef3bbd18169e7"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (10 lines \u00D7 3): engineering/agenthub/skills/agenthub/scripts/board_manager.py:226-235 | engineering/agenthub/skills/agenthub/scripts/result_ranker.py:203-212 | engineering/agenthub/skills/agenthub/scripts/session_manager.py:268-277 \u2014 the copies sit in sibling files of one directory, so a shared home is within easy reach: extract the block into a single shared function the call sites can all reach \u2014 a file they already depend on, or a new one alongside them \u2014 and call it from all 3 call sites, so a change lands once. Read the line range as the matched WINDOW rather than a finished unit: at \u0060engineering/agenthub/skills/agenthub/scripts/board_manager.py:226\u0060 it begins part-way through the construct above it, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that. The \u0060return\u0060 at the foot of the matched lines is the enclosing body\u0027s own terminal exit, not an early one: it moves with them unchanged, and each site calls the extracted unit from the position that \u0060return\u0060 occupied \u2014 no decision has to be handed back and re-acted on."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/agenthub/skills/agenthub/scripts/board_manager.py"},"region":{"startLine":226}}}],"partialFingerprints":{"codehealthFindingId/v1":"5cd131f5c37bc3cbf3bdb8337c1bc921d969ddd7be45e321eb9a62f24bdbd536"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (8\u201310 lines \u00D7 3): engineering/skills/dependency-auditor/scripts/dep_scanner.py:696-705 | engineering/skills/dependency-auditor/scripts/license_checker.py:877-884 | engineering/skills/dependency-auditor/scripts/upgrade_planner.py:891-898 \u2014 the copies sit in sibling files of one directory, so a shared home is within easy reach: extract the block into a single shared function the call sites can all reach \u2014 a file they already depend on, or a new one alongside them \u2014 and call it from all 3 call sites, so a change lands once. Read the line range as the matched WINDOW rather than a finished unit: at \u0060engineering/skills/dependency-auditor/scripts/dep_scanner.py:696\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":"engineering/skills/dependency-auditor/scripts/dep_scanner.py"},"region":{"startLine":696}}}],"partialFingerprints":{"codehealthFindingId/v1":"831bea53933eb0b0826918114bd80a29be03688240f46782ade31ec5e920416c"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (10 lines \u00D7 3): engineering/skills/migration-architect/scripts/compatibility_checker.py:841-850 | engineering/skills/migration-architect/scripts/migration_planner.py:625-634 | engineering/skills/migration-architect/scripts/rollback_generator.py:1073-1082 \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":"engineering/skills/migration-architect/scripts/compatibility_checker.py"},"region":{"startLine":841}}}],"partialFingerprints":{"codehealthFindingId/v1":"44ded2fd6827cecef6fb6ad867d08a470bcdcfdc47477f3ab8ac986b7c4b1382"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (10 lines \u00D7 3): engineering/skills/migration-architect/scripts/compatibility_checker.py:852-861 | engineering/skills/migration-architect/scripts/migration_planner.py:636-645 | engineering/skills/migration-architect/scripts/rollback_generator.py:1084-1093 \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":"engineering/skills/migration-architect/scripts/compatibility_checker.py"},"region":{"startLine":852}}}],"partialFingerprints":{"codehealthFindingId/v1":"cc38f63c4227cb943c7d089c907edc024355ca576efc65f828a197605c007980"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9\u201310 lines \u00D7 3): finance/skills/stock-analysis/scripts/ratios.py:1375-1383 | finance/skills/stock-analysis/scripts/ratios.py:1393-1401 | finance/skills/stock-analysis/scripts/ratios.py:1438-1447 \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 \u0060finance/skills/stock-analysis/scripts/ratios.py:1375\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":"finance/skills/stock-analysis/scripts/ratios.py"},"region":{"startLine":1375}}}],"partialFingerprints":{"codehealthFindingId/v1":"2ddf686e9098e17113391f0ba205525f52b537b54102195f4eab77e4f1b7b523"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9\u201310 lines \u00D7 3): marketing-skill/skills/app-store-optimization/scripts/aso_scorer.py:187-196 | marketing-skill/skills/app-store-optimization/scripts/aso_scorer.py:240-248 | marketing-skill/skills/app-store-optimization/scripts/aso_scorer.py:287-295 \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":"marketing-skill/skills/app-store-optimization/scripts/aso_scorer.py"},"region":{"startLine":187}}}],"partialFingerprints":{"codehealthFindingId/v1":"eac9482e919e068f0ea63b9adfe819cb1ff9256aacc852af418a90d952c90646"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9\u201310 lines \u00D7 3): marketing/linkedin/skills/linkedin-skills/scripts/linkedin_goal_router.py:156-165 | product-team/skills/product-skills/scripts/product_goal_router.py:180-188 | project-management/skills/pm-skills/scripts/pm_goal_router.py:152-160 \u2014 before extracting anything, compare \u0060marketing/linkedin/skills/linkedin-skills/scripts/linkedin_goal_router.py\u0060 and \u0060product-team/skills/product-skills/scripts/product_goal_router.py\u0060 as WHOLE FILES: this scan already matched 8 separate duplicated blocks between them, totalling at least 79 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. Read the line range as the matched WINDOW rather than a finished unit: at \u0060marketing/linkedin/skills/linkedin-skills/scripts/linkedin_goal_router.py:156\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":"marketing/linkedin/skills/linkedin-skills/scripts/linkedin_goal_router.py"},"region":{"startLine":156}}}],"partialFingerprints":{"codehealthFindingId/v1":"8dc0c0b2b44a612091b6e734709088482ca2be1ca3cc90d7178a5e00278aa83e"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9\u201310 lines \u00D7 3): marketing/linkedin/skills/linkedin-skills/scripts/linkedin_goal_router.py:165-174 | product-team/skills/product-skills/scripts/product_goal_router.py:189-197 | project-management/skills/pm-skills/scripts/pm_goal_router.py:161-169 \u2014 before extracting anything, compare \u0060marketing/linkedin/skills/linkedin-skills/scripts/linkedin_goal_router.py\u0060 and \u0060product-team/skills/product-skills/scripts/product_goal_router.py\u0060 as WHOLE FILES: this scan already matched 8 separate duplicated blocks between them, totalling at least 79 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. Read the line range as the matched WINDOW rather than a finished unit: at \u0060marketing/linkedin/skills/linkedin-skills/scripts/linkedin_goal_router.py:165\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":"marketing/linkedin/skills/linkedin-skills/scripts/linkedin_goal_router.py"},"region":{"startLine":165}}}],"partialFingerprints":{"codehealthFindingId/v1":"98e8869625cd01a2c45d971721944434e832493b4b93181440e5925888056ec4"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (10 lines \u00D7 3): productivity/email/skills/inbox-setup/scripts/section_progress_tracker.py:241-250 | research/grants/skills/grants/scripts/citation_tracker.py:290-299 | research/litreview/skills/litreview/scripts/citation_tracker.py:246-255 \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":"productivity/email/skills/inbox-setup/scripts/section_progress_tracker.py"},"region":{"startLine":241}}}],"partialFingerprints":{"codehealthFindingId/v1":"97c35f48e9e68cf5b25a4ab7f0a75ee8e67b486072d31f95745272251df8a5bf"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (10 lines \u00D7 3): project-management/skills/atlassian-admin/scripts/permission_audit_tool.py:366-375 | project-management/skills/confluence-expert/scripts/content_audit_analyzer.py:354-363 | project-management/skills/jira-expert/scripts/jql_query_builder.py:366-375 \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":"project-management/skills/atlassian-admin/scripts/permission_audit_tool.py"},"region":{"startLine":366}}}],"partialFingerprints":{"codehealthFindingId/v1":"94e64ac5a00922df4d229fe864fbf678e32a377a079076c5444a611bab934cf6"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (4\u201310 lines \u00D7 6): engineering-team/skills/code-reviewer/scripts/review_report_generator.py:268-271 | engineering-team/skills/incident-commander/scripts/pir_generator.py:1290-1293 | marketing-skill/skills/local-seo-manager/scripts/nap_checker.py:189-192 | project-management/skills/atlassian-admin/scripts/permission_audit_tool.py:393-401 | project-management/skills/confluence-expert/scripts/content_audit_analyzer.py:390-399 | project-management/skills/jira-expert/scripts/workflow_validator.py:354-363 \u2014 the copies span different directories, so extracting a shared function means choosing where it lives: put it somewhere all 6 call sites can already reach \u2014 a location they all depend on today, or a new shared one if there is none \u2014 and call it from each site; until then, every change has to be made 6 times. 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":"engineering-team/skills/code-reviewer/scripts/review_report_generator.py"},"region":{"startLine":268}}}],"partialFingerprints":{"codehealthFindingId/v1":"baa98a28a434bd758768ba989b3538f2bc8bfe21fa99b8314744515b8747f3e6"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (10 lines \u00D7 3): research/dossier/skills/dossier/scripts/citation_tracker.py:281-290 | research/patent/skills/patent/scripts/citation_tracker.py:228-237 | research/syllabus/skills/syllabus/scripts/citation_tracker.py:204-213 \u2014 before extracting anything, compare \u0060research/dossier/skills/dossier/scripts/citation_tracker.py\u0060 and \u0060research/syllabus/skills/syllabus/scripts/citation_tracker.py\u0060 as WHOLE FILES: this scan already matched 3 separate duplicated blocks between them, totalling at least 46 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"research/dossier/skills/dossier/scripts/citation_tracker.py"},"region":{"startLine":281}}}],"partialFingerprints":{"codehealthFindingId/v1":"3224430f2228313c2226e34d3e2a6288b3433a7ba734d8bdf06c924b2e5d1e5c"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (10 lines \u00D7 2): business-growth/skills/customer-success-manager/scripts/churn_risk_analyzer.py:414-423 | business-growth/skills/customer-success-manager/scripts/health_score_calculator.py:366-375 \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":"business-growth/skills/customer-success-manager/scripts/churn_risk_analyzer.py"},"region":{"startLine":414}}}],"partialFingerprints":{"codehealthFindingId/v1":"28386792293fa2b22d25d90b8cf085479a5e545660b24de4780061dfba7de52c"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (10 lines \u00D7 2): business-growth/skills/revenue-operations/scripts/forecast_accuracy_tracker.py:409-418 | project-management/skills/jira-expert/scripts/workflow_validator.py:323-332 \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":"business-growth/skills/revenue-operations/scripts/forecast_accuracy_tracker.py"},"region":{"startLine":409}}}],"partialFingerprints":{"codehealthFindingId/v1":"d53f4d0aab2ca6e07a280b17744f26b7713e9c10bebcc68ba03fd82641d8a8e0"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (10 lines \u00D7 2): business-growth/skills/sales-engineer/scripts/poc_planner.py:658-667 | business-growth/skills/sales-engineer/scripts/rfp_response_analyzer.py:497-506 \u2014 the copies sit in sibling files of one directory, so a shared home is within easy reach: extract the block into a single shared function the call sites can all reach \u2014 a file they already depend on, or a new one alongside them \u2014 and call it from both call sites, so a change lands once. \u2605 These copies have DRIFTED, and that is worth reading before extracting anything: just after the matched lines, \u0060business-growth/skills/sales-engineer/scripts/poc_planner.py:670\u0060 calls \u0060items\u0060 and \u0060business-growth/skills/sales-engineer/scripts/rfp_response_analyzer.py:507\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":"business-growth/skills/sales-engineer/scripts/poc_planner.py"},"region":{"startLine":658}}}],"partialFingerprints":{"codehealthFindingId/v1":"0d2a90e08cbde49368829d03259b00c801850593cc7d0fa172f5590bc574262c"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (10 lines \u00D7 2): business-operations/skills/vendor-management/scripts/sla_compliance_tracker.py:309-318 | business-operations/skills/vendor-management/scripts/vendor_risk_classifier.py:338-348 \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 \u0060business-operations/skills/vendor-management/scripts/vendor_risk_classifier.py:338\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":"business-operations/skills/vendor-management/scripts/sla_compliance_tracker.py"},"region":{"startLine":309}}}],"partialFingerprints":{"codehealthFindingId/v1":"83ea620b9d27482950fe81d8f89f029b4a95462b767765dade8a1d4a761fd771"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (10 lines \u00D7 2): c-level-advisor/arquiteto-de-empresa/skills/arquiteto-de-empresa/scripts/okf_linter.py:140-149 | c-level-advisor/skills/arquiteto-de-empresa/scripts/okf_linter.py:140-149 \u2014 before extracting anything, compare \u0060c-level-advisor/arquiteto-de-empresa/skills/arquiteto-de-empresa/scripts/okf_linter.py\u0060 and \u0060c-level-advisor/skills/arquiteto-de-empresa/scripts/okf_linter.py\u0060 as WHOLE FILES: this scan already matched 7 separate duplicated blocks between them, totalling at least 147 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"c-level-advisor/arquiteto-de-empresa/skills/arquiteto-de-empresa/scripts/okf_linter.py"},"region":{"startLine":140}}}],"partialFingerprints":{"codehealthFindingId/v1":"f4317c2813e133260ce7a74e6cafcf2ec76748fedcb59c8e24d100cdedf2981c"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (10 lines \u00D7 2): c-level-advisor/chief-ai-officer-advisor/skills/chief-ai-officer-advisor/scripts/ai_cost_economics.py:284-293 | c-level-advisor/skills/chief-ai-officer-advisor/scripts/ai_cost_economics.py:284-293 \u2014 before extracting anything, compare \u0060c-level-advisor/chief-ai-officer-advisor/skills/chief-ai-officer-advisor/scripts/ai_cost_economics.py\u0060 and \u0060c-level-advisor/skills/chief-ai-officer-advisor/scripts/ai_cost_economics.py\u0060 as WHOLE FILES: this scan already matched 11 separate duplicated blocks between them, totalling at least 231 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"c-level-advisor/chief-ai-officer-advisor/skills/chief-ai-officer-advisor/scripts/ai_cost_economics.py"},"region":{"startLine":284}}}],"partialFingerprints":{"codehealthFindingId/v1":"58a10a8ef3279fd93ef35e5c6d2ec392b0f571dda79d273815391d4a0c14f4e9"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (10 lines \u00D7 2): c-level-advisor/chief-customer-officer-advisor/skills/chief-customer-officer-advisor/scripts/cs_coverage_calculator.py:195-204 | c-level-advisor/skills/chief-customer-officer-advisor/scripts/cs_coverage_calculator.py:195-204 \u2014 before extracting anything, compare \u0060c-level-advisor/chief-customer-officer-advisor/skills/chief-customer-officer-advisor/scripts/cs_coverage_calculator.py\u0060 and \u0060c-level-advisor/skills/chief-customer-officer-advisor/scripts/cs_coverage_calculator.py\u0060 as WHOLE FILES: this scan already matched 8 separate duplicated blocks between them, totalling at least 188 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"c-level-advisor/chief-customer-officer-advisor/skills/chief-customer-officer-advisor/scripts/cs_coverage_calculator.py"},"region":{"startLine":195}}}],"partialFingerprints":{"codehealthFindingId/v1":"f4821f6df8b593732ebc55b3743c161cb1d8920141cf5190decac234f9d97458"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (10 lines \u00D7 2): c-level-advisor/chief-data-officer-advisor/skills/chief-data-officer-advisor/scripts/data_asset_valuator.py:294-303 | c-level-advisor/skills/chief-data-officer-advisor/scripts/data_asset_valuator.py:294-303 \u2014 before extracting anything, compare \u0060c-level-advisor/chief-data-officer-advisor/skills/chief-data-officer-advisor/scripts/data_asset_valuator.py\u0060 and \u0060c-level-advisor/skills/chief-data-officer-advisor/scripts/data_asset_valuator.py\u0060 as WHOLE FILES: this scan already matched 12 separate duplicated blocks between them, totalling at least 283 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"c-level-advisor/chief-data-officer-advisor/skills/chief-data-officer-advisor/scripts/data_asset_valuator.py"},"region":{"startLine":294}}}],"partialFingerprints":{"codehealthFindingId/v1":"700ad9d14412240342554f7a9332cab3ce2e4b676ba4d00894cd5e9b5a30cfbe"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (10 lines \u00D7 2): c-level-advisor/chief-data-officer-advisor/skills/chief-data-officer-advisor/scripts/data_asset_valuator.py:304-313 | c-level-advisor/skills/chief-data-officer-advisor/scripts/data_asset_valuator.py:304-313 \u2014 before extracting anything, compare \u0060c-level-advisor/chief-data-officer-advisor/skills/chief-data-officer-advisor/scripts/data_asset_valuator.py\u0060 and \u0060c-level-advisor/skills/chief-data-officer-advisor/scripts/data_asset_valuator.py\u0060 as WHOLE FILES: this scan already matched 12 separate duplicated blocks between them, totalling at least 283 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"c-level-advisor/chief-data-officer-advisor/skills/chief-data-officer-advisor/scripts/data_asset_valuator.py"},"region":{"startLine":304}}}],"partialFingerprints":{"codehealthFindingId/v1":"1812321af2e10fd3cd92a22a2c1d6d285698d44e3e9768a1360ec27f15694e8f"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (10 lines \u00D7 2): c-level-advisor/skills/vpe-advisor/scripts/delivery_throughput_analyzer.py:206-215 | c-level-advisor/vpe-advisor/skills/vpe-advisor/scripts/delivery_throughput_analyzer.py:206-215 \u2014 before extracting anything, compare \u0060c-level-advisor/skills/vpe-advisor/scripts/delivery_throughput_analyzer.py\u0060 and \u0060c-level-advisor/vpe-advisor/skills/vpe-advisor/scripts/delivery_throughput_analyzer.py\u0060 as WHOLE FILES: this scan already matched 12 separate duplicated blocks between them, totalling at least 119 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"c-level-advisor/skills/vpe-advisor/scripts/delivery_throughput_analyzer.py"},"region":{"startLine":206}}}],"partialFingerprints":{"codehealthFindingId/v1":"b26159c76b24a3ccc1dfaa85de6f1071e051bec63a5a7c82c874f25604abf2d2"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (10 lines \u00D7 2): commercial/skills/partnerships-architect/scripts/joint_gtm_planner.py:345-354 | commercial/skills/partnerships-architect/scripts/partner_tier_classifier.py:494-503 \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":"commercial/skills/partnerships-architect/scripts/joint_gtm_planner.py"},"region":{"startLine":345}}}],"partialFingerprints":{"codehealthFindingId/v1":"af28f16fd780739c18e691635fbbd5e06d1eda05990a3e09a9267b9c993619a2"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (10 lines \u00D7 2): commercial/skills/pricing-strategist/scripts/pricing_model_picker.py:102-111 | commercial/skills/pricing-strategist/scripts/pricing_model_picker.py:121-130 \u2014 both copies are in the same file, so extract the block 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":"commercial/skills/pricing-strategist/scripts/pricing_model_picker.py"},"region":{"startLine":102}}}],"partialFingerprints":{"codehealthFindingId/v1":"c0b2ac76c7456574931c4f4916c492bcc53f960ef739aa5caeb8037c62caa241"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (10 lines \u00D7 2): commercial/skills/pricing-strategist/scripts/wtp_analyzer.py:194-203 | engineering-team/skills/incident-commander/scripts/pir_generator.py:1322-1332 \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 \u0060commercial/skills/pricing-strategist/scripts/wtp_analyzer.py:194\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":"commercial/skills/pricing-strategist/scripts/wtp_analyzer.py"},"region":{"startLine":194}}}],"partialFingerprints":{"codehealthFindingId/v1":"061a138e8e8d9a9a80fadb828b8a501e52351d232de73cd9d99b42069e940ef6"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (10 lines \u00D7 2): engineering/agenthub/skills/agenthub/scripts/dag_analyzer.py:235-244 | engineering/agenthub/skills/agenthub/scripts/hub_init.py:185-194 \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 \u0060engineering/agenthub/skills/agenthub/scripts/dag_analyzer.py:235\u0060 it begins part-way through the construct above it, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that. The \u0060return\u0060 at the foot of the matched lines is the enclosing body\u0027s own terminal exit, not an early one: it moves with them unchanged, and each site calls the extracted unit from the position that \u0060return\u0060 occupied \u2014 no decision has to be handed back and re-acted on."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/agenthub/skills/agenthub/scripts/dag_analyzer.py"},"region":{"startLine":235}}}],"partialFingerprints":{"codehealthFindingId/v1":"1c5468d2817034eeed1f6f5dab659d057488856a569fddd9cc4ddb4b56ad5c31"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (10 lines \u00D7 2): engineering/agenthub/skills/agenthub/scripts/hub_init.py:185-194 | engineering/agenthub/skills/agenthub/scripts/result_ranker.py:203-212 \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 \u0060engineering/agenthub/skills/agenthub/scripts/hub_init.py:185\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. \u2605 These copies have DRIFTED, and that is worth reading before extracting anything: just before the matched lines, \u0060engineering/agenthub/skills/agenthub/scripts/result_ranker.py:202\u0060 calls \u0060add_argument\u0060 and \u0060engineering/agenthub/skills/agenthub/scripts/hub_init.py:184\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":"engineering/agenthub/skills/agenthub/scripts/hub_init.py"},"region":{"startLine":185}}}],"partialFingerprints":{"codehealthFindingId/v1":"429b4a38337ccee4ecbdb29b4763b157571869c64002f5217ceea508fd14b693"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (10 lines \u00D7 2): engineering/docker-development/skills/docker-development/scripts/dockerfile_analyzer.py:321-330 | engineering/helm-chart-builder/skills/helm-chart-builder/scripts/chart_analyzer.py:422-431 \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":"engineering/docker-development/skills/docker-development/scripts/dockerfile_analyzer.py"},"region":{"startLine":321}}}],"partialFingerprints":{"codehealthFindingId/v1":"1e3fdd757f47d931a89179a8059fbbc056c57054b8b27262ecde592d2537ba5a"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (10 lines \u00D7 2): engineering/feature-flags-architect/skills/feature-flags-architect/scripts/flag_debt_scanner.py:35-44 | engineering/skills/feature-flags-architect/scripts/flag_debt_scanner.py:35-44 \u2014 before extracting anything, compare \u0060engineering/feature-flags-architect/skills/feature-flags-architect/scripts/flag_debt_scanner.py\u0060 and \u0060engineering/skills/feature-flags-architect/scripts/flag_debt_scanner.py\u0060 as WHOLE FILES: this scan already matched 7 separate duplicated blocks between them, totalling at least 77 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/feature-flags-architect/skills/feature-flags-architect/scripts/flag_debt_scanner.py"},"region":{"startLine":35}}}],"partialFingerprints":{"codehealthFindingId/v1":"b13ad9853188e261ed6734703b66fc16ef8d394767b7de61f6aa63a4b53e67e0"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (10 lines \u00D7 2): engineering/skills/api-design-reviewer/scripts/api_scorecard.py:319-328 | engineering/skills/api-design-reviewer/scripts/api_scorecard.py:731-740 \u2014 both copies are in the same file, so extract the block 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":"engineering/skills/api-design-reviewer/scripts/api_scorecard.py"},"region":{"startLine":319}}}],"partialFingerprints":{"codehealthFindingId/v1":"c95a2988c2ad67c1ea8db53e5de96ed3dbcd867561001bf20c829f3711956a1e"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (10 lines \u00D7 2): engineering/skills/api-design-reviewer/scripts/breaking_change_detector.py:389-398 | engineering/skills/api-design-reviewer/scripts/breaking_change_detector.py:474-485 \u2014 both copies are in the same file, so extract the block 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 \u0060engineering/skills/api-design-reviewer/scripts/breaking_change_detector.py:389\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":"engineering/skills/api-design-reviewer/scripts/breaking_change_detector.py"},"region":{"startLine":389}}}],"partialFingerprints":{"codehealthFindingId/v1":"00ebdf2f71649881e549841f211bb3f5a5ce29c08f62d96c9bb90f6861ccca34"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (10 lines \u00D7 2): engineering/skills/api-design-reviewer/scripts/breaking_change_detector.py:513-522 | engineering/skills/api-design-reviewer/scripts/breaking_change_detector.py:562-572 \u2014 both copies are in the same file, so extract the block 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 \u0060engineering/skills/api-design-reviewer/scripts/breaking_change_detector.py:513\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":"engineering/skills/api-design-reviewer/scripts/breaking_change_detector.py"},"region":{"startLine":513}}}],"partialFingerprints":{"codehealthFindingId/v1":"dabd7fba63924cd37cd977aab495d33f24bee6037eb68224be3ab8ab2ce5212d"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (10 lines \u00D7 2): engineering/skills/slo-architect/scripts/slo_designer.py:107-116 | engineering/slo-architect/skills/slo-architect/scripts/slo_designer.py:107-116 \u2014 before extracting anything, compare \u0060engineering/skills/slo-architect/scripts/slo_designer.py\u0060 and \u0060engineering/slo-architect/skills/slo-architect/scripts/slo_designer.py\u0060 as WHOLE FILES: this scan already matched 8 separate duplicated blocks between them, totalling at least 70 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The \u0060return\u0060 at the foot of the matched lines is the enclosing body\u0027s own terminal exit, not an early one: it moves with them unchanged, and each site calls the extracted unit from the position that \u0060return\u0060 occupied \u2014 no decision has to be handed back and re-acted on."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/slo-architect/scripts/slo_designer.py"},"region":{"startLine":107}}}],"partialFingerprints":{"codehealthFindingId/v1":"05b058dbef3cb14013585d06649cd172e1d91fc791968b5fdb32df08157dc69d"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (10 lines \u00D7 2): engineering/skills/tc-tracker/scripts/tc_status.py:176-185 | engineering/skills/tc-tracker/scripts/tc_update.py:162-171 \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, \u0060engineering/skills/tc-tracker/scripts/tc_update.py:172\u0060 calls \u0060loads\u0060, \u0060read_text\u0060 and \u0060engineering/skills/tc-tracker/scripts/tc_status.py:186\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":"engineering/skills/tc-tracker/scripts/tc_status.py"},"region":{"startLine":176}}}],"partialFingerprints":{"codehealthFindingId/v1":"8ef2fa497c6dce5699f0f56715d05b44624e7d4a54194b7a0af68479122179a0"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (10 lines \u00D7 2): engineering/skills/tc-tracker/scripts/tc_validator.py:162-171 | engineering/skills/tc-tracker/scripts/tc_validator.py:197-206 \u2014 both copies are in the same file, so extract the block 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 \u0060engineering/skills/tc-tracker/scripts/tc_validator.py:162\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":"engineering/skills/tc-tracker/scripts/tc_validator.py"},"region":{"startLine":162}}}],"partialFingerprints":{"codehealthFindingId/v1":"dab38a6185eb5ddec9756e81da35589c220ab6905a6a366ebb5a009288f8c19a"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (10 lines \u00D7 2): engineering/skills/tech-debt-tracker/scripts/debt_prioritizer.py:789-798 | engineering/skills/tech-debt-tracker/scripts/debt_scanner.py:616-625 \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":"engineering/skills/tech-debt-tracker/scripts/debt_prioritizer.py"},"region":{"startLine":789}}}],"partialFingerprints":{"codehealthFindingId/v1":"693d3a9864ead5ef33c9b8b0210c45ce6f3d87a0b3d139e79840af4b6e2f2150"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (10 lines \u00D7 2): finance/skills/financial-analyst/scripts/budget_variance_analyzer.py:342-351 | finance/skills/financial-analyst/scripts/budget_variance_analyzer.py:353-362 \u2014 both copies are in the same file, so extract the block 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 \u0060finance/skills/financial-analyst/scripts/budget_variance_analyzer.py:342\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":"finance/skills/financial-analyst/scripts/budget_variance_analyzer.py"},"region":{"startLine":342}}}],"partialFingerprints":{"codehealthFindingId/v1":"3442fcc17186bfd9b9b5f252095db753c0de1a59864a28b6e88e4e30744bb01a"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9\u201310 lines \u00D7 2): markdown-html/skills/design-system/scripts/brand_palette_validator.py:204-212 | marketing/landing/skills/landing/scripts/brand_palette_validator.py:135-144 \u2014 before extracting anything, compare \u0060markdown-html/skills/design-system/scripts/brand_palette_validator.py\u0060 and \u0060marketing/landing/skills/landing/scripts/brand_palette_validator.py\u0060 as WHOLE FILES: this scan already matched 12 separate duplicated blocks between them, totalling at least 79 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"markdown-html/skills/design-system/scripts/brand_palette_validator.py"},"region":{"startLine":204}}}],"partialFingerprints":{"codehealthFindingId/v1":"f4434fa9dba994b8f3e5c78aca3cc7b9e52e31f682cc144b151a81ad1f0001c0"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9\u201310 lines \u00D7 2): markdown-html/skills/design-system/scripts/brand_palette_validator.py:233-241 | marketing/landing/skills/landing/scripts/brand_palette_validator.py:165-174 \u2014 before extracting anything, compare \u0060markdown-html/skills/design-system/scripts/brand_palette_validator.py\u0060 and \u0060marketing/landing/skills/landing/scripts/brand_palette_validator.py\u0060 as WHOLE FILES: this scan already matched 12 separate duplicated blocks between them, totalling at least 79 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"markdown-html/skills/design-system/scripts/brand_palette_validator.py"},"region":{"startLine":233}}}],"partialFingerprints":{"codehealthFindingId/v1":"70c0a617f341a87b888e01042c4adfed28305e52fc48e3b1218a934832bb89d0"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (10 lines \u00D7 2): markdown-html/skills/md-document/scripts/html_renderer.py:570-579 | markdown-html/skills/md-review/scripts/diff_parser.py:275-284 \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":"markdown-html/skills/md-document/scripts/html_renderer.py"},"region":{"startLine":570}}}],"partialFingerprints":{"codehealthFindingId/v1":"702f66b3a28584a2b2c645453bf92463fc14fba9d5b1991dd30b3e25b3c08ec2"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (10 lines \u00D7 2): marketing-skill/skills/app-store-optimization/scripts/aso_scorer.py:126-135 | marketing-skill/skills/app-store-optimization/scripts/aso_scorer.py:146-155 \u2014 both copies are in the same file, so extract the block 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":"marketing-skill/skills/app-store-optimization/scripts/aso_scorer.py"},"region":{"startLine":126}}}],"partialFingerprints":{"codehealthFindingId/v1":"35630b0aa3bc6fe54d32563ff76446a76d94e138f7552d13f8a89d57e667051b"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (10 lines \u00D7 2): marketing-skill/skills/app-store-optimization/scripts/metadata_optimizer.py:517-526 | marketing-skill/skills/app-store-optimization/scripts/review_analyzer.py:568-577 \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 \u0060marketing-skill/skills/app-store-optimization/scripts/metadata_optimizer.py:517\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":"marketing-skill/skills/app-store-optimization/scripts/metadata_optimizer.py"},"region":{"startLine":517}}}],"partialFingerprints":{"codehealthFindingId/v1":"396c55faaa96306545d2428bd47d9d2122294728342b5d1fb48e87bf678f209d"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (10 lines \u00D7 2): product-team/research-summarizer/skills/research-summarizer/scripts/extract_citations.py:153-162 | product-team/research-summarizer/skills/research-summarizer/scripts/extract_citations.py:179-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. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"product-team/research-summarizer/skills/research-summarizer/scripts/extract_citations.py"},"region":{"startLine":153}}}],"partialFingerprints":{"codehealthFindingId/v1":"4f2ea5e0d7174291a7cca5c27227de4748902a55f3053ce4574d360a81bdb1e4"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9\u201310 lines \u00D7 2): productivity/email/skills/inbox-setup/scripts/kb_validator.py:239-248 | productivity/email/skills/inbox-triage/scripts/kb_reader.py:282-290 \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. \u2605 These copies have DRIFTED, and that is worth reading before extracting anything: just before the matched lines, \u0060productivity/email/skills/inbox-setup/scripts/kb_validator.py:237\u0060 calls \u0060add_argument\u0060 and \u0060productivity/email/skills/inbox-triage/scripts/kb_reader.py:281\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":"productivity/email/skills/inbox-setup/scripts/kb_validator.py"},"region":{"startLine":239}}}],"partialFingerprints":{"codehealthFindingId/v1":"fb0f7777a2a621156de2f7a99a57a3bd362596871e52281af2be24b2cddf4b39"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (10 lines \u00D7 2): productivity/email/skills/inbox-setup/scripts/section_progress_tracker.py:230-239 | research/litreview/skills/litreview/scripts/citation_tracker.py:235-244 \u2014 before extracting anything, compare \u0060productivity/email/skills/inbox-setup/scripts/section_progress_tracker.py\u0060 and \u0060research/litreview/skills/litreview/scripts/citation_tracker.py\u0060 as WHOLE FILES: this scan already matched 6 separate duplicated blocks between them, totalling at least 70 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. Read the line range as the matched WINDOW rather than a finished unit: at \u0060productivity/email/skills/inbox-setup/scripts/section_progress_tracker.py:230\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":"productivity/email/skills/inbox-setup/scripts/section_progress_tracker.py"},"region":{"startLine":230}}}],"partialFingerprints":{"codehealthFindingId/v1":"ca5a6e9e518edd2277088b9c4364212b61cc6496ac976555cc5ee1337814e9a6"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (10 lines \u00D7 2): project-management/skills/atlassian-admin/scripts/permission_audit_tool.py:405-414 | project-management/skills/confluence-expert/scripts/space_structure_generator.py:453-462 \u2014 the copies span different directories, so extracting a shared function means choosing where it lives: put it somewhere both call sites can already reach \u2014 a location they all depend on today, or a new shared one if there is none \u2014 and call it from each site; until then, every change has to be made twice. The \u0060return\u0060 at the foot of the matched lines is the enclosing body\u0027s own terminal exit, not an early one: it moves with them unchanged, and each site calls the extracted unit from the position that \u0060return\u0060 occupied \u2014 no decision has to be handed back and re-acted on."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"project-management/skills/atlassian-admin/scripts/permission_audit_tool.py"},"region":{"startLine":405}}}],"partialFingerprints":{"codehealthFindingId/v1":"a0a8a6c1f71bf93de090a4a509205ecbe431eb82a6ce766ff6e5d97956bde132"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (10 lines \u00D7 2): ra-qm-team/compliance-team-eu-ai-act/skills/eu-ai-act-specialist/scripts/ai_system_risk_classifier.py:260-269 | ra-qm-team/skills/eu-ai-act-specialist/scripts/ai_system_risk_classifier.py:260-269 \u2014 before extracting anything, compare \u0060ra-qm-team/compliance-team-eu-ai-act/skills/eu-ai-act-specialist/scripts/ai_system_risk_classifier.py\u0060 and \u0060ra-qm-team/skills/eu-ai-act-specialist/scripts/ai_system_risk_classifier.py\u0060 as WHOLE FILES: this scan already matched 7 separate duplicated blocks between them, totalling at least 156 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"ra-qm-team/compliance-team-eu-ai-act/skills/eu-ai-act-specialist/scripts/ai_system_risk_classifier.py"},"region":{"startLine":260}}}],"partialFingerprints":{"codehealthFindingId/v1":"56da15dcf153b46ecd91efab7dee09742ad24ef064d2bb05468201f29c66d2cf"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (10 lines \u00D7 2): ra-qm-team/compliance-team-iso42001/skills/iso42001-specialist/scripts/aims_audit_scheduler.py:188-197 | ra-qm-team/skills/iso42001-specialist/scripts/aims_audit_scheduler.py:188-197 \u2014 before extracting anything, compare \u0060ra-qm-team/compliance-team-iso42001/skills/iso42001-specialist/scripts/aims_audit_scheduler.py\u0060 and \u0060ra-qm-team/skills/iso42001-specialist/scripts/aims_audit_scheduler.py\u0060 as WHOLE FILES: this scan already matched 9 separate duplicated blocks between them, totalling at least 151 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"ra-qm-team/compliance-team-iso42001/skills/iso42001-specialist/scripts/aims_audit_scheduler.py"},"region":{"startLine":188}}}],"partialFingerprints":{"codehealthFindingId/v1":"f8e777c848aa1c0295db32ad108d5f872412c4f48f34e8d34b9bf686c0b4598e"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (10 lines \u00D7 2): scripts/check_model_freshness.py:194-203 | scripts/check_paths.py:187-196 \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 \u0060scripts/check_model_freshness.py:194\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":"scripts/check_model_freshness.py"},"region":{"startLine":194}}}],"partialFingerprints":{"codehealthFindingId/v1":"1297f301e51b394c3330a667a503dbd4088b0a691eff76b6e9eedb1f8d98fdae"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7\u201310 lines \u00D7 2): scripts/smoke_json_output.py:127-133 | scripts/smoke_scripts.py:80-89 \u2014 before extracting anything, compare \u0060scripts/smoke_json_output.py\u0060 and \u0060scripts/smoke_scripts.py\u0060 as WHOLE FILES: this scan already matched 3 separate duplicated blocks between them, totalling at least 33 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 \u0060scripts/smoke_json_output.py:127\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":"scripts/smoke_json_output.py"},"region":{"startLine":127}}}],"partialFingerprints":{"codehealthFindingId/v1":"1af26aac732d1bef598805adca47b4b5887ba6d5a033d8f92d5eabd2c612b91f"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9 lines \u00D7 7): commercial/skills/commercial-forecaster/scripts/funnel_confidence_scorer.py:129-137 | commercial/skills/pricing-strategist/scripts/wtp_analyzer.py:196-204 | engineering-team/skills/incident-commander/scripts/pir_generator.py:1324-1334 | engineering-team/skills/senior-architect/scripts/architecture_diagram_generator.py:415-424 | engineering-team/skills/tdd-guide/scripts/tdd_workflow.py:381-392 | engineering/handoff/skills/handoff/scripts/handoff_template_generator.py:149-157 | engineering/skillopt-sleep/skillopt_sleep/experiments/report.py:102-110 \u2014 the copies span different directories, so extracting a shared function means choosing where it lives: put it somewhere all 7 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 7 times. Read the line range as the matched WINDOW rather than a finished unit: at \u0060engineering-team/skills/senior-architect/scripts/architecture_diagram_generator.py:415\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":"commercial/skills/commercial-forecaster/scripts/funnel_confidence_scorer.py"},"region":{"startLine":129}}}],"partialFingerprints":{"codehealthFindingId/v1":"360f498df8778ccf6948fba7fbb86f88e6921b95b39e0d49d4b2c4a4e937ff84"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9 lines \u00D7 6): business-growth/skills/customer-success-manager/scripts/churn_risk_analyzer.py:463-471 | business-growth/skills/customer-success-manager/scripts/expansion_opportunity_scorer.py:390-398 | business-growth/skills/customer-success-manager/scripts/health_score_calculator.py:453-461 | marketing-skill/skills/campaign-analytics/scripts/attribution_analyzer.py:310-318 | marketing-skill/skills/campaign-analytics/scripts/campaign_roi_calculator.py:426-434 | marketing-skill/skills/campaign-analytics/scripts/funnel_analyzer.py:263-271 \u2014 the copies span different directories, so extracting a shared function means choosing where it lives: put it somewhere all 6 call sites can already reach \u2014 a location they all depend on today, or a new shared one if there is none \u2014 and call it from each site; until then, every change has to be made 6 times."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"business-growth/skills/customer-success-manager/scripts/churn_risk_analyzer.py"},"region":{"startLine":463}}}],"partialFingerprints":{"codehealthFindingId/v1":"41c0462e9f306e696b5879f9ffe739490b5f9dc732264a01d94d9b3d37805720"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9 lines \u00D7 6): engineering/grill-with-docs/skills/grill-with-docs/scripts/adr_scanner.py:180-188 | engineering/grill-with-docs/skills/grill-with-docs/scripts/context_md_linter.py:218-226 | marketing/landing/skills/landing/scripts/brand_palette_validator.py:208-216 | marketing/landing/skills/landing/scripts/html_validator.py:241-249 | productivity/email/skills/inbox-setup/scripts/kb_validator.py:197-205 | productivity/reflect/skills/reflect/scripts/directional_recommendation_validator.py:168-176 \u2014 the copies span different directories, so extracting a shared function means choosing where it lives: put it somewhere all 6 call sites can already reach \u2014 a location they all depend on today, or a new shared one if there is none \u2014 and call it from each site; until then, every change has to be made 6 times. Note first that the copies are not typed on the same thing: the declarations holding them bind \u0060findings\u0060 to \u0060List[Dict[str, Any]]\u0060 in one and \u0060List[Dict[str, str]]\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":"engineering/grill-with-docs/skills/grill-with-docs/scripts/adr_scanner.py"},"region":{"startLine":180}}}],"partialFingerprints":{"codehealthFindingId/v1":"8bcdeb35b14516efda402dbfbf15b714adff9da5f06868f9e4209d15b88804b2"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9 lines \u00D7 6): engineering/skills/tech-debt-tracker/scripts/debt_dashboard.py:946-954 | engineering/skills/tech-debt-tracker/scripts/debt_dashboard.py:958-966 | engineering/skills/tech-debt-tracker/scripts/debt_prioritizer.py:833-841 | engineering/skills/tech-debt-tracker/scripts/debt_prioritizer.py:845-853 | engineering/skills/tech-debt-tracker/scripts/debt_scanner.py:660-668 | engineering/skills/tech-debt-tracker/scripts/debt_scanner.py:672-680 \u2014 there are 6 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 6 sites; resolving a subset leaves the remainder to drift apart."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/tech-debt-tracker/scripts/debt_dashboard.py"},"region":{"startLine":946}}}],"partialFingerprints":{"codehealthFindingId/v1":"6589f5a511e28f50fde831ce0aea806353e5cc3bf04734212f38ca4de5d27182"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9 lines \u00D7 4): engineering-team/skills/senior-architect/scripts/project_architect.py:198-206 | engineering-team/skills/senior-architect/scripts/project_architect.py:237-245 | engineering-team/skills/senior-architect/scripts/project_architect.py:275-283 | engineering-team/skills/senior-architect/scripts/project_architect.py:394-402 \u2014 all 4 copies are in the same file, so extract the block into one function there and call it from every one of those sites \u2014 resolving only two of them leaves the rest to drift apart the first time one is edited. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/skills/senior-architect/scripts/project_architect.py"},"region":{"startLine":198}}}],"partialFingerprints":{"codehealthFindingId/v1":"846549cf77b1494748aa72b36376c934634b9fe7db086e4b11ea3c48205bd52c"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9 lines \u00D7 4): engineering/skills/database-designer/schema_analyzer.py:844-852 | engineering/skills/dependency-auditor/scripts/dep_scanner.py:734-742 | engineering/skills/dependency-auditor/scripts/license_checker.py:930-938 | engineering/skills/dependency-auditor/scripts/upgrade_planner.py:950-958 \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."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/database-designer/schema_analyzer.py"},"region":{"startLine":844}}}],"partialFingerprints":{"codehealthFindingId/v1":"014fcac73c17a59fcb64f25801913584c25e0defe6fbc629f16790756b43390f"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9 lines \u00D7 4): finance/skills/stock-analysis/scripts/ratios.py:1375-1383 | finance/skills/stock-analysis/scripts/ratios.py:1393-1401 | finance/skills/stock-analysis/scripts/ratios.py:1438-1447 | finance/skills/stock-analysis/scripts/ratios.py:1575-1583 \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 \u0060finance/skills/stock-analysis/scripts/ratios.py:1375\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":"finance/skills/stock-analysis/scripts/ratios.py"},"region":{"startLine":1375}}}],"partialFingerprints":{"codehealthFindingId/v1":"6d3962081dde8fe0d3e1fb0147c49de177da2f17d987fa62305673ece49833c6"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9 lines \u00D7 3): business-growth/skills/revenue-operations/scripts/forecast_accuracy_tracker.py:408-417 | project-management/skills/confluence-expert/scripts/space_structure_generator.py:418-426 | project-management/skills/jira-expert/scripts/workflow_validator.py:322-331 \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":"business-growth/skills/revenue-operations/scripts/forecast_accuracy_tracker.py"},"region":{"startLine":408}}}],"partialFingerprints":{"codehealthFindingId/v1":"df63db6e2639c9eef2b4288ce9ace8ed293e208a61d09212a3d1f82dd56334cc"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9 lines \u00D7 3): business-growth/skills/revenue-operations/scripts/forecast_accuracy_tracker.py:508-516 | business-growth/skills/revenue-operations/scripts/gtm_efficiency_calculator.py:630-638 | business-growth/skills/revenue-operations/scripts/pipeline_analyzer.py:501-509 \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":"business-growth/skills/revenue-operations/scripts/forecast_accuracy_tracker.py"},"region":{"startLine":508}}}],"partialFingerprints":{"codehealthFindingId/v1":"18385bc2f472709245040fba21ad5ee94db9ede116b526922f673605db5dc0d1"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9 lines \u00D7 3): business-growth/skills/sales-engineer/scripts/poc_planner.py:657-665 | business-growth/skills/sales-engineer/scripts/poc_planner.py:688-696 | business-growth/skills/sales-engineer/scripts/rfp_response_analyzer.py:496-504 \u2014 there are 3 copies across 2 file(s) \u2014 more copies than files, so at least one file holds the block twice. Extract it once into a single shared function every call site can reach and call it from all 3 sites; resolving a subset leaves the remainder to drift apart."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"business-growth/skills/sales-engineer/scripts/poc_planner.py"},"region":{"startLine":657}}}],"partialFingerprints":{"codehealthFindingId/v1":"74c69e1589985ba5721912783c4e4b7b3c6baa7e9a0a0941cd06709bc571db9d"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9 lines \u00D7 3): business-operations/skills/vendor-management/scripts/sla_compliance_tracker.py:320-328 | business-operations/skills/vendor-management/scripts/vendor_risk_classifier.py:350-358 | business-operations/skills/vendor-management/scripts/vendor_scorer.py:409-417 \u2014 the copies sit in sibling files of one directory, so a shared home is within easy reach: extract the block into a single shared function the call sites can all reach \u2014 a file they already depend on, or a new one alongside them \u2014 and call it from all 3 call sites, so a change lands once. Read the line range as the matched WINDOW rather than a finished unit: at \u0060business-operations/skills/vendor-management/scripts/sla_compliance_tracker.py:320\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":"business-operations/skills/vendor-management/scripts/sla_compliance_tracker.py"},"region":{"startLine":320}}}],"partialFingerprints":{"codehealthFindingId/v1":"2ef8a106e597263779ca930ef3bb2097295a56450b16ba10b7c91947486c55a9"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9 lines \u00D7 3): compliance-os/skills/compliance-os/scripts/audit_simulator.py:349-357 | ra-qm-team/compliance-team-eu-ai-act/skills/eu-ai-act-specialist/scripts/conformity_assessment_planner.py:260-269 | ra-qm-team/skills/eu-ai-act-specialist/scripts/conformity_assessment_planner.py:260-269 \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":"compliance-os/skills/compliance-os/scripts/audit_simulator.py"},"region":{"startLine":349}}}],"partialFingerprints":{"codehealthFindingId/v1":"2e3b0f6c9a3cbed885e5f1fcc74fa6abf5d67f62991b1925008dd3a270e5df72"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9 lines \u00D7 3): engineering-team/skills/code-reviewer/scripts/pr_analyzer.py:522-530 | engineering-team/skills/senior-fullstack/scripts/code_quality_analyzer.py:674-682 | ra-qm-team/skills/gdpr-dsgvo-expert/scripts/gdpr_compliance_checker.py:426-434 \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":"engineering-team/skills/code-reviewer/scripts/pr_analyzer.py"},"region":{"startLine":522}}}],"partialFingerprints":{"codehealthFindingId/v1":"1e1eaf8cf7ef8254b83d5ea490ad11f414583339beb09c9965e3d91498216986"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9 lines \u00D7 3): engineering/docker-development/skills/docker-development/scripts/dockerfile_analyzer.py:330-344 | engineering/helm-chart-builder/skills/helm-chart-builder/scripts/chart_analyzer.py:431-439 | engineering/helm-chart-builder/skills/helm-chart-builder/scripts/values_validator.py:355-363 \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":"engineering/docker-development/skills/docker-development/scripts/dockerfile_analyzer.py"},"region":{"startLine":330}}}],"partialFingerprints":{"codehealthFindingId/v1":"3631a1b52e7f1bfdd6c9cd70f0cb4325214a0d1d55aa08a1eb0c150e841e7390"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9 lines \u00D7 3): engineering/grill-me/skills/grill-me/scripts/decision_tree_extractor.py:106-114 | engineering/grill-me/skills/grill-me/scripts/question_generator.py:97-105 | engineering/handoff/skills/handoff/scripts/artifact_deduplicator.py:168-176 \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":"engineering/grill-me/skills/grill-me/scripts/decision_tree_extractor.py"},"region":{"startLine":106}}}],"partialFingerprints":{"codehealthFindingId/v1":"28e0644df571676cf4cdd4edbf58e354534ecd977bf16fee59b525f5f7137ba7"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9 lines \u00D7 3): engineering/grill-with-docs/skills/grill-with-docs/scripts/context_md_linter.py:253-261 | productivity/capture/skills/capture/scripts/complexity_estimator.py:166-174 | productivity/capture/skills/capture/scripts/dump_classifier.py:138-146 \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. Read the line range as the matched WINDOW rather than a finished unit: at \u0060engineering/grill-with-docs/skills/grill-with-docs/scripts/context_md_linter.py:253\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":"engineering/grill-with-docs/skills/grill-with-docs/scripts/context_md_linter.py"},"region":{"startLine":253}}}],"partialFingerprints":{"codehealthFindingId/v1":"393660a7898dc1f93c08d0145e733ffc7e537a0055d1e937d1206161ed0aeba3"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9 lines \u00D7 3): engineering/skills/database-designer/index_optimizer.py:800-808 | engineering/skills/database-designer/migration_generator.py:1079-1087 | engineering/skills/database-designer/schema_analyzer.py:833-841 \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":"engineering/skills/database-designer/index_optimizer.py"},"region":{"startLine":800}}}],"partialFingerprints":{"codehealthFindingId/v1":"cb992facf2e80e16f25dce4dd157213d590156aee3032c3aa2ad0e96c96125f1"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9 lines \u00D7 3): productivity/andreessen/skills/andreessen/scripts/market_first_evaluator.py:149-157 | productivity/andreessen/skills/andreessen/scripts/pmf_signal_scorer.py:157-165 | productivity/roast/skills/roast/scripts/verdict_synthesizer.py:193-201 \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":"productivity/andreessen/skills/andreessen/scripts/market_first_evaluator.py"},"region":{"startLine":149}}}],"partialFingerprints":{"codehealthFindingId/v1":"d94886cf86688216d1293f20f61dde0d1391c706d444b0e0e35d098cdb8b82fb"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (8\u20139 lines \u00D7 3): ra-qm-team/skills/fda-consultant-specialist/scripts/hipaa_risk_assessment.py:269-277 | ra-qm-team/skills/fda-consultant-specialist/scripts/hipaa_risk_assessment.py:299-306 | ra-qm-team/skills/fda-consultant-specialist/scripts/hipaa_risk_assessment.py:333-340 \u2014 all 3 copies are in the same file, so extract the block into one function there and call it from every one of those sites \u2014 resolving only two of them leaves the rest to drift apart the first time one is edited. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"ra-qm-team/skills/fda-consultant-specialist/scripts/hipaa_risk_assessment.py"},"region":{"startLine":269}}}],"partialFingerprints":{"codehealthFindingId/v1":"fa129506816573195b610f83a1330908bb3f5b6aedffa61a8952d536cee7fd48"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9 lines \u00D7 2): business-growth/skills/revenue-operations/scripts/forecast_accuracy_tracker.py:422-430 | business-growth/skills/revenue-operations/scripts/forecast_accuracy_tracker.py:434-442 \u2014 both copies are in the same file, so extract the block 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, \u0060business-growth/skills/revenue-operations/scripts/forecast_accuracy_tracker.py:444\u0060 calls \u0060get\u0060 and \u0060business-growth/skills/revenue-operations/scripts/forecast_accuracy_tracker.py:432\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":"business-growth/skills/revenue-operations/scripts/forecast_accuracy_tracker.py"},"region":{"startLine":422}}}],"partialFingerprints":{"codehealthFindingId/v1":"9b93d3b55ead7cfa252f1be267badfb21e802af5ac52ba952d7c6f0bc800b5e0"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9 lines \u00D7 2): business-growth/skills/sales-engineer/scripts/poc_planner.py:678-686 | business-growth/skills/sales-engineer/scripts/rfp_response_analyzer.py:487-495 \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":"business-growth/skills/sales-engineer/scripts/poc_planner.py"},"region":{"startLine":678}}}],"partialFingerprints":{"codehealthFindingId/v1":"91d7821fdb172db2127c71bbf66ca9b1e7c176b1e20f77f8e2d665573b16bc7d"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9 lines \u00D7 2): c-level-advisor/arquiteto-de-empresa/skills/arquiteto-de-empresa/scripts/index_generator.py:32-40 | c-level-advisor/skills/arquiteto-de-empresa/scripts/index_generator.py:32-40 \u2014 before extracting anything, compare \u0060c-level-advisor/arquiteto-de-empresa/skills/arquiteto-de-empresa/scripts/index_generator.py\u0060 and \u0060c-level-advisor/skills/arquiteto-de-empresa/scripts/index_generator.py\u0060 as WHOLE FILES: this scan already matched 10 separate duplicated blocks between them, totalling at least 135 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"c-level-advisor/arquiteto-de-empresa/skills/arquiteto-de-empresa/scripts/index_generator.py"},"region":{"startLine":32}}}],"partialFingerprints":{"codehealthFindingId/v1":"64b6c8712767cd152e69fb2bb6d99d1c27cdcbda72b6c81ba6c39d22ab5609f8"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9 lines \u00D7 2): c-level-advisor/chief-customer-officer-advisor/skills/chief-customer-officer-advisor/scripts/customer_segmentation_designer.py:274-282 | c-level-advisor/skills/chief-customer-officer-advisor/scripts/customer_segmentation_designer.py:274-282 \u2014 before extracting anything, compare \u0060c-level-advisor/chief-customer-officer-advisor/skills/chief-customer-officer-advisor/scripts/customer_segmentation_designer.py\u0060 and \u0060c-level-advisor/skills/chief-customer-officer-advisor/scripts/customer_segmentation_designer.py\u0060 as WHOLE FILES: this scan already matched 11 separate duplicated blocks between them, totalling at least 146 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"c-level-advisor/chief-customer-officer-advisor/skills/chief-customer-officer-advisor/scripts/customer_segmentation_designer.py"},"region":{"startLine":274}}}],"partialFingerprints":{"codehealthFindingId/v1":"6fb2c44bf7fd4410e6dca1af5e3d1ed239d977f3100309f77b1d7e70545005e2"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9 lines \u00D7 2): c-level-advisor/chief-data-officer-advisor/skills/chief-data-officer-advisor/scripts/data_asset_valuator.py:284-292 | c-level-advisor/skills/chief-data-officer-advisor/scripts/data_asset_valuator.py:284-292 \u2014 before extracting anything, compare \u0060c-level-advisor/chief-data-officer-advisor/skills/chief-data-officer-advisor/scripts/data_asset_valuator.py\u0060 and \u0060c-level-advisor/skills/chief-data-officer-advisor/scripts/data_asset_valuator.py\u0060 as WHOLE FILES: this scan already matched 12 separate duplicated blocks between them, totalling at least 283 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"c-level-advisor/chief-data-officer-advisor/skills/chief-data-officer-advisor/scripts/data_asset_valuator.py"},"region":{"startLine":284}}}],"partialFingerprints":{"codehealthFindingId/v1":"b0271243f67c3c2911969452ecf8fe09cfcd15873d2e516d339319968bdf003b"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9 lines \u00D7 2): c-level-advisor/skills/cpo-advisor/scripts/pmf_scorer.py:194-202 | c-level-advisor/skills/cpo-advisor/scripts/pmf_scorer.py:223-231 \u2014 both copies are in the same file, so extract the block 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":"c-level-advisor/skills/cpo-advisor/scripts/pmf_scorer.py"},"region":{"startLine":194}}}],"partialFingerprints":{"codehealthFindingId/v1":"30f21de4b0e6d53841b70b6c7cdcc18843f133595c3c5d8f701646be7b0eee9a"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9 lines \u00D7 2): c-level-advisor/skills/vpe-advisor/scripts/delivery_throughput_analyzer.py:229-237 | c-level-advisor/vpe-advisor/skills/vpe-advisor/scripts/delivery_throughput_analyzer.py:229-237 \u2014 before extracting anything, compare \u0060c-level-advisor/skills/vpe-advisor/scripts/delivery_throughput_analyzer.py\u0060 and \u0060c-level-advisor/vpe-advisor/skills/vpe-advisor/scripts/delivery_throughput_analyzer.py\u0060 as WHOLE FILES: this scan already matched 12 separate duplicated blocks between them, totalling at least 119 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"c-level-advisor/skills/vpe-advisor/scripts/delivery_throughput_analyzer.py"},"region":{"startLine":229}}}],"partialFingerprints":{"codehealthFindingId/v1":"539b07d01ccab95725e0eee7ce95dafc94ed966a10648bf06098842d8e66435b"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9 lines \u00D7 2): commercial/skills/commercial-forecaster/scripts/funnel_confidence_scorer.py:123-131 | engineering/handoff/skills/handoff/scripts/handoff_template_generator.py:121-129 \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":"commercial/skills/commercial-forecaster/scripts/funnel_confidence_scorer.py"},"region":{"startLine":123}}}],"partialFingerprints":{"codehealthFindingId/v1":"7d640d1b57c2259f6baf72ff84a737b013e6224c28508f01a5ba517ca12217a4"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (8\u20139 lines \u00D7 2): engineering-team/skills/senior-backend/scripts/backend_decision_engine.py:300-308 | engineering/deep-learning-book/skills/deep-learning-book/scripts/capacity_planner.py:200-207 \u2014 the copies span different directories, so extracting a shared function means choosing where it lives: put it somewhere both call sites can already reach \u2014 a location they all depend on today, or a new shared one if there is none \u2014 and call it from each site; until then, every change has to be made twice. Read the line range as the matched WINDOW rather than a finished unit: at \u0060engineering-team/skills/senior-backend/scripts/backend_decision_engine.py:300\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":"engineering-team/skills/senior-backend/scripts/backend_decision_engine.py"},"region":{"startLine":300}}}],"partialFingerprints":{"codehealthFindingId/v1":"2c3de81f48b4c3b3f5302130a59a1f2f26d667b5db42a3730bbe8ffbdcb22185"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9 lines \u00D7 2): engineering-team/skills/senior-computer-vision/scripts/dataset_pipeline_builder.py:1648-1659 | ra-qm-team/skills/gdpr-dsgvo-expert/scripts/data_subject_rights_tracker.py:533-541 \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 \u0060engineering-team/skills/senior-computer-vision/scripts/dataset_pipeline_builder.py:1648\u0060 it begins part-way through the construct above it, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that. Note that the copies do not run to the end of the range shown: their LAST lines are different code, not the same code under different names \u2014 the matched region ends inside that line. Extract the lines above it, and read the last line of each site separately."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/skills/senior-computer-vision/scripts/dataset_pipeline_builder.py"},"region":{"startLine":1648}}}],"partialFingerprints":{"codehealthFindingId/v1":"333b5a83232e314867fc8dcd013531c7ed9e3a16dfe6732585e662ae5ab35980"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9 lines \u00D7 2): engineering-team/skills/senior-prompt-engineer/scripts/agent_orchestrator.py:340-348 | engineering-team/skills/senior-prompt-engineer/scripts/agent_orchestrator.py:351-359 \u2014 both copies are in the same file, so extract the block into one function there and call it from each site \u2014 the copies drift apart the first time only one of them is edited."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/skills/senior-prompt-engineer/scripts/agent_orchestrator.py"},"region":{"startLine":340}}}],"partialFingerprints":{"codehealthFindingId/v1":"c4b20f13134042d1f118bf35430994d0e616f857fd9e39978c43bf5644c03aeb"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9 lines \u00D7 2): engineering-team/skills/senior-secops/scripts/security_scanner.py:184-192 | engineering-team/skills/senior-secops/scripts/vulnerability_assessor.py:208-216 \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 \u0060engineering-team/skills/senior-secops/scripts/vulnerability_assessor.py:208\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":"engineering-team/skills/senior-secops/scripts/security_scanner.py"},"region":{"startLine":184}}}],"partialFingerprints":{"codehealthFindingId/v1":"c7bc1026d70d0ac54a5cbb63a3af81375efc06b41215f7ff8782637d488081a5"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9 lines \u00D7 2): engineering/agent-harness/skills/agent-harness/scripts/loop_controller.py:58-66 | productivity/deep-work/skills/deep-work/scripts/focus_session_logger.py:70-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."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/agent-harness/skills/agent-harness/scripts/loop_controller.py"},"region":{"startLine":58}}}],"partialFingerprints":{"codehealthFindingId/v1":"c37fd2e4aa75162a3e5e560ce9d05bfd2352a9436a79924c105c79ddb85cd345"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (8\u20139 lines \u00D7 2): engineering/book-to-skill/skills/book-to-skill/scripts/book_skill_validator.py:576-584 | engineering/book-to-skill/skills/book-to-skill/scripts/skill_plugin_emitter.py:569-576 \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 \u0060engineering/book-to-skill/skills/book-to-skill/scripts/book_skill_validator.py:576\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":"engineering/book-to-skill/skills/book-to-skill/scripts/book_skill_validator.py"},"region":{"startLine":576}}}],"partialFingerprints":{"codehealthFindingId/v1":"f1239d616fe414c4e096298c29be5930070803feee5b7bcdda676583b51600bd"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9 lines \u00D7 2): engineering/claude-coach/skills/claude-coach/scripts/coach_tip_classifier.py:189-197 | engineering/claude-coach/skills/claude-coach/scripts/prompt_rater.py:160-168 \u2014 the copies sit in sibling files of one directory, so a shared home is within easy reach: extract the block into a single shared function the call sites can all reach \u2014 a file they already depend on, or a new one alongside them \u2014 and call it from both call sites, so a change lands once. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it. \u2605 These copies have DRIFTED, and that is worth reading before extracting anything: just before the matched lines, \u0060engineering/claude-coach/skills/claude-coach/scripts/coach_tip_classifier.py:188\u0060 calls \u0060add_argument\u0060 and \u0060engineering/claude-coach/skills/claude-coach/scripts/prompt_rater.py:159\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":"engineering/claude-coach/skills/claude-coach/scripts/coach_tip_classifier.py"},"region":{"startLine":189}}}],"partialFingerprints":{"codehealthFindingId/v1":"9ec91257510f5e4f38111a9f055cb325307311c1c017562f0f58070be7ed6606"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9 lines \u00D7 2): engineering/feature-flags-architect/skills/feature-flags-architect/scripts/flag_debt_scanner.py:102-110 | engineering/skills/feature-flags-architect/scripts/flag_debt_scanner.py:102-110 \u2014 before extracting anything, compare \u0060engineering/feature-flags-architect/skills/feature-flags-architect/scripts/flag_debt_scanner.py\u0060 and \u0060engineering/skills/feature-flags-architect/scripts/flag_debt_scanner.py\u0060 as WHOLE FILES: this scan already matched 7 separate duplicated blocks between them, totalling at least 77 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/feature-flags-architect/skills/feature-flags-architect/scripts/flag_debt_scanner.py"},"region":{"startLine":102}}}],"partialFingerprints":{"codehealthFindingId/v1":"be86c7d2da06cc2b891aaa4e127d90b6331c0a7c8e8e0b68b50bc0f43a5f6d4a"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9 lines \u00D7 2): engineering/human-gate/skills/human-gate/scripts/human_gate.py:577-585 | engineering/human-gate/skills/human-gate/scripts/human_gate.py:606-614 \u2014 both copies are in the same file, so extract the block into one function there and call it from each site \u2014 the copies drift apart the first time only one of them is edited. \u2605 These copies have DRIFTED, and that is worth reading before extracting anything: just after the matched lines, \u0060engineering/human-gate/skills/human-gate/scripts/human_gate.py:616\u0060 calls \u0060open\u0060, \u0060write\u0060 and \u0060engineering/human-gate/skills/human-gate/scripts/human_gate.py:587\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":"engineering/human-gate/skills/human-gate/scripts/human_gate.py"},"region":{"startLine":577}}}],"partialFingerprints":{"codehealthFindingId/v1":"f9e79f7d671f92c40b778d292f6b0aa6f269e3b80b4b70e064d7bf02af32ce6f"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9 lines \u00D7 2): engineering/kubernetes-operator/skills/kubernetes-operator/scripts/crd_validator.py:84-92 | engineering/skills/kubernetes-operator/scripts/crd_validator.py:84-92 \u2014 before extracting anything, compare \u0060engineering/kubernetes-operator/skills/kubernetes-operator/scripts/crd_validator.py\u0060 and \u0060engineering/skills/kubernetes-operator/scripts/crd_validator.py\u0060 as WHOLE FILES: this scan already matched 8 separate duplicated blocks between them, totalling at least 79 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/kubernetes-operator/skills/kubernetes-operator/scripts/crd_validator.py"},"region":{"startLine":84}}}],"partialFingerprints":{"codehealthFindingId/v1":"5eec4e5338f26aecf8b3776f85537af097d434a97c65c7899fdf21cefe62d3a0"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9 lines \u00D7 2): engineering/kubernetes-operator/skills/kubernetes-operator/scripts/reconcile_lint.py:147-155 | engineering/skills/kubernetes-operator/scripts/reconcile_lint.py:147-155 \u2014 before extracting anything, compare \u0060engineering/kubernetes-operator/skills/kubernetes-operator/scripts/reconcile_lint.py\u0060 and \u0060engineering/skills/kubernetes-operator/scripts/reconcile_lint.py\u0060 as WHOLE FILES: this scan already matched 9 separate duplicated blocks between them, totalling at least 127 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/kubernetes-operator/skills/kubernetes-operator/scripts/reconcile_lint.py"},"region":{"startLine":147}}}],"partialFingerprints":{"codehealthFindingId/v1":"66758e4bcaa8aad55379bf4bf32fbea32f52c615696c3cac054000e6d57becd2"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7\u20139 lines \u00D7 2): engineering/llm-wiki/skills/llm-wiki/scripts/update_index.py:69-77 | engineering/llm-wiki/skills/llm-wiki/scripts/wiki_search.py:47-53 \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":"engineering/llm-wiki/skills/llm-wiki/scripts/update_index.py"},"region":{"startLine":69}}}],"partialFingerprints":{"codehealthFindingId/v1":"9cecc792b351c3897bbd930be656db512d326f1292abd0115169575c23ef03a0"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9 lines \u00D7 2): engineering/skills/agent-designer/agent_evaluator.py:1172-1184 | engineering/skills/agent-designer/tool_schema_generator.py:934-942 \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":"engineering/skills/agent-designer/agent_evaluator.py"},"region":{"startLine":1172}}}],"partialFingerprints":{"codehealthFindingId/v1":"5f62e34d8e94c41fca6d71a7acc78c8f3528e06c6a1df3351c255010e11b9339"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9 lines \u00D7 2): engineering/skills/api-design-reviewer/scripts/api_linter.py:443-451 | engineering/skills/api-design-reviewer/scripts/api_linter.py:454-462 \u2014 both copies are in the same file, so extract the block into one function there and call it from each site \u2014 the copies drift apart the first time only one of them is edited."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/api-design-reviewer/scripts/api_linter.py"},"region":{"startLine":443}}}],"partialFingerprints":{"codehealthFindingId/v1":"76551b062c1bfbfcf034b3cd26f0a20cc78d608a562fca66224bc00f006e2abe"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9 lines \u00D7 2): engineering/skills/api-design-reviewer/scripts/api_linter.py:487-495 | engineering/skills/api-design-reviewer/scripts/api_linter.py:500-508 \u2014 both copies are in the same file, so extract the block 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":"engineering/skills/api-design-reviewer/scripts/api_linter.py"},"region":{"startLine":487}}}],"partialFingerprints":{"codehealthFindingId/v1":"0c95c9c13ef1f2ffd48fc56969e891fd799855ca1e67fed6446e1ae4fd6bfbd4"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9 lines \u00D7 2): engineering/skills/api-design-reviewer/scripts/api_linter.py:579-587 | engineering/skills/api-design-reviewer/scripts/api_linter.py:591-599 \u2014 both copies are in the same file, so extract the block 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, \u0060engineering/skills/api-design-reviewer/scripts/api_linter.py:575\u0060 calls \u0060get\u0060 and \u0060engineering/skills/api-design-reviewer/scripts/api_linter.py:587\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":"engineering/skills/api-design-reviewer/scripts/api_linter.py"},"region":{"startLine":579}}}],"partialFingerprints":{"codehealthFindingId/v1":"d7f11afd244eb5820ce2919d18bcab3bf704ed307a134ac8be829845fe464d64"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9 lines \u00D7 2): engineering/skills/api-design-reviewer/scripts/api_scorecard.py:1164-1172 | engineering/skills/api-design-reviewer/scripts/api_scorecard.py:1349-1357 \u2014 both copies are in the same file, so extract the block 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":"engineering/skills/api-design-reviewer/scripts/api_scorecard.py"},"region":{"startLine":1164}}}],"partialFingerprints":{"codehealthFindingId/v1":"a07dfaacf372e6bd5e935dd315a9c7bcf46e434a7dd4a78510c3a8835424126c"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9 lines \u00D7 2): engineering/skills/database-designer/index_optimizer.py:823-831 | engineering/skills/database-designer/schema_analyzer.py:892-900 \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":"engineering/skills/database-designer/index_optimizer.py"},"region":{"startLine":823}}}],"partialFingerprints":{"codehealthFindingId/v1":"5819d0342ec8f0fc7f686b518fac7577075e681c0e401e1076d4bb8e97e09c17"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9 lines \u00D7 2): engineering/skills/database-designer/schema_analyzer.py:852-860 | engineering/skills/database-designer/schema_analyzer.py:878-886 \u2014 both copies are in the same file, so extract the block 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 \u0060engineering/skills/database-designer/schema_analyzer.py:852\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":"engineering/skills/database-designer/schema_analyzer.py"},"region":{"startLine":852}}}],"partialFingerprints":{"codehealthFindingId/v1":"824e5b7c08321fbea62ecabdfa637810cac8706c4d17078ee3c810663999d44d"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9 lines \u00D7 2): engineering/skills/database-designer/schema_analyzer.py:862-870 | engineering/skills/database-designer/schema_analyzer.py:888-896 \u2014 both copies are in the same file, so extract the block 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":"engineering/skills/database-designer/schema_analyzer.py"},"region":{"startLine":862}}}],"partialFingerprints":{"codehealthFindingId/v1":"d3cdd416524ad52c35f075c64678af50a798901cea7df17f6e6dc66a4059dbac"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9 lines \u00D7 2): engineering/skills/database-designer/schema_analyzer.py:865-873 | engineering/skills/database-designer/schema_analyzer.py:876-884 \u2014 both copies are in the same file, so extract the block 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":"engineering/skills/database-designer/schema_analyzer.py"},"region":{"startLine":865}}}],"partialFingerprints":{"codehealthFindingId/v1":"2b13ecde5c8fa49c92069de355e395fa561e41c04e482b8cd176d2e13e4a7ee3"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9 lines \u00D7 2): engineering/skills/migration-architect/scripts/compatibility_checker.py:393-401 | engineering/skills/migration-architect/scripts/compatibility_checker.py:465-473 \u2014 both copies are in the same file, so extract the block 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 \u0060engineering/skills/migration-architect/scripts/compatibility_checker.py:393\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":"engineering/skills/migration-architect/scripts/compatibility_checker.py"},"region":{"startLine":393}}}],"partialFingerprints":{"codehealthFindingId/v1":"3c374050e388ac9549c2c68e184234b75b310edd341684602fca401d82488678"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9 lines \u00D7 2): engineering/skills/slo-architect/scripts/error_budget_calculator.py:115-123 | engineering/slo-architect/skills/slo-architect/scripts/error_budget_calculator.py:115-123 \u2014 before extracting anything, compare \u0060engineering/skills/slo-architect/scripts/error_budget_calculator.py\u0060 and \u0060engineering/slo-architect/skills/slo-architect/scripts/error_budget_calculator.py\u0060 as WHOLE FILES: this scan already matched 7 separate duplicated blocks between them, totalling at least 89 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/slo-architect/scripts/error_budget_calculator.py"},"region":{"startLine":115}}}],"partialFingerprints":{"codehealthFindingId/v1":"fa2ad9479d0619fd032e8b217691826dde9d095d4e4757375bdaa9622e5a038b"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9 lines \u00D7 2): engineering/skills/tc-tracker/scripts/tc_status.py:28-36 | engineering/skills/tc-tracker/scripts/tc_update.py:74-82 \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":"engineering/skills/tc-tracker/scripts/tc_status.py"},"region":{"startLine":28}}}],"partialFingerprints":{"codehealthFindingId/v1":"278d4eaf51b0362f6ea7c11fdfed5421f956688a675c543b702cc3cefc7eb11c"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (4\u20139 lines \u00D7 3): engineering/write-a-skill/skills/write-a-skill/scripts/skill_description_validator.py:205-213 | engineering/write-a-skill/skills/write-a-skill/scripts/skill_review_checklist_runner.py:226-229 | engineering/write-a-skill/skills/write-a-skill/scripts/skill_structure_validator.py:233-241 \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":"engineering/write-a-skill/skills/write-a-skill/scripts/skill_description_validator.py"},"region":{"startLine":205}}}],"partialFingerprints":{"codehealthFindingId/v1":"14f0b794fad3732423117736695308c770d82482272a6795ba230f5131be05cf"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9 lines \u00D7 2): markdown-html/skills/design-system/scripts/brand_palette_validator.py:304-312 | marketing/landing/skills/landing/scripts/brand_palette_validator.py:240-248 \u2014 before extracting anything, compare \u0060markdown-html/skills/design-system/scripts/brand_palette_validator.py\u0060 and \u0060marketing/landing/skills/landing/scripts/brand_palette_validator.py\u0060 as WHOLE FILES: this scan already matched 12 separate duplicated blocks between them, totalling at least 79 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. Note first that the copies are not typed on the same thing: the declarations holding them bind \u0060argv\u0060 to \u0060list[str]\u0060 in one and \u0060List[str]\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":"markdown-html/skills/design-system/scripts/brand_palette_validator.py"},"region":{"startLine":304}}}],"partialFingerprints":{"codehealthFindingId/v1":"7ce361b11f0388c4fa6b64ba6304c188c020a5063d8cb1db7769d66035e8f207"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9 lines \u00D7 2): marketing-skill/skills/campaign-analytics/scripts/attribution_analyzer.py:47-55 | marketing-skill/skills/campaign-analytics/scripts/attribution_analyzer.py:63-71 \u2014 both copies are in the same file, so extract the block 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":"marketing-skill/skills/campaign-analytics/scripts/attribution_analyzer.py"},"region":{"startLine":47}}}],"partialFingerprints":{"codehealthFindingId/v1":"e342376dca84ef63271ba885fb0b292b4ac8135d179aff99fb2985286624ef14"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9 lines \u00D7 2): marketing-skill/skills/campaign-analytics/scripts/attribution_analyzer.py:106-114 | marketing-skill/skills/campaign-analytics/scripts/attribution_analyzer.py:140-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":"marketing-skill/skills/campaign-analytics/scripts/attribution_analyzer.py"},"region":{"startLine":106}}}],"partialFingerprints":{"codehealthFindingId/v1":"b5250c076e30511510a2d544fee4835106f2e03d43cbd2e118647c5038165f07"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9 lines \u00D7 2): marketing-skill/skills/onboarding-cro/scripts/activation_funnel_analyzer.py:197-205 | marketing-skill/skills/programmatic-seo/scripts/url_pattern_generator.py:169-177 \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":"marketing-skill/skills/onboarding-cro/scripts/activation_funnel_analyzer.py"},"region":{"startLine":197}}}],"partialFingerprints":{"codehealthFindingId/v1":"a1fcb85d17dc85da438570e514375a3bae00daf33bce1deb2693973ef16d6e9f"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9 lines \u00D7 2): product-team/skills/product-skills/scripts/discovery_cadence_tracker.py:147-155 | product-team/skills/product-skills/scripts/ost_linter.py:130-138 \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 \u0060product-team/skills/product-skills/scripts/discovery_cadence_tracker.py:147\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":"product-team/skills/product-skills/scripts/discovery_cadence_tracker.py"},"region":{"startLine":147}}}],"partialFingerprints":{"codehealthFindingId/v1":"e5adf94e2c9507df6debbe0451e429273bf55042b2ed2fe34a1bf2e0093d222d"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9 lines \u00D7 2): productivity/email/skills/inbox-setup/scripts/section_progress_tracker.py:207-215 | research/litreview/skills/litreview/scripts/citation_tracker.py:213-221 \u2014 before extracting anything, compare \u0060productivity/email/skills/inbox-setup/scripts/section_progress_tracker.py\u0060 and \u0060research/litreview/skills/litreview/scripts/citation_tracker.py\u0060 as WHOLE FILES: this scan already matched 6 separate duplicated blocks between them, totalling at least 70 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The \u0060return\u0060 at the foot of the matched lines is the enclosing body\u0027s own terminal exit, not an early one: it moves with them unchanged, and each site calls the extracted unit from the position that \u0060return\u0060 occupied \u2014 no decision has to be handed back and re-acted on. \u2605 These copies have DRIFTED, and that is worth reading before extracting anything: just before the matched lines, \u0060productivity/email/skills/inbox-setup/scripts/section_progress_tracker.py:206\u0060 calls \u0060add_argument\u0060 and \u0060research/litreview/skills/litreview/scripts/citation_tracker.py:212\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":"productivity/email/skills/inbox-setup/scripts/section_progress_tracker.py"},"region":{"startLine":207}}}],"partialFingerprints":{"codehealthFindingId/v1":"91650e65c913c4e8d73d5b236b9395386313e0f61222b24d9c212c2425f6fd25"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (8\u20139 lines \u00D7 2): project-management/skills/atlassian-templates/scripts/template_scaffolder.py:187-195 | project-management/skills/atlassian-templates/scripts/template_scaffolder.py:211-218 \u2014 both copies are in the same file, so extract the block 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":"project-management/skills/atlassian-templates/scripts/template_scaffolder.py"},"region":{"startLine":187}}}],"partialFingerprints":{"codehealthFindingId/v1":"d14706211a7af24054044cc3a34450ea8b43aba6abadac642fa69f238808b6a5"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9 lines \u00D7 2): ra-qm-team/compliance-team-eu-ai-act/skills/eu-ai-act-specialist/scripts/ai_act_obligation_tracker.py:228-236 | ra-qm-team/skills/eu-ai-act-specialist/scripts/ai_act_obligation_tracker.py:228-236 \u2014 before extracting anything, compare \u0060ra-qm-team/compliance-team-eu-ai-act/skills/eu-ai-act-specialist/scripts/ai_act_obligation_tracker.py\u0060 and \u0060ra-qm-team/skills/eu-ai-act-specialist/scripts/ai_act_obligation_tracker.py\u0060 as WHOLE FILES: this scan already matched 11 separate duplicated blocks between them, totalling at least 122 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The \u0060return\u0060 at the foot of the matched lines is the enclosing body\u0027s own terminal exit, not an early one: it moves with them unchanged, and each site calls the extracted unit from the position that \u0060return\u0060 occupied \u2014 no decision has to be handed back and re-acted on."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"ra-qm-team/compliance-team-eu-ai-act/skills/eu-ai-act-specialist/scripts/ai_act_obligation_tracker.py"},"region":{"startLine":228}}}],"partialFingerprints":{"codehealthFindingId/v1":"e6701d496964ba763d2be1b9a8dc6f32315a3ea617da0fd219de9a92c3333c36"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9 lines \u00D7 2): ra-qm-team/compliance-team-eu-ai-act/skills/eu-ai-act-specialist/scripts/ai_system_risk_classifier.py:293-301 | ra-qm-team/skills/eu-ai-act-specialist/scripts/ai_system_risk_classifier.py:293-301 \u2014 before extracting anything, compare \u0060ra-qm-team/compliance-team-eu-ai-act/skills/eu-ai-act-specialist/scripts/ai_system_risk_classifier.py\u0060 and \u0060ra-qm-team/skills/eu-ai-act-specialist/scripts/ai_system_risk_classifier.py\u0060 as WHOLE FILES: this scan already matched 7 separate duplicated blocks between them, totalling at least 156 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The \u0060return\u0060 at the foot of the matched lines is the enclosing body\u0027s own terminal exit, not an early one: it moves with them unchanged, and each site calls the extracted unit from the position that \u0060return\u0060 occupied \u2014 no decision has to be handed back and re-acted on."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"ra-qm-team/compliance-team-eu-ai-act/skills/eu-ai-act-specialist/scripts/ai_system_risk_classifier.py"},"region":{"startLine":293}}}],"partialFingerprints":{"codehealthFindingId/v1":"b90b8348698e05b27e398a753005d24e248addf6dd5ff48625fad16e8a2969c8"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9 lines \u00D7 2): ra-qm-team/compliance-team-iso42001/skills/iso42001-specialist/scripts/aims_gap_analyzer.py:198-206 | ra-qm-team/skills/iso42001-specialist/scripts/aims_gap_analyzer.py:198-206 \u2014 before extracting anything, compare \u0060ra-qm-team/compliance-team-iso42001/skills/iso42001-specialist/scripts/aims_gap_analyzer.py\u0060 and \u0060ra-qm-team/skills/iso42001-specialist/scripts/aims_gap_analyzer.py\u0060 as WHOLE FILES: this scan already matched 8 separate duplicated blocks between them, totalling at least 105 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"ra-qm-team/compliance-team-iso42001/skills/iso42001-specialist/scripts/aims_gap_analyzer.py"},"region":{"startLine":198}}}],"partialFingerprints":{"codehealthFindingId/v1":"47d227ead05d06c5c5beea0aa4a777bdc999af6d58e537c5ef840a43ddbec1ca"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7\u20139 lines \u00D7 2): ra-qm-team/skills/quality-manager-qmr/scripts/quality_effectiveness_monitor.py:126-134 | ra-qm-team/skills/quality-manager-qmr/scripts/quality_effectiveness_monitor.py:216-222 \u2014 both copies are in the same file, so extract the block into one function there and call it from each site \u2014 the copies drift apart the first time only one of them is edited."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"ra-qm-team/skills/quality-manager-qmr/scripts/quality_effectiveness_monitor.py"},"region":{"startLine":126}}}],"partialFingerprints":{"codehealthFindingId/v1":"61a6e4d4ee6ee94834ca3321c09bfeb3478ea3e054ab1feaf180c55f3270fb25"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (8\u20139 lines \u00D7 2): ra-qm-team/skills/soc2-compliance/scripts/evidence_tracker.py:39-47 | ra-qm-team/skills/soc2-compliance/scripts/gap_analyzer.py:129-136 \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":"ra-qm-team/skills/soc2-compliance/scripts/evidence_tracker.py"},"region":{"startLine":39}}}],"partialFingerprints":{"codehealthFindingId/v1":"629dc7f46ac7f4102e920467f5d44805fbc7c660d153c64b7941d6ffad29b029"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9 lines \u00D7 2): research-ops/skills/clinical-research/scripts/endpoint_selector.py:166-174 | research-ops/skills/market-research/scripts/segmentation_scorer.py:123-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. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"research-ops/skills/clinical-research/scripts/endpoint_selector.py"},"region":{"startLine":166}}}],"partialFingerprints":{"codehealthFindingId/v1":"0d1e59231137187aa5146e30bce60a72df0bd1f2623b51e487d430f172ad570d"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9 lines \u00D7 2): research-ops/skills/market-research/scripts/market_sizer.py:150-158 | research-ops/skills/product-research/scripts/study_designer.py:127-135 \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":"research-ops/skills/market-research/scripts/market_sizer.py"},"region":{"startLine":150}}}],"partialFingerprints":{"codehealthFindingId/v1":"cb1b06ce9f3d85577eee57981d347c00bb164c9be1e78e13c18d51106d297e99"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9 lines \u00D7 2): research-ops/skills/market-research/scripts/onboard.py:54-62 | research-ops/skills/research-finance/scripts/onboard.py:57-65 \u2014 before extracting anything, compare \u0060research-ops/skills/market-research/scripts/onboard.py\u0060 and \u0060research-ops/skills/research-finance/scripts/onboard.py\u0060 as WHOLE FILES: this scan already matched 6 separate duplicated blocks between them, totalling at least 69 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"research-ops/skills/market-research/scripts/onboard.py"},"region":{"startLine":54}}}],"partialFingerprints":{"codehealthFindingId/v1":"ca54b11d3d8043d5941d9d7c27790ac49de1de89c612a3d29878d9598b35b2f7"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9 lines \u00D7 2): research/patent/skills/patent/scripts/citation_tracker.py:202-210 | research/syllabus/skills/syllabus/scripts/citation_tracker.py:180-188 \u2014 before extracting anything, compare \u0060research/patent/skills/patent/scripts/citation_tracker.py\u0060 and \u0060research/syllabus/skills/syllabus/scripts/citation_tracker.py\u0060 as WHOLE FILES: this scan already matched 6 separate duplicated blocks between them, totalling at least 43 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. \u2605 These copies have DRIFTED, and that is worth reading before extracting anything: just before the matched lines, \u0060research/patent/skills/patent/scripts/citation_tracker.py:200\u0060 calls \u0060add_argument\u0060 and \u0060research/syllabus/skills/syllabus/scripts/citation_tracker.py:179\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":"research/patent/skills/patent/scripts/citation_tracker.py"},"region":{"startLine":202}}}],"partialFingerprints":{"codehealthFindingId/v1":"16483c427019d6c2db431e4c222a2402f8424e8b3e48eac69b18a421aa59d07a"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9 lines \u00D7 2): research/research/skills/research/scripts/classifier.py:169-177 | research/research/skills/research/scripts/fallback_decomposer.py:88-96 \u2014 the copies sit in sibling files of one directory, so a shared home is within easy reach: extract the block into a single shared function the call sites can all reach \u2014 a file they already depend on, or a new one alongside them \u2014 and call it from both call sites, so a change lands once. \u2605 These copies have DRIFTED, and that is worth reading before extracting anything: just before the matched lines, \u0060research/research/skills/research/scripts/fallback_decomposer.py:87\u0060 calls \u0060add_argument\u0060 and \u0060research/research/skills/research/scripts/classifier.py:168\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":"research/research/skills/research/scripts/classifier.py"},"region":{"startLine":169}}}],"partialFingerprints":{"codehealthFindingId/v1":"bdd1cf5fe9bb7a2740c13e8af0d009bdcfef7a54d880d73fabcc116f8b980997"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6\u20139 lines \u00D7 2): scripts/derive_counters.py:291-296 | scripts/derive_counters.py:311-319 \u2014 both copies are in the same file, so extract the block 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":"scripts/derive_counters.py"},"region":{"startLine":291}}}],"partialFingerprints":{"codehealthFindingId/v1":"f9413e06353e56a0dd759d9fbf85e4d0343e4855f2403750859d4d5549b3273b"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (8\u20139 lines \u00D7 2): scripts/smoke_json_output.py:78-85 | scripts/smoke_scripts.py:63-71 \u2014 before extracting anything, compare \u0060scripts/smoke_json_output.py\u0060 and \u0060scripts/smoke_scripts.py\u0060 as WHOLE FILES: this scan already matched 3 separate duplicated blocks between them, totalling at least 33 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":"scripts/smoke_json_output.py"},"region":{"startLine":78}}}],"partialFingerprints":{"codehealthFindingId/v1":"f6eb8cdbe387d0f45ef22973dc201d2443a9c47af30c719260e52317676a32a9"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7\u20138 lines \u00D7 7): marketing-skill/skills/aeo/scripts/citation_tracker.py:291-298 | marketing/linkedin/skills/linkedin-skills/scripts/linkedin_goal_router.py:118-125 | marketing/linkedin/skills/linkedin-skills/scripts/linkedin_policy_gate.py:291-298 | product-team/skills/product-skills/scripts/discovery_cadence_tracker.py:138-145 | product-team/skills/product-skills/scripts/product_goal_router.py:151-158 | project-management/skills/pm-skills/scripts/pm_goal_router.py:123-130 | research/research/skills/research/scripts/routing_transparency_logger.py:140-146 \u2014 before extracting anything, compare \u0060marketing/linkedin/skills/linkedin-skills/scripts/linkedin_goal_router.py\u0060 and \u0060product-team/skills/product-skills/scripts/product_goal_router.py\u0060 as WHOLE FILES: this scan already matched 8 separate duplicated blocks between them, totalling at least 79 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. \u2605 These copies have DRIFTED, and that is worth reading before extracting anything: just before the matched lines, \u0060research/research/skills/research/scripts/routing_transparency_logger.py:139\u0060 calls \u0060add_argument\u0060 and \u0060marketing-skill/skills/aeo/scripts/citation_tracker.py:290\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":"marketing-skill/skills/aeo/scripts/citation_tracker.py"},"region":{"startLine":291}}}],"partialFingerprints":{"codehealthFindingId/v1":"31b81d3d862e9f254c397b3b814ebc210f147fb541d7550a41b6004f0cab8c4b"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6\u20138 lines \u00D7 4): business-growth/skills/sales-engineer/scripts/poc_planner.py:600-607 | marketing-skill/skills/local-seo-manager/scripts/nap_checker.py:247-253 | ra-qm-team/compliance-team-eu-ai-act/skills/eu-ai-act-specialist/scripts/conformity_assessment_planner.py:247-252 | ra-qm-team/skills/eu-ai-act-specialist/scripts/conformity_assessment_planner.py:247-252 \u2014 before extracting anything, compare \u0060ra-qm-team/compliance-team-eu-ai-act/skills/eu-ai-act-specialist/scripts/conformity_assessment_planner.py\u0060 and \u0060ra-qm-team/skills/eu-ai-act-specialist/scripts/conformity_assessment_planner.py\u0060 as WHOLE FILES: this scan already matched 13 separate duplicated blocks between them, totalling at least 187 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. 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":"business-growth/skills/sales-engineer/scripts/poc_planner.py"},"region":{"startLine":600}}}],"partialFingerprints":{"codehealthFindingId/v1":"bbbfce7e660713726520d8132ffa72191f1d508ba57294e56eef35477beeaea1"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (8 lines \u00D7 4): business-growth/skills/sales-engineer/scripts/poc_planner.py:620-627 | business-growth/skills/sales-engineer/scripts/poc_planner.py:659-666 | business-growth/skills/sales-engineer/scripts/rfp_response_analyzer.py:436-443 | business-growth/skills/sales-engineer/scripts/rfp_response_analyzer.py:498-505 \u2014 there are 4 copies across 2 file(s) \u2014 more copies than files, so at least one file holds the block twice. Extract it once into a single shared function every call site can reach and call it from all 4 sites; resolving a subset leaves the remainder to drift apart."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"business-growth/skills/sales-engineer/scripts/poc_planner.py"},"region":{"startLine":620}}}],"partialFingerprints":{"codehealthFindingId/v1":"064896780900631f90e6b5b558e73910242811273bbc2e49947f1b302d2ba7ca"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (8 lines \u00D7 4): c-level-advisor/arquiteto-de-empresa/skills/arquiteto-de-empresa/scripts/index_generator.py:153-160 | c-level-advisor/arquiteto-de-empresa/skills/arquiteto-de-empresa/scripts/okf_linter.py:168-175 | c-level-advisor/skills/arquiteto-de-empresa/scripts/index_generator.py:153-160 | c-level-advisor/skills/arquiteto-de-empresa/scripts/okf_linter.py:168-175 \u2014 before extracting anything, compare \u0060c-level-advisor/arquiteto-de-empresa/skills/arquiteto-de-empresa/scripts/index_generator.py\u0060 and \u0060c-level-advisor/skills/arquiteto-de-empresa/scripts/index_generator.py\u0060 as WHOLE FILES: this scan already matched 10 separate duplicated blocks between them, totalling at least 135 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The \u0060return\u0060 at the foot of the matched lines is the enclosing body\u0027s own terminal exit, not an early one: it moves with them unchanged, and each site calls the extracted unit from the position that \u0060return\u0060 occupied \u2014 no decision has to be handed back and re-acted on. \u2605 These copies have DRIFTED, and that is worth reading before extracting anything: just before the matched lines, \u0060c-level-advisor/arquiteto-de-empresa/skills/arquiteto-de-empresa/scripts/index_generator.py:151\u0060 calls \u0060add_argument\u0060 and \u0060c-level-advisor/arquiteto-de-empresa/skills/arquiteto-de-empresa/scripts/okf_linter.py:166\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":"c-level-advisor/arquiteto-de-empresa/skills/arquiteto-de-empresa/scripts/index_generator.py"},"region":{"startLine":153}}}],"partialFingerprints":{"codehealthFindingId/v1":"3a50131731a7a36a1b1944ac6e9e05ed6f0285c7b10e78a2fe1946696bb93f06"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (8 lines \u00D7 4): c-level-advisor/chief-customer-officer-advisor/skills/chief-customer-officer-advisor/scripts/cs_coverage_calculator.py:194-201 | c-level-advisor/chief-customer-officer-advisor/skills/chief-customer-officer-advisor/scripts/customer_segmentation_designer.py:260-267 | c-level-advisor/skills/chief-customer-officer-advisor/scripts/cs_coverage_calculator.py:194-201 | c-level-advisor/skills/chief-customer-officer-advisor/scripts/customer_segmentation_designer.py:260-267 \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."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"c-level-advisor/chief-customer-officer-advisor/skills/chief-customer-officer-advisor/scripts/cs_coverage_calculator.py"},"region":{"startLine":194}}}],"partialFingerprints":{"codehealthFindingId/v1":"784bd2075a4714f997ca8ec92d073dce6f9c370338b67a5fff8e8441f58f3b08"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (8 lines \u00D7 4): c-level-advisor/skills/coo-advisor/scripts/okr_tracker.py:733-740 | c-level-advisor/skills/coo-advisor/scripts/ops_efficiency_analyzer.py:804-811 | c-level-advisor/skills/cpo-advisor/scripts/pmf_scorer.py:574-581 | c-level-advisor/skills/cpo-advisor/scripts/portfolio_analyzer.py:518-525 \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."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"c-level-advisor/skills/coo-advisor/scripts/okr_tracker.py"},"region":{"startLine":733}}}],"partialFingerprints":{"codehealthFindingId/v1":"899173d219a3a5a6b73c44139a33b07f685223486ac9ee191b0ed17d68aca6fe"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (8 lines \u00D7 4): engineering/kubernetes-operator/skills/kubernetes-operator/scripts/reconcile_lint.py:146-153 | engineering/skills/kubernetes-operator/scripts/reconcile_lint.py:146-153 | engineering/skills/slo-architect/scripts/slo_review.py:139-146 | engineering/slo-architect/skills/slo-architect/scripts/slo_review.py:139-146 \u2014 before extracting anything, compare \u0060engineering/kubernetes-operator/skills/kubernetes-operator/scripts/reconcile_lint.py\u0060 and \u0060engineering/skills/kubernetes-operator/scripts/reconcile_lint.py\u0060 as WHOLE FILES: this scan already matched 9 separate duplicated blocks between them, totalling at least 127 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/kubernetes-operator/skills/kubernetes-operator/scripts/reconcile_lint.py"},"region":{"startLine":146}}}],"partialFingerprints":{"codehealthFindingId/v1":"cd24422a4dc0ca38ba45df201f69afaff9413912858f32986e4a9b9c936aafa4"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (8 lines \u00D7 4): engineering/skills/database-designer/index_optimizer.py:800-807 | engineering/skills/database-designer/migration_generator.py:1079-1086 | engineering/skills/database-designer/schema_analyzer.py:833-840 | engineering/skills/tech-debt-tracker/scripts/debt_prioritizer.py:761-768 \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."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/database-designer/index_optimizer.py"},"region":{"startLine":800}}}],"partialFingerprints":{"codehealthFindingId/v1":"b27171090e5e9a9e8d7087646fa60cd843b446d5b2ac972de3858dd1dc3c56a3"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (8 lines \u00D7 4): marketing/linkedin/skills/linkedin-engagement/scripts/outreach_message_builder.py:224-231 | marketing/linkedin/skills/linkedin-profile/scripts/about_section_builder.py:239-247 | marketing/linkedin/skills/linkedin-profile/scripts/profile_completeness_auditor.py:242-251 | marketing/linkedin/skills/linkedin-strategy/scripts/positioning_brief.py:261-268 \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":"marketing/linkedin/skills/linkedin-engagement/scripts/outreach_message_builder.py"},"region":{"startLine":224}}}],"partialFingerprints":{"codehealthFindingId/v1":"3bf1472b8126bda4a144d71788cb3da6247f6ca8f5234419d5ce93b2912b77fb"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (8 lines \u00D7 4): productivity/handoff/hooks/session_end.py:43-50 | productivity/handoff/hooks/session_start.py:46-53 | productivity/handoff/skills/handoff/scripts/cleanup.py:28-35 | productivity/handoff/skills/handoff/scripts/handoff_template_generator.py:69-76 \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."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"productivity/handoff/hooks/session_end.py"},"region":{"startLine":43}}}],"partialFingerprints":{"codehealthFindingId/v1":"1753434181c20008826ed5dc9bea9fd43553d75f8434f470925f1d6d800a2913"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (8 lines \u00D7 4): ra-qm-team/compliance-team-eu-ai-act/skills/eu-ai-act-specialist/scripts/conformity_assessment_planner.py:249-256 | ra-qm-team/compliance-team-iso42001/skills/iso42001-specialist/scripts/ai_risk_register_builder.py:196-203 | ra-qm-team/skills/eu-ai-act-specialist/scripts/conformity_assessment_planner.py:249-256 | ra-qm-team/skills/iso42001-specialist/scripts/ai_risk_register_builder.py:196-203 \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."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"ra-qm-team/compliance-team-eu-ai-act/skills/eu-ai-act-specialist/scripts/conformity_assessment_planner.py"},"region":{"startLine":249}}}],"partialFingerprints":{"codehealthFindingId/v1":"1d38c37287055e5f77dff9a392ac8879ce6608874004560fe4c20c4e30586d2f"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (8 lines \u00D7 3): c-level-advisor/skills/vpe-advisor/scripts/delivery_throughput_analyzer.py:230-238 | c-level-advisor/vpe-advisor/skills/vpe-advisor/scripts/delivery_throughput_analyzer.py:230-238 | compliance-os/skills/compliance-os/scripts/audit_simulator.py:352-359 \u2014 before extracting anything, compare \u0060c-level-advisor/skills/vpe-advisor/scripts/delivery_throughput_analyzer.py\u0060 and \u0060c-level-advisor/vpe-advisor/skills/vpe-advisor/scripts/delivery_throughput_analyzer.py\u0060 as WHOLE FILES: this scan already matched 12 separate duplicated blocks between them, totalling at least 119 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The \u0060return\u0060 at the foot of the matched lines is the enclosing body\u0027s own terminal exit, not an early one: it moves with them unchanged, and each site calls the extracted unit from the position that \u0060return\u0060 occupied \u2014 no decision has to be handed back and re-acted on."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"c-level-advisor/skills/vpe-advisor/scripts/delivery_throughput_analyzer.py"},"region":{"startLine":230}}}],"partialFingerprints":{"codehealthFindingId/v1":"ff06c92567a394c3382c1b58ddab4def723b4e7a247bf26640fe88fe1e2121eb"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (8 lines \u00D7 3): engineering-team/google-workspace-cli/skills/google-workspace-cli/scripts/auth_setup_guide.py:377-384 | engineering-team/google-workspace-cli/skills/google-workspace-cli/scripts/gws_doctor.py:226-233 | engineering-team/google-workspace-cli/skills/google-workspace-cli/scripts/workspace_audit.py:280-287 \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":"engineering-team/google-workspace-cli/skills/google-workspace-cli/scripts/auth_setup_guide.py"},"region":{"startLine":377}}}],"partialFingerprints":{"codehealthFindingId/v1":"faa2f70d70c6bae3178262c61eb30cef881ac0aebdb47788cb2b2c260fc17a8b"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (8 lines \u00D7 3): engineering-team/skills/senior-backend/scripts/backend_decision_engine.py:99-106 | engineering-team/skills/senior-frontend/scripts/frontend_decision_engine.py:81-88 | engineering-team/skills/senior-fullstack/scripts/fullstack_decision_engine.py:94-101 \u2014 before extracting anything, compare \u0060engineering-team/skills/senior-backend/scripts/backend_decision_engine.py\u0060 and \u0060engineering-team/skills/senior-frontend/scripts/frontend_decision_engine.py\u0060 as WHOLE FILES: this scan already matched 6 separate duplicated blocks between them, totalling at least 99 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/skills/senior-backend/scripts/backend_decision_engine.py"},"region":{"startLine":99}}}],"partialFingerprints":{"codehealthFindingId/v1":"00e18607a279912e1801841c425da70b1c5b3eb30f40b44172fe22968dc19ce3"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5\u20138 lines \u00D7 3): engineering-team/snowflake-development/skills/snowflake-development/scripts/snowflake_query_helper.py:168-172 | engineering-team/snowflake-development/skills/snowflake-development/scripts/snowflake_query_helper.py:178-185 | engineering-team/snowflake-development/skills/snowflake-development/scripts/snowflake_query_helper.py:191-198 \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 \u0060engineering-team/snowflake-development/skills/snowflake-development/scripts/snowflake_query_helper.py:168\u0060 it does not close everything it opens, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that. Note that the copies do not run to the end of the range shown: their LAST lines are different code, not the same code under different names \u2014 the matched region ends inside that line. Extract the lines above it, and read the last line of each site separately. \u2605 These copies have DRIFTED, and that is worth reading before extracting anything: just after the matched lines, \u0060engineering-team/snowflake-development/skills/snowflake-development/scripts/snowflake_query_helper.py:172\u0060 calls \u0060add_argument\u0060 and \u0060engineering-team/snowflake-development/skills/snowflake-development/scripts/snowflake_query_helper.py:185\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":"engineering-team/snowflake-development/skills/snowflake-development/scripts/snowflake_query_helper.py"},"region":{"startLine":168}}}],"partialFingerprints":{"codehealthFindingId/v1":"991528b225e211852122b89e7ddb04cfb12882fdea2794c3c804b1bb8a69f96e"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (8 lines \u00D7 3): engineering/autoresearch-agent/skills/autoresearch-agent/scripts/log_results.py:140-147 | engineering/autoresearch-agent/skills/autoresearch-agent/scripts/log_results.py:226-233 | engineering/autoresearch-agent/skills/autoresearch-agent/scripts/log_results.py:291-298 \u2014 all 3 copies are in the same file, so extract the block into one function there and call it from every one of those sites \u2014 resolving only two of them leaves the rest to drift apart the first time one is edited. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/autoresearch-agent/skills/autoresearch-agent/scripts/log_results.py"},"region":{"startLine":140}}}],"partialFingerprints":{"codehealthFindingId/v1":"3a449a4ecc14c86c5fdee1c1f04e66bca4a532f7928ed1b80b61478825a02531"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (8 lines \u00D7 3): engineering/docker-development/skills/docker-development/scripts/dockerfile_analyzer.py:320-327 | engineering/helm-chart-builder/skills/helm-chart-builder/scripts/chart_analyzer.py:421-428 | engineering/terraform-patterns/skills/terraform-patterns/scripts/tf_security_scanner.py:473-480 \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. \u2605 These copies have DRIFTED, and that is worth reading before extracting anything: just after the matched lines, \u0060engineering/terraform-patterns/skills/terraform-patterns/scripts/tf_security_scanner.py:485\u0060 calls \u0060generate_report\u0060, \u0060scan_content\u0060 and \u0060engineering/docker-development/skills/docker-development/scripts/dockerfile_analyzer.py:330\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":"engineering/docker-development/skills/docker-development/scripts/dockerfile_analyzer.py"},"region":{"startLine":320}}}],"partialFingerprints":{"codehealthFindingId/v1":"fc4a2300e6258c8b4fb5bdd0e8ba78ce5cd7c4d55ebf9ef80c71e6c044dbdd8f"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (8 lines \u00D7 3): engineering/skills/secrets-vault-manager/scripts/rotation_planner.py:59-66 | ra-qm-team/skills/soc2-compliance/scripts/evidence_tracker.py:35-42 | ra-qm-team/skills/soc2-compliance/scripts/gap_analyzer.py:125-132 \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":"engineering/skills/secrets-vault-manager/scripts/rotation_planner.py"},"region":{"startLine":59}}}],"partialFingerprints":{"codehealthFindingId/v1":"c4a7e05831f67ce1a7215c3e2c7fa6d579a973b1e1d615946cd4ed0cde170a6b"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (8 lines \u00D7 3): markdown-html/skills/design-system/scripts/brand_palette_validator.py:209-216 | markdown-html/skills/design-system/scripts/brand_palette_validator.py:218-225 | markdown-html/skills/design-system/scripts/brand_palette_validator.py:227-234 \u2014 all 3 copies are in the same file, so extract the block into one function there and call it from every one of those sites \u2014 resolving only two of them leaves the rest to drift apart the first time one is edited. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"markdown-html/skills/design-system/scripts/brand_palette_validator.py"},"region":{"startLine":209}}}],"partialFingerprints":{"codehealthFindingId/v1":"0aeb727fa516564af67a18d48b7d20b7132a8535724e5d242397c0f3c3bfa4c4"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (8 lines \u00D7 3): marketing-skill/skills/ad-creative/scripts/ad_copy_validator.py:440-447 | marketing-skill/skills/free-tool-strategy/scripts/tool_roi_estimator.py:353-360 | marketing-skill/skills/referral-program/scripts/referral_roi_calculator.py:376-383 \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":"marketing-skill/skills/ad-creative/scripts/ad_copy_validator.py"},"region":{"startLine":440}}}],"partialFingerprints":{"codehealthFindingId/v1":"1c790617abd6603854fedda817d61a4f34406dd399f9f3400cd30a36ff3f51af"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7\u20138 lines \u00D7 3): marketing/linkedin/skills/linkedin-content/scripts/format_picker.py:213-220 | marketing/linkedin/skills/linkedin-content/scripts/post_linter.py:304-310 | marketing/linkedin/skills/linkedin-content/scripts/repurpose_splitter.py:207-214 \u2014 the copies sit in sibling files of one directory, so a shared home is within easy reach: extract the block into a single shared function the call sites can all reach \u2014 a file they already depend on, or a new one alongside them \u2014 and call it from all 3 call sites, so a change lands once. Read the line range as the matched WINDOW rather than a finished unit: at \u0060marketing/linkedin/skills/linkedin-content/scripts/format_picker.py:213\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":"marketing/linkedin/skills/linkedin-content/scripts/format_picker.py"},"region":{"startLine":213}}}],"partialFingerprints":{"codehealthFindingId/v1":"3f0d63dd4298fb939310871bb18645667899e0090cc0610321ffc1ef98a276af"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7\u20138 lines \u00D7 3): marketing/linkedin/skills/linkedin-profile/scripts/headline_scorer.py:255-261 | product-team/skills/product-skills/scripts/product_goal_router.py:148-154 | project-management/skills/pm-skills/scripts/pm_goal_router.py:119-126 \u2014 before extracting anything, compare \u0060product-team/skills/product-skills/scripts/product_goal_router.py\u0060 and \u0060project-management/skills/pm-skills/scripts/pm_goal_router.py\u0060 as WHOLE FILES: this scan already matched 9 separate duplicated blocks between them, totalling at least 130 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. Read the line range as the matched WINDOW rather than a finished unit: at \u0060marketing/linkedin/skills/linkedin-profile/scripts/headline_scorer.py:255\u0060 it does not close everything it opens, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that. \u2605 These copies have DRIFTED, and that is worth reading before extracting anything: just after the matched lines, \u0060marketing/linkedin/skills/linkedin-profile/scripts/headline_scorer.py:263\u0060 calls \u0060add_argument\u0060 and \u0060product-team/skills/product-skills/scripts/product_goal_router.py:156\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":"marketing/linkedin/skills/linkedin-profile/scripts/headline_scorer.py"},"region":{"startLine":255}}}],"partialFingerprints":{"codehealthFindingId/v1":"94a2bf4093d9f642ff69630fb35c581ca72bad2c8da85c2feebdc4d67f30c7cd"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (8 lines \u00D7 3): product-team/research-summarizer/skills/research-summarizer/scripts/extract_citations.py:127-134 | product-team/research-summarizer/skills/research-summarizer/scripts/extract_citations.py:140-147 | product-team/research-summarizer/skills/research-summarizer/scripts/extract_citations.py:166-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. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"product-team/research-summarizer/skills/research-summarizer/scripts/extract_citations.py"},"region":{"startLine":127}}}],"partialFingerprints":{"codehealthFindingId/v1":"ff0f6ae1919d194068b0bca41351374e96761f75f409eb8f2d622ada93c2ad36"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (8 lines \u00D7 2): business-growth/skills/customer-success-manager/scripts/churn_risk_analyzer.py:387-394 | business-growth/skills/customer-success-manager/scripts/expansion_opportunity_scorer.py:313-320 \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":"business-growth/skills/customer-success-manager/scripts/churn_risk_analyzer.py"},"region":{"startLine":387}}}],"partialFingerprints":{"codehealthFindingId/v1":"fcd048742c0f6d14ef0f9144eaf98a69931a25a6206017b669a74e5d00415f7c"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7\u20138 lines \u00D7 2): business-growth/skills/revenue-operations/scripts/pipeline_analyzer.py:392-399 | productivity/capture/skills/capture/scripts/complexity_estimator.py:145-151 \u2014 the copies span different directories, so extracting a shared function means choosing where it lives: put it somewhere both call sites can already reach \u2014 a location they all depend on today, or a new shared one if there is none \u2014 and call it from each site; until then, every change has to be made twice. Read the line range as the matched WINDOW rather than a finished unit: at \u0060business-growth/skills/revenue-operations/scripts/pipeline_analyzer.py:392\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":"business-growth/skills/revenue-operations/scripts/pipeline_analyzer.py"},"region":{"startLine":392}}}],"partialFingerprints":{"codehealthFindingId/v1":"b0c0f325416b303a12f647a23f8dced93a22b35cad548321d2224124ebed7cef"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (8 lines \u00D7 2): business-operations/skills/internal-comms/scripts/comms_template_filler.py:229-236 | business-operations/skills/internal-comms/scripts/comms_template_filler.py:239-246 \u2014 both copies are in the same file, so extract the block 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 \u0060business-operations/skills/internal-comms/scripts/comms_template_filler.py:229\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":"business-operations/skills/internal-comms/scripts/comms_template_filler.py"},"region":{"startLine":229}}}],"partialFingerprints":{"codehealthFindingId/v1":"b31044006751a512d67f936919a639604bd4f6eed3228900648e7126dde78aa8"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (8 lines \u00D7 2): c-level-advisor/chief-customer-officer-advisor/skills/chief-customer-officer-advisor/scripts/customer_segmentation_designer.py:284-291 | c-level-advisor/skills/chief-customer-officer-advisor/scripts/customer_segmentation_designer.py:284-291 \u2014 before extracting anything, compare \u0060c-level-advisor/chief-customer-officer-advisor/skills/chief-customer-officer-advisor/scripts/customer_segmentation_designer.py\u0060 and \u0060c-level-advisor/skills/chief-customer-officer-advisor/scripts/customer_segmentation_designer.py\u0060 as WHOLE FILES: this scan already matched 11 separate duplicated blocks between them, totalling at least 146 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"c-level-advisor/chief-customer-officer-advisor/skills/chief-customer-officer-advisor/scripts/customer_segmentation_designer.py"},"region":{"startLine":284}}}],"partialFingerprints":{"codehealthFindingId/v1":"465a58840c3e76049b566b371ebd013edbf88c624f61f12535fd179bd6d3a4f9"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7\u20138 lines \u00D7 2): c-level-advisor/skills/org-health-diagnostic/scripts/health_scorer.py:84-91 | c-level-advisor/skills/org-health-diagnostic/scripts/health_scorer.py:98-104 \u2014 both copies are in the same file, so extract the block 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":"c-level-advisor/skills/org-health-diagnostic/scripts/health_scorer.py"},"region":{"startLine":84}}}],"partialFingerprints":{"codehealthFindingId/v1":"b9499b7ee27887b6cc1bfecd0c04d3d9573a13d8b7d594373353dc87796fd73d"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (8 lines \u00D7 2): c-level-advisor/skills/vpe-advisor/scripts/delivery_throughput_analyzer.py:220-227 | c-level-advisor/vpe-advisor/skills/vpe-advisor/scripts/delivery_throughput_analyzer.py:220-227 \u2014 before extracting anything, compare \u0060c-level-advisor/skills/vpe-advisor/scripts/delivery_throughput_analyzer.py\u0060 and \u0060c-level-advisor/vpe-advisor/skills/vpe-advisor/scripts/delivery_throughput_analyzer.py\u0060 as WHOLE FILES: this scan already matched 12 separate duplicated blocks between them, totalling at least 119 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"c-level-advisor/skills/vpe-advisor/scripts/delivery_throughput_analyzer.py"},"region":{"startLine":220}}}],"partialFingerprints":{"codehealthFindingId/v1":"09a4910f89933b667a69ff060a1211a2654f853857c06d9df2bc8930a17772a2"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (8 lines \u00D7 2): commercial/skills/partnerships-architect/scripts/partner_tier_classifier.py:195-202 | commercial/skills/partnerships-architect/scripts/partner_tier_classifier.py:215-222 \u2014 both copies are in the same file, so extract the block into one function there and call it from each site \u2014 the copies drift apart the first time only one of them is edited. Read the line range as the matched WINDOW rather than a finished unit: at \u0060commercial/skills/partnerships-architect/scripts/partner_tier_classifier.py:195\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":"commercial/skills/partnerships-architect/scripts/partner_tier_classifier.py"},"region":{"startLine":195}}}],"partialFingerprints":{"codehealthFindingId/v1":"32205bf45f90351d9750a00490423ede07e404e2310b37d5909a2ef7b9ae1802"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (8 lines \u00D7 2): engineering-team/skills/azure-cloud-architect/scripts/cost_optimizer.py:142-149 | engineering-team/skills/azure-cloud-architect/scripts/cost_optimizer.py:300-307 \u2014 both copies are in the same file, so extract the block 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":"engineering-team/skills/azure-cloud-architect/scripts/cost_optimizer.py"},"region":{"startLine":142}}}],"partialFingerprints":{"codehealthFindingId/v1":"d158cbbc68d651eb7be0ab77d961efe8f3c778f8fa49caebd759b86b3a761cca"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (8 lines \u00D7 2): engineering-team/skills/cloud-security/scripts/cloud_posture_check.py:328-335 | engineering-team/skills/cloud-security/scripts/cloud_posture_check.py:402-410 \u2014 both copies are in the same file, so extract the block 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 \u0060engineering-team/skills/cloud-security/scripts/cloud_posture_check.py:328\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":"engineering-team/skills/cloud-security/scripts/cloud_posture_check.py"},"region":{"startLine":328}}}],"partialFingerprints":{"codehealthFindingId/v1":"f53daa4af16872c3a61990c9ef22039d02b6b82b2992ad94794e9c5a9425c58c"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (8 lines \u00D7 2): engineering-team/skills/senior-backend/scripts/api_scaffolder.py:367-374 | engineering-team/skills/senior-backend/scripts/api_scaffolder.py:379-386 \u2014 both copies are in the same file, so extract the block 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":"engineering-team/skills/senior-backend/scripts/api_scaffolder.py"},"region":{"startLine":367}}}],"partialFingerprints":{"codehealthFindingId/v1":"4c3c851eb677b5a7001bd2510b22d2947313fc1a122b55f83aaededf2f56d78d"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (8 lines \u00D7 2): engineering/book-to-skill/skills/book-to-skill/scripts/skill_plugin_emitter.py:570-577 | engineering/book-to-skill/skills/book-to-skill/scripts/token_budget_estimator.py:332-339 \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 \u0060engineering/book-to-skill/skills/book-to-skill/scripts/token_budget_estimator.py:332\u0060 it begins part-way through the construct above it, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that. The \u0060return\u0060 at the foot of the matched lines is the enclosing body\u0027s own terminal exit, not an early one: it moves with them unchanged, and each site calls the extracted unit from the position that \u0060return\u0060 occupied \u2014 no decision has to be handed back and re-acted on."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/book-to-skill/skills/book-to-skill/scripts/skill_plugin_emitter.py"},"region":{"startLine":570}}}],"partialFingerprints":{"codehealthFindingId/v1":"10584c0ee3b450897b4216c2f4ee375406a829662789d32a5ea3d1392b899785"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (8 lines \u00D7 2): engineering/helm-chart-builder/skills/helm-chart-builder/scripts/chart_analyzer.py:491-498 | engineering/helm-chart-builder/skills/helm-chart-builder/scripts/chart_analyzer.py:530-537 \u2014 both copies are in the same file, so extract the block 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":"engineering/helm-chart-builder/skills/helm-chart-builder/scripts/chart_analyzer.py"},"region":{"startLine":491}}}],"partialFingerprints":{"codehealthFindingId/v1":"428acc7dc86cfbd3f17e7f9276dab38813585634658e75fe422fca1e97b54bdf"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (8 lines \u00D7 2): engineering/memory-engineering/skills/memory-engineering/scripts/memory_cost_profiler.py:301-308 | engineering/memory-engineering/skills/memory-engineering/scripts/memory_density_auditor.py:600-607 \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":"engineering/memory-engineering/skills/memory-engineering/scripts/memory_cost_profiler.py"},"region":{"startLine":301}}}],"partialFingerprints":{"codehealthFindingId/v1":"5b7c661c892094c7a8b123387ad9ed2f13152b68a688ef817c9d28e5a37a57c2"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (8 lines \u00D7 2): engineering/skills/database-designer/migration_generator.py:1085-1092 | engineering/skills/migration-architect/scripts/rollback_generator.py:955-962 \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":"engineering/skills/database-designer/migration_generator.py"},"region":{"startLine":1085}}}],"partialFingerprints":{"codehealthFindingId/v1":"254e423ce361a21c1d87e6a0ace38fc50d2315efd98aafb1f2e544881c867ae2"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (8 lines \u00D7 2): engineering/skills/dependency-auditor/scripts/dep_scanner.py:706-713 | ra-qm-team/skills/soc2-compliance/scripts/gap_analyzer.py:378-385 \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":"engineering/skills/dependency-auditor/scripts/dep_scanner.py"},"region":{"startLine":706}}}],"partialFingerprints":{"codehealthFindingId/v1":"82eaf7bead8eb9032a05560281ddc71d895d44ae337b4bb367a59358e8d65f7b"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (8 lines \u00D7 2): engineering/skills/interview-system-designer/hiring_calibrator.py:808-815 | engineering/skills/interview-system-designer/hiring_calibrator.py:822-829 \u2014 both copies are in the same file, so extract the block into one function there and call it from each site \u2014 the copies drift apart the first time only one of them is edited."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/interview-system-designer/hiring_calibrator.py"},"region":{"startLine":808}}}],"partialFingerprints":{"codehealthFindingId/v1":"b2269f79bb167e84ffadbe3e1de5e6c072fa5e408f840f1c6f592f40698838e8"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (8 lines \u00D7 2): engineering/skills/interview-system-designer/hiring_calibrator.py:1136-1143 | engineering/skills/interview-system-designer/hiring_calibrator.py:1179-1186 \u2014 both copies are in the same file, so extract the block 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, \u0060engineering/skills/interview-system-designer/hiring_calibrator.py:1135\u0060 calls \u0060get\u0060 and \u0060engineering/skills/interview-system-designer/hiring_calibrator.py:1178\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":"engineering/skills/interview-system-designer/hiring_calibrator.py"},"region":{"startLine":1136}}}],"partialFingerprints":{"codehealthFindingId/v1":"8c496acb3ecd3076d0e4060f65a4760755efb57f22f205a1241214a79336e8b0"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (8 lines \u00D7 2): engineering/skills/interview-system-designer/loop_designer.py:841-848 | engineering/skills/interview-system-designer/question_bank_generator.py:986-993 \u2014 the copies sit in sibling files of one directory, so a shared home is within easy reach: extract the block into a single shared function the call sites can all reach \u2014 a file they already depend on, or a new one alongside them \u2014 and call it from both call sites, so a change lands once. \u2605 These copies have DRIFTED, and that is worth reading before extracting anything: just after the matched lines, \u0060engineering/skills/interview-system-designer/question_bank_generator.py:994\u0060 calls \u0060get\u0060 and \u0060engineering/skills/interview-system-designer/loop_designer.py:849\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":"engineering/skills/interview-system-designer/loop_designer.py"},"region":{"startLine":841}}}],"partialFingerprints":{"codehealthFindingId/v1":"b8596bf6e27d97eedfab0e3f949d2a4551ee251e5775460ea74cdf60176372db"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (8 lines \u00D7 2): engineering/skills/migration-architect/scripts/compatibility_checker.py:319-326 | engineering/skills/migration-architect/scripts/compatibility_checker.py:620-627 \u2014 both copies are in the same file, so extract the block 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 \u0060engineering/skills/migration-architect/scripts/compatibility_checker.py:319\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":"engineering/skills/migration-architect/scripts/compatibility_checker.py"},"region":{"startLine":319}}}],"partialFingerprints":{"codehealthFindingId/v1":"57f23e996b0c2183bb8a102658cc5182b1c4be32023b836f5a07d145271a35f2"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (8 lines \u00D7 2): engineering/skills/migration-architect/scripts/compatibility_checker.py:552-559 | engineering/skills/migration-architect/scripts/compatibility_checker.py:568-575 \u2014 both copies are in the same file, so extract the block 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 \u0060engineering/skills/migration-architect/scripts/compatibility_checker.py:552\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":"engineering/skills/migration-architect/scripts/compatibility_checker.py"},"region":{"startLine":552}}}],"partialFingerprints":{"codehealthFindingId/v1":"94155f96901e266922f7a85581309c429ae61a58a2f013cd543c55bc2be401dd"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (8 lines \u00D7 2): engineering/skills/ship-gate/scripts/ship_gate_scanner.py:629-636 | engineering/skills/ship-gate/scripts/ship_gate_scanner.py:823-830 \u2014 both copies are in the same file, so extract the block 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":"engineering/skills/ship-gate/scripts/ship_gate_scanner.py"},"region":{"startLine":629}}}],"partialFingerprints":{"codehealthFindingId/v1":"1e54bfc2112f74e21a4347414ca16fea77da7b8475e0d79f7ffa65179951954d"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (8 lines \u00D7 2): engineering/skills/slo-architect/scripts/error_budget_calculator.py:106-113 | engineering/slo-architect/skills/slo-architect/scripts/error_budget_calculator.py:106-113 \u2014 before extracting anything, compare \u0060engineering/skills/slo-architect/scripts/error_budget_calculator.py\u0060 and \u0060engineering/slo-architect/skills/slo-architect/scripts/error_budget_calculator.py\u0060 as WHOLE FILES: this scan already matched 7 separate duplicated blocks between them, totalling at least 89 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/slo-architect/scripts/error_budget_calculator.py"},"region":{"startLine":106}}}],"partialFingerprints":{"codehealthFindingId/v1":"fa71e795045b1ea6eb4b70f2bc0a1b8763e97d6cb71e2cda873973a1be3963d0"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (8 lines \u00D7 2): engineering/terraform-patterns/skills/terraform-patterns/scripts/tf_module_analyzer.py:127-134 | engineering/terraform-patterns/skills/terraform-patterns/scripts/tf_security_scanner.py:246-253 \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":"engineering/terraform-patterns/skills/terraform-patterns/scripts/tf_module_analyzer.py"},"region":{"startLine":127}}}],"partialFingerprints":{"codehealthFindingId/v1":"d08253e3add033a0370e82b02f2a5ca5fd3b5f1ab52beb390bce65a259cabca5"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (8 lines \u00D7 2): markdown-html/skills/design-system/scripts/config_loader.py:109-116 | research-ops/skills/clinical-research/scripts/config_loader.py:89-96 \u2014 before extracting anything, compare \u0060markdown-html/skills/design-system/scripts/config_loader.py\u0060 and \u0060research-ops/skills/clinical-research/scripts/config_loader.py\u0060 as WHOLE FILES: this scan already matched 6 separate duplicated blocks between them, totalling at least 60 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The \u0060return\u0060 at the foot of the matched lines is the enclosing body\u0027s own terminal exit, not an early one: it moves with them unchanged, and each site calls the extracted unit from the position that \u0060return\u0060 occupied \u2014 no decision has to be handed back and re-acted on."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"markdown-html/skills/design-system/scripts/config_loader.py"},"region":{"startLine":109}}}],"partialFingerprints":{"codehealthFindingId/v1":"305deb45e2e82f7fb95c467261003d378c36e79196c640d2fbe862ec2092e86e"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (8 lines \u00D7 2): markdown-html/skills/md-document/scripts/markdown_parser.py:346-353 | markdown-html/skills/md-slides/scripts/presenter_notes_parser.py:84-91 \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":"markdown-html/skills/md-document/scripts/markdown_parser.py"},"region":{"startLine":346}}}],"partialFingerprints":{"codehealthFindingId/v1":"4f49872ea56322026787a6a8a75d7b247495c756accf041f2a6fe6d1259c56c4"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (8 lines \u00D7 2): marketing-skill/skills/copy-editing/scripts/ai_content_detector.py:106-113 | marketing-skill/skills/copy-editing/scripts/ai_content_detector.py:139-146 \u2014 both copies are in the same file, so extract the block into one function there and call it from each site \u2014 the copies drift apart the first time only one of them is edited."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"marketing-skill/skills/copy-editing/scripts/ai_content_detector.py"},"region":{"startLine":106}}}],"partialFingerprints":{"codehealthFindingId/v1":"8444bfa1937e7c6371839d0a330c3c06a654061584c77012d431e9da33a6beb9"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7\u20138 lines \u00D7 2): marketing-skill/skills/copy-editing/scripts/readability_scorer.py:203-210 | marketing-skill/skills/page-cro/scripts/conversion_audit.py:357-363 \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 \u0060marketing-skill/skills/copy-editing/scripts/readability_scorer.py:203\u0060 it begins part-way through the construct above it, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that. \u2605 These copies have DRIFTED, and that is worth reading before extracting anything: just before the matched lines, \u0060marketing-skill/skills/page-cro/scripts/conversion_audit.py:356\u0060 calls \u0060add_argument\u0060 and \u0060marketing-skill/skills/copy-editing/scripts/readability_scorer.py:203\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":"marketing-skill/skills/copy-editing/scripts/readability_scorer.py"},"region":{"startLine":203}}}],"partialFingerprints":{"codehealthFindingId/v1":"fe5a97668ba691ba728fc626dfddc504b19f7a0671c406af65be3d3f7ee9bb26"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (8 lines \u00D7 2): productivity/email/skills/inbox-setup/scripts/kb_validator.py:223-230 | productivity/email/skills/inbox-triage/scripts/kb_reader.py:268-275 \u2014 the copies span different directories, so extracting a shared function means choosing where it lives: put it somewhere both call sites can already reach \u2014 a location they all depend on today, or a new shared one if there is none \u2014 and call it from each site; until then, every change has to be made twice."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"productivity/email/skills/inbox-setup/scripts/kb_validator.py"},"region":{"startLine":223}}}],"partialFingerprints":{"codehealthFindingId/v1":"93f6ecb1cb5e9b8617ea763ed2138088bfa4fe480359d1478e402a97dd485767"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (8 lines \u00D7 2): productivity/handoff/skills/handoff/scripts/handoff_self_check.py:146-153 | productivity/handoff/skills/handoff/scripts/handoff_template_generator.py:32-43 \u2014 the copies sit in sibling files of one directory, so a shared home is within easy reach: extract the block into a single shared function the call sites can all reach \u2014 a file they already depend on, or a new one alongside them \u2014 and call it from both call sites, so a change lands once."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"productivity/handoff/skills/handoff/scripts/handoff_self_check.py"},"region":{"startLine":146}}}],"partialFingerprints":{"codehealthFindingId/v1":"bdc18e8fedbe2340f5e09769e852e554fd6675cf32ed788a6d640cc76b8e6dcb"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (8 lines \u00D7 2): productivity/handoff/skills/handoff/scripts/handoff_self_check.py:279-286 | productivity/handoff/skills/handoff/scripts/redaction_linter.py:200-207 \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":"productivity/handoff/skills/handoff/scripts/handoff_self_check.py"},"region":{"startLine":279}}}],"partialFingerprints":{"codehealthFindingId/v1":"de4db703171cfb8cfc87ca62b59fd51654f8173f9f886e970a3e9e8a37a57225"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (8 lines \u00D7 2): ra-qm-team/skills/fda-consultant-specialist/scripts/hipaa_risk_assessment.py:525-532 | ra-qm-team/skills/fda-consultant-specialist/scripts/qsr_compliance_checker.py:566-573 \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":"ra-qm-team/skills/fda-consultant-specialist/scripts/hipaa_risk_assessment.py"},"region":{"startLine":525}}}],"partialFingerprints":{"codehealthFindingId/v1":"255cb95d5de113f25299a24199a8d15259bf0aad703dbe3e6e100293bb606509"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (8 lines \u00D7 2): ra-qm-team/skills/soc2-compliance/scripts/gap_analyzer.py:390-397 | ra-qm-team/skills/soc2-compliance/scripts/gap_analyzer.py:401-409 \u2014 both copies are in the same file, so extract the block 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 \u0060ra-qm-team/skills/soc2-compliance/scripts/gap_analyzer.py:401\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":"ra-qm-team/skills/soc2-compliance/scripts/gap_analyzer.py"},"region":{"startLine":390}}}],"partialFingerprints":{"codehealthFindingId/v1":"7978e6fbe764859ac59e7534f9a7d6d2fbe2052d314befe84f89ddb481f514bb"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (8 lines \u00D7 2): research-ops/skills/market-research/scripts/market_sizer.py:123-130 | research-ops/skills/research-finance/scripts/burn_runway_tracker.py:117-124 \u2014 the copies span different directories, so extracting a shared function means choosing where it lives: put it somewhere both call sites can already reach \u2014 a location they all depend on today, or a new shared one if there is none \u2014 and call it from each site; until then, every change has to be made twice. The \u0060return\u0060 at the foot of the matched lines is the enclosing body\u0027s own terminal exit, not an early one: it moves with them unchanged, and each site calls the extracted unit from the position that \u0060return\u0060 occupied \u2014 no decision has to be handed back and re-acted on."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"research-ops/skills/market-research/scripts/market_sizer.py"},"region":{"startLine":123}}}],"partialFingerprints":{"codehealthFindingId/v1":"b5c56b4c02c3909b314055336d4115bcc7f9d91525659594aff62a43fe5f12c8"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (8 lines \u00D7 2): research/patent/skills/patent/scripts/citation_tracker.py:102-109 | research/syllabus/skills/syllabus/scripts/citation_tracker.py:87-94 \u2014 before extracting anything, compare \u0060research/patent/skills/patent/scripts/citation_tracker.py\u0060 and \u0060research/syllabus/skills/syllabus/scripts/citation_tracker.py\u0060 as WHOLE FILES: this scan already matched 6 separate duplicated blocks between them, totalling at least 43 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"research/patent/skills/patent/scripts/citation_tracker.py"},"region":{"startLine":102}}}],"partialFingerprints":{"codehealthFindingId/v1":"7504b4540240018ef5d3b616b69df046761921754df6422d3f3bc3650bf3af2c"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (8 lines \u00D7 2): research/patent/skills/patent/scripts/family_resolver.py:140-147 | research/patent/skills/patent/scripts/family_resolver.py:151-158 \u2014 both copies are in the same file, so extract the block into one function there and call it from each site \u2014 the copies drift apart the first time only one of them is edited."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"research/patent/skills/patent/scripts/family_resolver.py"},"region":{"startLine":140}}}],"partialFingerprints":{"codehealthFindingId/v1":"d734da7a06fb73fdb858088f3be84e752b48a972acd7cf21221a1bd707b2377c"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (3\u20138 lines \u00D7 3): scripts/check_frontmatter.py:175-182 | scripts/check_model_freshness.py:172-179 | scripts/check_paths.py:177-179 \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. 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":"scripts/check_frontmatter.py"},"region":{"startLine":175}}}],"partialFingerprints":{"codehealthFindingId/v1":"d765e2e6633a6c044b4ed6c5dfb4e67df4457c0bbdeae3b929363f0798ad8a27"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 18): c-level-advisor/skills/vpe-advisor/scripts/delivery_throughput_analyzer.py:202-208 | c-level-advisor/vpe-advisor/skills/vpe-advisor/scripts/delivery_throughput_analyzer.py:202-208 | compliance-os/skills/compliance-os/scripts/audit_simulator.py:318-324 | compliance-os/skills/compliance-os/scripts/cross_framework_mapper.py:356-362 | compliance-os/skills/compliance-os/scripts/evidence_pool_generator.py:282-288 | compliance-os/skills/compliance-os/scripts/framework_selector.py:231-237 | ra-qm-team/compliance-team-eu-ai-act/skills/eu-ai-act-specialist/scripts/ai_act_obligation_tracker.py:202-208 | ra-qm-team/compliance-team-eu-ai-act/skills/eu-ai-act-specialist/scripts/ai_system_risk_classifier.py:273-279 | ra-qm-team/compliance-team-eu-ai-act/skills/eu-ai-act-specialist/scripts/conformity_assessment_planner.py:236-242 | ra-qm-team/compliance-team-iso42001/skills/iso42001-specialist/scripts/ai_risk_register_builder.py:185-191 | ra-qm-team/compliance-team-iso42001/skills/iso42001-specialist/scripts/aims_audit_scheduler.py:180-186 | ra-qm-team/compliance-team-iso42001/skills/iso42001-specialist/scripts/aims_gap_analyzer.py:188-194 | ra-qm-team/skills/eu-ai-act-specialist/scripts/ai_act_obligation_tracker.py:202-208 | ra-qm-team/skills/eu-ai-act-specialist/scripts/ai_system_risk_classifier.py:273-279 | ra-qm-team/skills/eu-ai-act-specialist/scripts/conformity_assessment_planner.py:236-242 | ra-qm-team/skills/iso42001-specialist/scripts/ai_risk_register_builder.py:185-191 | ra-qm-team/skills/iso42001-specialist/scripts/aims_audit_scheduler.py:180-186 | ra-qm-team/skills/iso42001-specialist/scripts/aims_gap_analyzer.py:188-194 \u2014 before extracting anything, compare \u0060c-level-advisor/skills/vpe-advisor/scripts/delivery_throughput_analyzer.py\u0060 and \u0060c-level-advisor/vpe-advisor/skills/vpe-advisor/scripts/delivery_throughput_analyzer.py\u0060 as WHOLE FILES: this scan already matched 12 separate duplicated blocks between them, totalling at least 119 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"c-level-advisor/skills/vpe-advisor/scripts/delivery_throughput_analyzer.py"},"region":{"startLine":202}}}],"partialFingerprints":{"codehealthFindingId/v1":"ccfd0b30e2d72be4b0acb2b92ae1389dbd7fd9102f4c84399b33298b1851b75e"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 8): c-level-advisor/chief-ai-officer-advisor/skills/chief-ai-officer-advisor/scripts/ai_cost_economics.py:250-256 | c-level-advisor/chief-ai-officer-advisor/skills/chief-ai-officer-advisor/scripts/ai_risk_classifier.py:359-365 | c-level-advisor/chief-ai-officer-advisor/skills/chief-ai-officer-advisor/scripts/model_buildvsbuy_calculator.py:272-278 | c-level-advisor/chief-data-officer-advisor/skills/chief-data-officer-advisor/scripts/data_asset_valuator.py:274-280 | c-level-advisor/skills/chief-ai-officer-advisor/scripts/ai_cost_economics.py:250-256 | c-level-advisor/skills/chief-ai-officer-advisor/scripts/ai_risk_classifier.py:359-365 | c-level-advisor/skills/chief-ai-officer-advisor/scripts/model_buildvsbuy_calculator.py:272-278 | c-level-advisor/skills/chief-data-officer-advisor/scripts/data_asset_valuator.py:274-280 \u2014 the copies span different directories, so extracting a shared function means choosing where it lives: put it somewhere all 8 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 8 times."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"c-level-advisor/chief-ai-officer-advisor/skills/chief-ai-officer-advisor/scripts/ai_cost_economics.py"},"region":{"startLine":250}}}],"partialFingerprints":{"codehealthFindingId/v1":"b94522a6fea0055703a4e2f8a8f1cf296835a964252ec57a61d4af4c8635d2d8"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 8): engineering-team/skills/senior-backend/scripts/backend_decision_engine.py:238-244 | engineering-team/skills/senior-backend/scripts/backend_decision_engine.py:245-251 | engineering-team/skills/senior-backend/scripts/backend_decision_engine.py:252-258 | engineering-team/skills/senior-frontend/scripts/frontend_decision_engine.py:191-197 | engineering-team/skills/senior-frontend/scripts/frontend_decision_engine.py:198-204 | engineering-team/skills/senior-fullstack/scripts/fullstack_decision_engine.py:236-242 | engineering-team/skills/senior-fullstack/scripts/fullstack_decision_engine.py:243-249 | engineering-team/skills/senior-fullstack/scripts/fullstack_decision_engine.py:250-256 \u2014 before extracting anything, compare \u0060engineering-team/skills/senior-backend/scripts/backend_decision_engine.py\u0060 and \u0060engineering-team/skills/senior-frontend/scripts/frontend_decision_engine.py\u0060 as WHOLE FILES: this scan already matched 6 separate duplicated blocks between them, totalling at least 99 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/skills/senior-backend/scripts/backend_decision_engine.py"},"region":{"startLine":238}}}],"partialFingerprints":{"codehealthFindingId/v1":"8b0ff937da490734985414d58173574049579d0b6e9e5a98ec1ea2a638d1efc5"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 6): business-growth/skills/sales-engineer/scripts/competitive_matrix_builder.py:56-62 | business-growth/skills/sales-engineer/scripts/poc_planner.py:143-149 | business-growth/skills/sales-engineer/scripts/rfp_response_analyzer.py:62-68 | engineering/skills/secrets-vault-manager/scripts/rotation_planner.py:62-68 | ra-qm-team/skills/soc2-compliance/scripts/evidence_tracker.py:38-44 | ra-qm-team/skills/soc2-compliance/scripts/gap_analyzer.py:128-134 \u2014 the copies span different directories, so extracting a shared function means choosing where it lives: put it somewhere all 6 call sites can already reach \u2014 a location they all depend on today, or a new shared one if there is none \u2014 and call it from each site; until then, every change has to be made 6 times."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"business-growth/skills/sales-engineer/scripts/competitive_matrix_builder.py"},"region":{"startLine":56}}}],"partialFingerprints":{"codehealthFindingId/v1":"e6dd219eb43b3314bac72e6db318d7b570356315ddcf79d595b875bc671161f7"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 6): markdown-html/skills/design-system/scripts/config_loader.py:80-86 | productivity/handoff/skills/handoff/scripts/config_loader.py:59-65 | research-ops/skills/clinical-research/scripts/config_loader.py:60-66 | research-ops/skills/market-research/scripts/config_loader.py:55-61 | research-ops/skills/product-research/scripts/config_loader.py:55-61 | research-ops/skills/research-finance/scripts/config_loader.py:56-62 \u2014 before extracting anything, compare \u0060markdown-html/skills/design-system/scripts/config_loader.py\u0060 and \u0060research-ops/skills/clinical-research/scripts/config_loader.py\u0060 as WHOLE FILES: this scan already matched 6 separate duplicated blocks between them, totalling at least 60 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The \u0060return\u0060 at the foot of the matched lines is the enclosing body\u0027s own terminal exit, not an early one: it moves with them unchanged, and each site calls the extracted unit from the position that \u0060return\u0060 occupied \u2014 no decision has to be handed back and re-acted on."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"markdown-html/skills/design-system/scripts/config_loader.py"},"region":{"startLine":80}}}],"partialFingerprints":{"codehealthFindingId/v1":"3376e000056a559119980947648e8cdb260aa4f96fc0b7d93c1a2fbb06429d82"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 6): markdown-html/skills/design-system/scripts/config_loader.py:121-127 | productivity/handoff/skills/handoff/scripts/config_loader.py:129-135 | research-ops/skills/clinical-research/scripts/config_loader.py:101-107 | research-ops/skills/market-research/scripts/config_loader.py:92-98 | research-ops/skills/product-research/scripts/config_loader.py:92-98 | research-ops/skills/research-finance/scripts/config_loader.py:93-99 \u2014 before extracting anything, compare \u0060markdown-html/skills/design-system/scripts/config_loader.py\u0060 and \u0060research-ops/skills/clinical-research/scripts/config_loader.py\u0060 as WHOLE FILES: this scan already matched 6 separate duplicated blocks between them, totalling at least 60 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"markdown-html/skills/design-system/scripts/config_loader.py"},"region":{"startLine":121}}}],"partialFingerprints":{"codehealthFindingId/v1":"0cd6213a43f3768bb03fcc4d79ef5aa450a37d584510a2f528d4649bc393726f"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 5): business-growth/skills/revenue-operations/scripts/forecast_accuracy_tracker.py:508-514 | business-growth/skills/revenue-operations/scripts/gtm_efficiency_calculator.py:630-636 | business-growth/skills/revenue-operations/scripts/pipeline_analyzer.py:501-507 | c-level-advisor/skills/coo-advisor/scripts/okr_tracker.py:731-737 | c-level-advisor/skills/coo-advisor/scripts/ops_efficiency_analyzer.py:802-808 \u2014 the copies span different directories, so extracting a shared function means choosing where it lives: put it somewhere all 5 call sites can already reach \u2014 a location they all depend on today, or a new shared one if there is none \u2014 and call it from each site; until then, every change has to be made 5 times."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"business-growth/skills/revenue-operations/scripts/forecast_accuracy_tracker.py"},"region":{"startLine":508}}}],"partialFingerprints":{"codehealthFindingId/v1":"90f0077221c489961d790e5f77677fe47a13cb8643519ff4a818b23f5264193c"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (3\u20137 lines \u00D7 6): business-growth/skills/revenue-operations/scripts/gtm_efficiency_calculator.py:546-552 | business-growth/skills/revenue-operations/scripts/gtm_efficiency_calculator.py:558-564 | business-growth/skills/revenue-operations/scripts/gtm_efficiency_calculator.py:567-573 | business-growth/skills/revenue-operations/scripts/gtm_efficiency_calculator.py:576-582 | business-growth/skills/revenue-operations/scripts/gtm_efficiency_calculator.py:585-591 | business-growth/skills/revenue-operations/scripts/gtm_efficiency_calculator.py:595-597 \u2014 all 6 copies are in the same file, so extract the block into one function there and call it from every one of those sites \u2014 resolving only two of them leaves the rest to drift apart the first time one is edited."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"business-growth/skills/revenue-operations/scripts/gtm_efficiency_calculator.py"},"region":{"startLine":546}}}],"partialFingerprints":{"codehealthFindingId/v1":"80d42e22df607a4f65dab292ffaab24cf8d9cdf15dbcf996cbd53ccef39ed8d6"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 5): c-level-advisor/skills/cpo-advisor/scripts/pmf_scorer.py:233-240 | c-level-advisor/skills/cpo-advisor/scripts/pmf_scorer.py:247-253 | c-level-advisor/skills/cpo-advisor/scripts/pmf_scorer.py:325-331 | c-level-advisor/skills/cpo-advisor/scripts/pmf_scorer.py:338-344 | c-level-advisor/skills/cpo-advisor/scripts/pmf_scorer.py:351-357 \u2014 all 5 copies are in the same file, so extract the block into one function there and call it from every one of those sites \u2014 resolving only two of them leaves the rest to drift apart the first time one is edited."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"c-level-advisor/skills/cpo-advisor/scripts/pmf_scorer.py"},"region":{"startLine":233}}}],"partialFingerprints":{"codehealthFindingId/v1":"00fca8f1c392458fd492d91a7a076abadaec378e294d273bb0e7086b9d089e59"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6\u20137 lines \u00D7 5): marketing/linkedin/skills/linkedin-profile/scripts/headline_scorer.py:257-262 | marketing/linkedin/skills/linkedin-skills/scripts/linkedin_goal_router.py:116-122 | marketing/linkedin/skills/linkedin-skills/scripts/linkedin_policy_gate.py:289-295 | product-team/skills/product-skills/scripts/product_goal_router.py:150-155 | project-management/skills/pm-skills/scripts/pm_goal_router.py:121-127 \u2014 before extracting anything, compare \u0060marketing/linkedin/skills/linkedin-skills/scripts/linkedin_goal_router.py\u0060 and \u0060product-team/skills/product-skills/scripts/product_goal_router.py\u0060 as WHOLE FILES: this scan already matched 8 separate duplicated blocks between them, totalling at least 79 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. Read the line range as the matched WINDOW rather than a finished unit: at \u0060marketing/linkedin/skills/linkedin-skills/scripts/linkedin_goal_router.py:116\u0060 it begins part-way through the construct above it, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that. \u2605 These copies have DRIFTED, and that is worth reading before extracting anything: just after the matched lines, \u0060marketing/linkedin/skills/linkedin-profile/scripts/headline_scorer.py:263\u0060 calls \u0060add_argument\u0060 and \u0060marketing/linkedin/skills/linkedin-skills/scripts/linkedin_goal_router.py:123\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":"marketing/linkedin/skills/linkedin-profile/scripts/headline_scorer.py"},"region":{"startLine":257}}}],"partialFingerprints":{"codehealthFindingId/v1":"787b6bd18dda5ca8d7b39df8c97481800c6011513b9572641ca8ff7b29d40ef1"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 4): business-operations/skills/internal-comms/scripts/change_announcement_builder.py:314-320 | business-operations/skills/internal-comms/scripts/comms_calendar_builder.py:272-278 | business-operations/skills/internal-comms/scripts/comms_template_filler.py:325-331 | business-operations/skills/process-mapper/scripts/cycle_time_analyzer.py:207-213 \u2014 the copies span different directories, so extracting a shared function means choosing where it lives: put it somewhere all 4 call sites can already reach \u2014 a location they all depend on today, or a new shared one if there is none \u2014 and call it from each site; until then, every change has to be made 4 times. Read the line range as the matched WINDOW rather than a finished unit: at \u0060business-operations/skills/internal-comms/scripts/change_announcement_builder.py:314\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":"business-operations/skills/internal-comms/scripts/change_announcement_builder.py"},"region":{"startLine":314}}}],"partialFingerprints":{"codehealthFindingId/v1":"ad9e8ce873b219409120ef310542a3f432ae21234a0d27cf8ee6aa9304df1073"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 4): c-level-advisor/skills/vpe-advisor/scripts/eng_team_structure_designer.py:232-238 | c-level-advisor/vpe-advisor/skills/vpe-advisor/scripts/eng_team_structure_designer.py:232-238 | ra-qm-team/compliance-team-iso42001/skills/iso42001-specialist/scripts/ai_risk_register_builder.py:211-218 | ra-qm-team/skills/iso42001-specialist/scripts/ai_risk_register_builder.py:211-218 \u2014 before extracting anything, compare \u0060c-level-advisor/skills/vpe-advisor/scripts/eng_team_structure_designer.py\u0060 and \u0060c-level-advisor/vpe-advisor/skills/vpe-advisor/scripts/eng_team_structure_designer.py\u0060 as WHOLE FILES: this scan already matched 11 separate duplicated blocks between them, totalling at least 223 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"c-level-advisor/skills/vpe-advisor/scripts/eng_team_structure_designer.py"},"region":{"startLine":232}}}],"partialFingerprints":{"codehealthFindingId/v1":"4dc4c73962622c242b5c6eb9f8319caab3b0a38192c417221ef3f8c301a32fc1"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 4): engineering/skills/agent-designer/agent_evaluator.py:1117-1123 | engineering/skills/agent-designer/tool_schema_generator.py:855-861 | engineering/skills/dependency-auditor/scripts/license_checker.py:961-969 | engineering/skills/observability-designer/scripts/alert_optimizer.py:1015-1023 \u2014 the copies span different directories, so extracting a shared function means choosing where it lives: put it somewhere all 4 call sites can already reach \u2014 a location they all depend on today, or a new shared one if there is none \u2014 and call it from each site; until then, every change has to be made 4 times. Read the line range as the matched WINDOW rather than a finished unit: at \u0060engineering/skills/dependency-auditor/scripts/license_checker.py:961\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":"engineering/skills/agent-designer/agent_evaluator.py"},"region":{"startLine":1117}}}],"partialFingerprints":{"codehealthFindingId/v1":"094ffa833b1a83d760fbdf971b15e6d7b473e7f562c5eae7ac63ea3ae40226ad"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 4): marketing/linkedin/skills/linkedin-engagement/scripts/outreach_message_builder.py:233-239 | marketing/linkedin/skills/linkedin-profile/scripts/about_section_builder.py:249-255 | marketing/linkedin/skills/linkedin-profile/scripts/profile_completeness_auditor.py:253-259 | marketing/linkedin/skills/linkedin-strategy/scripts/positioning_brief.py:270-276 \u2014 the copies span different directories, so extracting a shared function means choosing where it lives: put it somewhere all 4 call sites can already reach \u2014 a location they all depend on today, or a new shared one if there is none \u2014 and call it from each site; until then, every change has to be made 4 times. Read the line range as the matched WINDOW rather than a finished unit: at \u0060marketing/linkedin/skills/linkedin-engagement/scripts/outreach_message_builder.py:233\u0060 it begins part-way through the construct above it, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that. The \u0060return\u0060 at the foot of the matched lines is the enclosing body\u0027s own terminal exit, not an early one: it moves with them unchanged, and each site calls the extracted unit from the position that \u0060return\u0060 occupied \u2014 no decision has to be handed back and re-acted on."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"marketing/linkedin/skills/linkedin-engagement/scripts/outreach_message_builder.py"},"region":{"startLine":233}}}],"partialFingerprints":{"codehealthFindingId/v1":"67e8841a2831ff9489b8fe8cff67068559bb12317e6cc3497d97a03eeadfa050"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 3): compliance-os/skills/compliance-os/scripts/evidence_pool_generator.py:298-304 | ra-qm-team/compliance-team-iso42001/skills/iso42001-specialist/scripts/ai_risk_register_builder.py:197-203 | ra-qm-team/skills/iso42001-specialist/scripts/ai_risk_register_builder.py:197-203 \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":"compliance-os/skills/compliance-os/scripts/evidence_pool_generator.py"},"region":{"startLine":298}}}],"partialFingerprints":{"codehealthFindingId/v1":"82297a6a885c68ce11f9b073f4f73bacfb21c09bdab48a8d7bba28b469efe9e7"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 3): engineering-team/skills/senior-backend/scripts/database_migration_tool.py:325-331 | engineering-team/skills/senior-backend/scripts/database_migration_tool.py:340-346 | engineering-team/skills/senior-backend/scripts/database_migration_tool.py:359-365 \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":"engineering-team/skills/senior-backend/scripts/database_migration_tool.py"},"region":{"startLine":325}}}],"partialFingerprints":{"codehealthFindingId/v1":"a1ee025507387700fe6670b145185416aec2c504770fec41361f958fd38867ba"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 3): research/grants/skills/grants/scripts/citation_tracker.py:289-295 | research/litreview/skills/litreview/scripts/citation_tracker.py:245-251 | research/syllabus/skills/syllabus/scripts/citation_tracker.py:203-209 \u2014 before extracting anything, compare \u0060research/grants/skills/grants/scripts/citation_tracker.py\u0060 and \u0060research/litreview/skills/litreview/scripts/citation_tracker.py\u0060 as WHOLE FILES: this scan already matched 7 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. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"research/grants/skills/grants/scripts/citation_tracker.py"},"region":{"startLine":289}}}],"partialFingerprints":{"codehealthFindingId/v1":"df15f295a84fa6de5a46f49726e3efea0f3ae5c346fa5905bbe6a95941ab588f"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 2): agent-launcher/skills/run-without-you/scripts/next_directions_writer.py:82-88 | agent-launcher/skills/wrap-up/scripts/overview_page.py:89-95 \u2014 the copies span different directories, so extracting a shared function means choosing where it lives: put it somewhere both call sites can already reach \u2014 a location they all depend on today, or a new shared one if there is none \u2014 and call it from each site; until then, every change has to be made twice. \u2605 These copies have DRIFTED, and that is worth reading before extracting anything: just before the matched lines, \u0060agent-launcher/skills/wrap-up/scripts/overview_page.py:88\u0060 calls \u0060add_argument\u0060 and \u0060agent-launcher/skills/run-without-you/scripts/next_directions_writer.py:81\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":"agent-launcher/skills/run-without-you/scripts/next_directions_writer.py"},"region":{"startLine":82}}}],"partialFingerprints":{"codehealthFindingId/v1":"c0a64d4528375093ba854407cb2fb3ddc100a0f80e0a677290e823d96cd08e45"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 2): business-growth/skills/customer-success-manager/scripts/health_score_calculator.py:366-372 | marketing-skill/skills/campaign-analytics/scripts/campaign_roi_calculator.py:395-401 \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":"business-growth/skills/customer-success-manager/scripts/health_score_calculator.py"},"region":{"startLine":366}}}],"partialFingerprints":{"codehealthFindingId/v1":"6c0dc1812f8146da8eae6e9da3c3a9907b796a69fd37f027aa2cf0892900e06b"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 2): business-growth/skills/revenue-operations/scripts/pipeline_analyzer.py:408-415 | engineering/caveman/skills/caveman/scripts/caveman_lint.py:141-147 \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":"business-growth/skills/revenue-operations/scripts/pipeline_analyzer.py"},"region":{"startLine":408}}}],"partialFingerprints":{"codehealthFindingId/v1":"6768143e7eedae0c3dcbba770bbdf60b252ef08038bf0218339d35b3e6068174"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6\u20137 lines \u00D7 2): business-growth/skills/sales-engineer/scripts/poc_planner.py:699-705 | research/litreview/skills/litreview/scripts/framework_recommender.py:163-168 \u2014 the copies span different directories, so extracting a shared function means choosing where it lives: put it somewhere both call sites can already reach \u2014 a location they all depend on today, or a new shared one if there is none \u2014 and call it from each site; until then, every change has to be made twice. \u2605 These copies have DRIFTED, and that is worth reading before extracting anything: just after the matched lines, \u0060research/litreview/skills/litreview/scripts/framework_recommender.py:169\u0060 calls \u0060sum\u0060, \u0060values\u0060, \u0060join\u0060 and \u0060business-growth/skills/sales-engineer/scripts/poc_planner.py:706\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":"business-growth/skills/sales-engineer/scripts/poc_planner.py"},"region":{"startLine":699}}}],"partialFingerprints":{"codehealthFindingId/v1":"65a655cd0a08ffebd760f001e799db4369872abab0b49956c6d625debf75b8ca"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 2): c-level-advisor/chief-ai-officer-advisor/skills/chief-ai-officer-advisor/scripts/ai_cost_economics.py:296-302 | c-level-advisor/skills/chief-ai-officer-advisor/scripts/ai_cost_economics.py:296-302 \u2014 before extracting anything, compare \u0060c-level-advisor/chief-ai-officer-advisor/skills/chief-ai-officer-advisor/scripts/ai_cost_economics.py\u0060 and \u0060c-level-advisor/skills/chief-ai-officer-advisor/scripts/ai_cost_economics.py\u0060 as WHOLE FILES: this scan already matched 11 separate duplicated blocks between them, totalling at least 231 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The \u0060return\u0060 at the foot of the matched lines is the enclosing body\u0027s own terminal exit, not an early one: it moves with them unchanged, and each site calls the extracted unit from the position that \u0060return\u0060 occupied \u2014 no decision has to be handed back and re-acted on."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"c-level-advisor/chief-ai-officer-advisor/skills/chief-ai-officer-advisor/scripts/ai_cost_economics.py"},"region":{"startLine":296}}}],"partialFingerprints":{"codehealthFindingId/v1":"d60d8cec4b072cf287a20aa1f7fcf56a1274c7597336aec9e89a062cb6db96b0"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 2): c-level-advisor/chief-ai-officer-advisor/skills/chief-ai-officer-advisor/scripts/ai_risk_classifier.py:404-410 | c-level-advisor/skills/chief-ai-officer-advisor/scripts/ai_risk_classifier.py:404-410 \u2014 before extracting anything, compare \u0060c-level-advisor/chief-ai-officer-advisor/skills/chief-ai-officer-advisor/scripts/ai_risk_classifier.py\u0060 and \u0060c-level-advisor/skills/chief-ai-officer-advisor/scripts/ai_risk_classifier.py\u0060 as WHOLE FILES: this scan already matched 11 separate duplicated blocks between them, totalling at least 356 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"c-level-advisor/chief-ai-officer-advisor/skills/chief-ai-officer-advisor/scripts/ai_risk_classifier.py"},"region":{"startLine":404}}}],"partialFingerprints":{"codehealthFindingId/v1":"3ac13cf41923ac9670904546cfcc638df65001c12cec6da5df62cf8c3f62a58d"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 2): c-level-advisor/chief-data-officer-advisor/skills/chief-data-officer-advisor/scripts/data_product_strategy_picker.py:271-277 | c-level-advisor/skills/chief-data-officer-advisor/scripts/data_product_strategy_picker.py:271-277 \u2014 before extracting anything, compare \u0060c-level-advisor/chief-data-officer-advisor/skills/chief-data-officer-advisor/scripts/data_product_strategy_picker.py\u0060 and \u0060c-level-advisor/skills/chief-data-officer-advisor/scripts/data_product_strategy_picker.py\u0060 as WHOLE FILES: this scan already matched 9 separate duplicated blocks between them, totalling at least 282 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"c-level-advisor/chief-data-officer-advisor/skills/chief-data-officer-advisor/scripts/data_product_strategy_picker.py"},"region":{"startLine":271}}}],"partialFingerprints":{"codehealthFindingId/v1":"cae7c4407814809648058f5d3566e3134e984676937d8afb985b0cc9073c8a52"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 2): c-level-advisor/general-counsel-advisor/skills/general-counsel-advisor/scripts/term_sheet_analyzer.py:362-368 | c-level-advisor/skills/general-counsel-advisor/scripts/term_sheet_analyzer.py:362-368 \u2014 before extracting anything, compare \u0060c-level-advisor/general-counsel-advisor/skills/general-counsel-advisor/scripts/term_sheet_analyzer.py\u0060 and \u0060c-level-advisor/skills/general-counsel-advisor/scripts/term_sheet_analyzer.py\u0060 as WHOLE FILES: this scan already matched 6 separate duplicated blocks between them, totalling at least 323 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The \u0060return\u0060 at the foot of the matched lines is the enclosing body\u0027s own terminal exit, not an early one: it moves with them unchanged, and each site calls the extracted unit from the position that \u0060return\u0060 occupied \u2014 no decision has to be handed back and re-acted on."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"c-level-advisor/general-counsel-advisor/skills/general-counsel-advisor/scripts/term_sheet_analyzer.py"},"region":{"startLine":362}}}],"partialFingerprints":{"codehealthFindingId/v1":"94e31a6e09e7a1c8e216d5dafdc8e792589e9cea576f6a15073304b5893af522"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 2): c-level-advisor/skills/coo-advisor/scripts/okr_tracker.py:483-489 | c-level-advisor/skills/coo-advisor/scripts/okr_tracker.py:503-509 \u2014 both copies are in the same file, so extract the block 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":"c-level-advisor/skills/coo-advisor/scripts/okr_tracker.py"},"region":{"startLine":483}}}],"partialFingerprints":{"codehealthFindingId/v1":"ae8c6f8ac8d751784742757c8d9dd91656e56ef808364ccdf55dcd49a9c1f850"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (2\u20137 lines \u00D7 3): c-level-advisor/skills/coo-advisor/scripts/okr_tracker.py:460-461 | c-level-advisor/skills/coo-advisor/scripts/okr_tracker.py:492-497 | c-level-advisor/skills/coo-advisor/scripts/okr_tracker.py:511-517 \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 \u0060c-level-advisor/skills/coo-advisor/scripts/okr_tracker.py:511\u0060 it does not close everything it opens, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that. Note that the copies do not run to the end of the range shown: their LAST lines are different code, not the same code under different names \u2014 the matched region ends inside that line. Extract the lines above it, and read the last line of each site separately. \u2605 These copies have DRIFTED, and that is worth reading before extracting anything: just before the matched lines, \u0060c-level-advisor/skills/coo-advisor/scripts/okr_tracker.py:492\u0060 calls \u0060get\u0060 and \u0060c-level-advisor/skills/coo-advisor/scripts/okr_tracker.py:460\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":"c-level-advisor/skills/coo-advisor/scripts/okr_tracker.py"},"region":{"startLine":460}}}],"partialFingerprints":{"codehealthFindingId/v1":"71e08e9b05f2db5287bff79fda9799906b51cf0f66b7a54b1d14592f72dd8043"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 2): commercial/skills/rfp-responder/scripts/response_drafter.py:261-267 | commercial/skills/rfp-responder/scripts/rfp_parser.py:274-280 \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":"commercial/skills/rfp-responder/scripts/response_drafter.py"},"region":{"startLine":261}}}],"partialFingerprints":{"codehealthFindingId/v1":"69241cb4143c648c4cf3a92080e06403f4732aecb3dce5d06824fe28e67f9a9b"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 2): engineering-team/skills/ai-security/scripts/ai_threat_scanner.py:517-523 | engineering-team/skills/threat-detection/scripts/threat_signal_analyzer.py:529-535 \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":"engineering-team/skills/ai-security/scripts/ai_threat_scanner.py"},"region":{"startLine":517}}}],"partialFingerprints":{"codehealthFindingId/v1":"add659bf998aae650f53b4826c90175fe0e216ed1dc4ca469f458865441f0d0c"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 2): engineering-team/skills/cloud-security/scripts/cloud_posture_check.py:1035-1041 | engineering-team/skills/incident-response/scripts/incident_triage.py:663-669 \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":"engineering-team/skills/cloud-security/scripts/cloud_posture_check.py"},"region":{"startLine":1035}}}],"partialFingerprints":{"codehealthFindingId/v1":"75bed7684c3c4ad8164443d11e7d5850f7706768b0340a74f49a56cd494d7047"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 2): engineering-team/skills/gcp-cloud-architect/scripts/architecture_designer.py:786-792 | engineering-team/skills/gcp-cloud-architect/scripts/cost_optimizer.py:444-450 \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":"engineering-team/skills/gcp-cloud-architect/scripts/architecture_designer.py"},"region":{"startLine":786}}}],"partialFingerprints":{"codehealthFindingId/v1":"f0909a016024983d61537e4e2daec22c9e46a3a188497cb348e9c640899eaa70"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5\u20137 lines \u00D7 2): engineering-team/skills/incident-commander/scripts/pir_generator.py:654-658 | product-team/skills/product-manager-toolkit/scripts/customer_interview_analyzer.py:284-290 \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. 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":"engineering-team/skills/incident-commander/scripts/pir_generator.py"},"region":{"startLine":654}}}],"partialFingerprints":{"codehealthFindingId/v1":"89aecf4ee22b694fa26fba390f1fb30a361b221e41672d9e3cbd4e3bdc8eb79d"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 2): engineering-team/skills/security-pen-testing/scripts/pentest_report_generator.py:418-424 | engineering-team/skills/security-pen-testing/scripts/vulnerability_scanner.py:501-507 \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 \u0060engineering-team/skills/security-pen-testing/scripts/pentest_report_generator.py:418\u0060 it begins part-way through the construct above it, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/skills/security-pen-testing/scripts/pentest_report_generator.py"},"region":{"startLine":418}}}],"partialFingerprints":{"codehealthFindingId/v1":"fe8fd55f3565addd0a8c0eb8225c9d94339c63dfc063a2146ba39c6d473c43e6"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 2): engineering-team/skills/senior-architect/scripts/architecture_diagram_generator.py:269-275 | engineering-team/skills/senior-architect/scripts/architecture_diagram_generator.py:380-386 \u2014 both copies are in the same file, so extract the block 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 \u0060engineering-team/skills/senior-architect/scripts/architecture_diagram_generator.py:380\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":"engineering-team/skills/senior-architect/scripts/architecture_diagram_generator.py"},"region":{"startLine":269}}}],"partialFingerprints":{"codehealthFindingId/v1":"440e00b0c9b641c479e50b1e05d56867523bab157412f95d504d523ae1bfdfd5"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 2): engineering-team/skills/senior-devops/scripts/deployment_manager.py:263-269 | engineering-team/skills/senior-devops/scripts/terraform_scaffolder.py:480-486 \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":"engineering-team/skills/senior-devops/scripts/deployment_manager.py"},"region":{"startLine":263}}}],"partialFingerprints":{"codehealthFindingId/v1":"0ede5646939b92a078117af1eb232f509669f77158e18bd61f272d8a58a99274"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 2): engineering-team/skills/senior-secops/scripts/security_scanner.py:388-394 | engineering-team/skills/senior-secops/scripts/vulnerability_assessor.py:473-479 \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":"engineering-team/skills/senior-secops/scripts/security_scanner.py"},"region":{"startLine":388}}}],"partialFingerprints":{"codehealthFindingId/v1":"f6c7628fdc977b0b424d402025fb5038946e18b2541f1b8ce8a4bc6881191b4d"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 2): engineering-team/skills/threat-detection/scripts/threat_signal_analyzer.py:172-178 | engineering-team/skills/threat-detection/scripts/threat_signal_analyzer.py:275-281 \u2014 both copies are in the same file, so extract the block 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":"engineering-team/skills/threat-detection/scripts/threat_signal_analyzer.py"},"region":{"startLine":172}}}],"partialFingerprints":{"codehealthFindingId/v1":"f888965a8278df627d7336b7eed4662a09a006e3dc090574af867b629e6a3b32"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 2): engineering/llm-wiki/skills/llm-wiki/scripts/graph_analyzer.py:33-39 | engineering/llm-wiki/skills/llm-wiki/scripts/lint_wiki.py:53-59 \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":"engineering/llm-wiki/skills/llm-wiki/scripts/graph_analyzer.py"},"region":{"startLine":33}}}],"partialFingerprints":{"codehealthFindingId/v1":"a85e4d53429dabc342c45bf5838510a0a130c6cf9b67c6036aa889ec944cacd8"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 2): engineering/memory-engineering/skills/memory-engineering/scripts/memory_cost_profiler.py:293-299 | engineering/memory-engineering/skills/memory-engineering/scripts/memory_density_auditor.py:591-598 \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 \u0060engineering/memory-engineering/skills/memory-engineering/scripts/memory_cost_profiler.py:293\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":"engineering/memory-engineering/skills/memory-engineering/scripts/memory_cost_profiler.py"},"region":{"startLine":293}}}],"partialFingerprints":{"codehealthFindingId/v1":"7e80dd9a4616d61a375ddbcbf5a580c557e21699a7666f7254bfe63fcea6dd95"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 2): engineering/skill-doctor/skills/skill-doctor/scripts/collect_sessions.py:203-209 | engineering/skill-doctor/skills/skill-doctor/scripts/collect_sessions.py:662-668 \u2014 both copies are in the same file, so extract the block 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, \u0060engineering/skill-doctor/skills/skill-doctor/scripts/collect_sessions.py:202\u0060 calls \u0060rglob\u0060, \u0060is_dir\u0060 and \u0060engineering/skill-doctor/skills/skill-doctor/scripts/collect_sessions.py:661\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":"engineering/skill-doctor/skills/skill-doctor/scripts/collect_sessions.py"},"region":{"startLine":203}}}],"partialFingerprints":{"codehealthFindingId/v1":"9a426a1f8c020f05569640a575c598e2bdf5eb4a69176fee537717ad2d790baa"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 2): engineering/skills/interview-system-designer/question_bank_generator.py:889-895 | engineering/skills/migration-architect/scripts/rollback_generator.py:967-973 \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":"engineering/skills/interview-system-designer/question_bank_generator.py"},"region":{"startLine":889}}}],"partialFingerprints":{"codehealthFindingId/v1":"2d10b764ea3c82e361a4020838768e7703c37963b8d95caedc57474d7954228f"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 2): engineering/skills/ship-gate/scripts/ship_gate_scanner.py:203-209 | engineering/skills/ship-gate/scripts/ship_gate_scanner.py:589-595 \u2014 both copies are in the same file, so extract the block into one function there and call it from each site \u2014 the copies drift apart the first time only one of them is edited. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/ship-gate/scripts/ship_gate_scanner.py"},"region":{"startLine":203}}}],"partialFingerprints":{"codehealthFindingId/v1":"6c0037b3ef671a3d7fa1ad2e38646757e864a10b5e8eb00b47b8024366caed67"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 2): engineering/skills/ship-gate/scripts/ship_gate_scanner.py:764-770 | engineering/skills/ship-gate/scripts/ship_gate_scanner.py:878-884 \u2014 both copies are in the same file, so extract the block 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 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":"engineering/skills/ship-gate/scripts/ship_gate_scanner.py"},"region":{"startLine":764}}}],"partialFingerprints":{"codehealthFindingId/v1":"aeac90adfbf17aaa426adf1a361335e23bb13f76e6ad2badd15a3ff395976574"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 2): engineering/skills/skill-tester/scripts/quality_scorer.py:1056-1062 | engineering/skills/skill-tester/scripts/skill_validator.py:579-585 \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. Note first that the copies are not typed on the same thing: the declarations holding them bind \u0060report\u0060 to \u0060QualityReport\u0060 in one and \u0060ValidationReport\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":"engineering/skills/skill-tester/scripts/quality_scorer.py"},"region":{"startLine":1056}}}],"partialFingerprints":{"codehealthFindingId/v1":"0bf58f59597178fb0f218f59720c3791cf14bcf8baf0ec06b412dc215c65655b"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (3\u20137 lines \u00D7 5): engineering/skills/tc-tracker/scripts/tc_create.py:175-178 | engineering/skills/tc-tracker/scripts/tc_init.py:125-128 | engineering/skills/tc-tracker/scripts/tc_status.py:155-161 | engineering/skills/tc-tracker/scripts/tc_status.py:181-187 | engineering/skills/tc-tracker/scripts/tc_update.py:173-175 \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. Note that the copies do not run to the end of the range shown: their LAST lines are different code, not the same code under different names \u2014 the matched region ends inside that line. Extract the lines above it, and read the last line of each site separately. \u2605 These copies have DRIFTED, and that is worth reading before extracting anything: just before the matched lines, \u0060engineering/skills/tc-tracker/scripts/tc_create.py:175\u0060 calls \u0060except\u0060 and \u0060engineering/skills/tc-tracker/scripts/tc_update.py:173\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":"engineering/skills/tc-tracker/scripts/tc_create.py"},"region":{"startLine":175}}}],"partialFingerprints":{"codehealthFindingId/v1":"7d8beb85b975c8b40c0bbfd8acdc4a965d9446fe2dc9a62224a2e05a69ed1745"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 2): finance/skills/financial-analyst/scripts/forecast_builder.py:241-248 | marketing-skill/skills/social-media-analyzer/scripts/calculate_metrics.py:41-47 \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":"finance/skills/financial-analyst/scripts/forecast_builder.py"},"region":{"startLine":241}}}],"partialFingerprints":{"codehealthFindingId/v1":"9ee8d633e08bc2b8ab2633a0ca0d92e1ab9426e5f6a6592b936249aae2b6a7a8"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 2): markdown-html/skills/design-system/scripts/brand_palette_validator.py:293-299 | marketing/landing/skills/landing/scripts/brand_palette_validator.py:229-235 \u2014 before extracting anything, compare \u0060markdown-html/skills/design-system/scripts/brand_palette_validator.py\u0060 and \u0060marketing/landing/skills/landing/scripts/brand_palette_validator.py\u0060 as WHOLE FILES: this scan already matched 12 separate duplicated blocks between them, totalling at least 79 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The \u0060return\u0060 at the foot of the matched lines is the enclosing body\u0027s own terminal exit, not an early one: it moves with them unchanged, and each site calls the extracted unit from the position that \u0060return\u0060 occupied \u2014 no decision has to be handed back and re-acted on. Note first that the copies are not typed on the same thing: the declarations holding them bind \u0060result\u0060 to \u0060dict[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":"markdown-html/skills/design-system/scripts/brand_palette_validator.py"},"region":{"startLine":293}}}],"partialFingerprints":{"codehealthFindingId/v1":"7ecd739cb43baba032a72be217cdf3247f9b1b75113f4d21c05f2d7402299fb1"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 2): markdown-html/skills/md-review/scripts/review_html_renderer.py:583-589 | markdown-html/skills/md-slides/scripts/deck_html_renderer.py:568-574 \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 \u0060markdown-html/skills/md-review/scripts/review_html_renderer.py:583\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":"markdown-html/skills/md-review/scripts/review_html_renderer.py"},"region":{"startLine":583}}}],"partialFingerprints":{"codehealthFindingId/v1":"a51362017b10e6710a9fb87112668c96c423c908c9b218c0a479778a99267cd7"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 2): marketing/linkedin/skills/linkedin-skills/scripts/linkedin_goal_router.py:93-99 | product-team/skills/product-skills/scripts/product_goal_router.py:127-133 \u2014 before extracting anything, compare \u0060marketing/linkedin/skills/linkedin-skills/scripts/linkedin_goal_router.py\u0060 and \u0060product-team/skills/product-skills/scripts/product_goal_router.py\u0060 as WHOLE FILES: this scan already matched 8 separate duplicated blocks between them, totalling at least 79 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The \u0060return\u0060 at the foot of the matched lines is the enclosing body\u0027s own terminal exit, not an early one: it moves with them unchanged, and each site calls the extracted unit from the position that \u0060return\u0060 occupied \u2014 no decision has to be handed back and re-acted on."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"marketing/linkedin/skills/linkedin-skills/scripts/linkedin_goal_router.py"},"region":{"startLine":93}}}],"partialFingerprints":{"codehealthFindingId/v1":"592a5bd208e20b0cefba664c1293a10a65499dbcfa4472e4932f1e66b0c7b6f1"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 2): marketing/linkedin/skills/linkedin-strategy/scripts/positioning_brief.py:229-235 | productivity/andreessen/skills/andreessen/scripts/anti_todo_card.py:123-129 \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":"marketing/linkedin/skills/linkedin-strategy/scripts/positioning_brief.py"},"region":{"startLine":229}}}],"partialFingerprints":{"codehealthFindingId/v1":"4c3723606025fa2c0ae07fef3af8f3f4b9a14eb42f4d5d1a5c9ffe4ef8388151"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 2): product-team/skills/product-manager-toolkit/scripts/customer_interview_analyzer.py:282-288 | product-team/skills/product-manager-toolkit/scripts/customer_interview_analyzer.py:294-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. 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":"product-team/skills/product-manager-toolkit/scripts/customer_interview_analyzer.py"},"region":{"startLine":282}}}],"partialFingerprints":{"codehealthFindingId/v1":"d922c66087e90296199159b8f95ced23ed1f3ae708b31078951ef10e4135651c"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 2): productivity/email/skills/inbox-setup/scripts/section_progress_tracker.py:240-246 | research/dossier/skills/dossier/scripts/citation_tracker.py:280-286 \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":"productivity/email/skills/inbox-setup/scripts/section_progress_tracker.py"},"region":{"startLine":240}}}],"partialFingerprints":{"codehealthFindingId/v1":"9c11c6842b24e3187f02905d77440bafedd40a16e39d770d5ecdc2f96391019c"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 2): ra-qm-team/compliance-team-iso42001/skills/iso42001-specialist/scripts/aims_gap_analyzer.py:208-214 | ra-qm-team/skills/iso42001-specialist/scripts/aims_gap_analyzer.py:208-214 \u2014 before extracting anything, compare \u0060ra-qm-team/compliance-team-iso42001/skills/iso42001-specialist/scripts/aims_gap_analyzer.py\u0060 and \u0060ra-qm-team/skills/iso42001-specialist/scripts/aims_gap_analyzer.py\u0060 as WHOLE FILES: this scan already matched 8 separate duplicated blocks between them, totalling at least 105 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The \u0060return\u0060 at the foot of the matched lines is the enclosing body\u0027s own terminal exit, not an early one: it moves with them unchanged, and each site calls the extracted unit from the position that \u0060return\u0060 occupied \u2014 no decision has to be handed back and re-acted on."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"ra-qm-team/compliance-team-iso42001/skills/iso42001-specialist/scripts/aims_gap_analyzer.py"},"region":{"startLine":208}}}],"partialFingerprints":{"codehealthFindingId/v1":"2f6acd1cb306b59e9150cec9a2df69131223455561547a3fabe6b2994274803d"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 2): ra-qm-team/skills/risk-management-specialist/scripts/risk_matrix_calculator.py:219-225 | ra-qm-team/skills/risk-management-specialist/scripts/risk_matrix_calculator.py:227-233 \u2014 both copies are in the same file, so extract the block 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":"ra-qm-team/skills/risk-management-specialist/scripts/risk_matrix_calculator.py"},"region":{"startLine":219}}}],"partialFingerprints":{"codehealthFindingId/v1":"e7413dd826bf7f87eced6cfd30224814f602431a6ca0fd1516e566294b2f395c"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 2): research-ops/skills/clinical-research/scripts/endpoint_selector.py:147-153 | research-ops/skills/market-research/scripts/segmentation_scorer.py:104-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 \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":"research-ops/skills/clinical-research/scripts/endpoint_selector.py"},"region":{"startLine":147}}}],"partialFingerprints":{"codehealthFindingId/v1":"04c1099cdaf17556ce837a0dc4924e19bf53079d8198f4ad263ed7ded70da2d5"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 2): research/grants/skills/grants/scripts/citation_tracker.py:125-131 | research/grants/skills/grants/scripts/citation_tracker.py:144-150 \u2014 both copies are in the same file, so extract the block 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":"research/grants/skills/grants/scripts/citation_tracker.py"},"region":{"startLine":125}}}],"partialFingerprints":{"codehealthFindingId/v1":"0d7984655be9833d280eed77aa3bf73f0501b14071a5be35d33a472c8e4cd06b"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 2): research/grants/skills/grants/scripts/citation_tracker.py:198-204 | research/litreview/skills/litreview/scripts/citation_tracker.py:163-169 \u2014 before extracting anything, compare \u0060research/grants/skills/grants/scripts/citation_tracker.py\u0060 and \u0060research/litreview/skills/litreview/scripts/citation_tracker.py\u0060 as WHOLE FILES: this scan already matched 7 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. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"research/grants/skills/grants/scripts/citation_tracker.py"},"region":{"startLine":198}}}],"partialFingerprints":{"codehealthFindingId/v1":"1fb1685cad5295fb276cb2dfc0f91b2c02cffc8c5f265539a62cd82a8bea2cea"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 8): productivity/email/skills/inbox-setup/scripts/voice_sample_analyzer.py:267-272 | productivity/email/skills/inbox-triage/scripts/kb_reader.py:281-286 | productivity/reflect/skills/reflect/scripts/bias_pattern_detector.py:174-179 | productivity/reflect/skills/reflect/scripts/conversation_depth_analyzer.py:173-178 | research/dossier/skills/dossier/scripts/disconfirming_evidence_balance.py:183-188 | research/litreview/skills/litreview/scripts/cross_search_aggregator.py:212-217 | research/litreview/skills/litreview/scripts/framework_recommender.py:184-189 | research/patent/skills/patent/scripts/family_resolver.py:233-238 \u2014 the copies span different directories, so extracting a shared function means choosing where it lives: put it somewhere all 8 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 8 times."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"productivity/email/skills/inbox-setup/scripts/voice_sample_analyzer.py"},"region":{"startLine":267}}}],"partialFingerprints":{"codehealthFindingId/v1":"fa92f85f1c2a36a2596fddddc2710d65fa54a905706e54ba39e42eb587b22372"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 6): agent-launcher/skills/grade-iterate/scripts/eval_scaffold.py:54-59 | agent-launcher/skills/run-without-you/scripts/deployment_builder.py:70-75 | agent-launcher/skills/run-without-you/scripts/next_directions_writer.py:84-89 | agent-launcher/skills/wrap-up/scripts/overview_page.py:91-96 | agent-launcher/skills/wrap-up/scripts/primitives_inventory.py:75-80 | agent-launcher/skills/wrap-up/scripts/upgrade_suggester.py:59-64 \u2014 the copies span different directories, so extracting a shared function means choosing where it lives: put it somewhere all 6 call sites can already reach \u2014 a location they all depend on today, or a new shared one if there is none \u2014 and call it from each site; until then, every change has to be made 6 times. \u2605 These copies have DRIFTED, and that is worth reading before extracting anything: just before the matched lines, \u0060agent-launcher/skills/grade-iterate/scripts/eval_scaffold.py:51\u0060 calls \u0060add_argument\u0060 and \u0060agent-launcher/skills/wrap-up/scripts/primitives_inventory.py:73\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":"agent-launcher/skills/grade-iterate/scripts/eval_scaffold.py"},"region":{"startLine":54}}}],"partialFingerprints":{"codehealthFindingId/v1":"282b5fe4b1e3e3f9a99ec37c4e22080fa71ddf0fcb96313c7f87d349888b6ccb"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (4\u20136 lines \u00D7 7): engineering/grill-with-docs/skills/grill-with-docs/scripts/adr_scanner.py:195-200 | engineering/grill-with-docs/skills/grill-with-docs/scripts/context_md_linter.py:235-238 | markdown-html/skills/design-system/scripts/brand_palette_validator.py:286-291 | marketing/landing/skills/landing/scripts/brand_palette_validator.py:222-227 | marketing/landing/skills/landing/scripts/html_validator.py:255-260 | productivity/email/skills/inbox-setup/scripts/kb_validator.py:211-216 | productivity/reflect/skills/reflect/scripts/directional_recommendation_validator.py:205-210 \u2014 before extracting anything, compare \u0060markdown-html/skills/design-system/scripts/brand_palette_validator.py\u0060 and \u0060marketing/landing/skills/landing/scripts/brand_palette_validator.py\u0060 as WHOLE FILES: this scan already matched 12 separate duplicated blocks between them, totalling at least 79 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. Note first that the copies are not typed on the same thing: the declarations holding them bind \u0060result\u0060 to \u0060Dict[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":"engineering/grill-with-docs/skills/grill-with-docs/scripts/adr_scanner.py"},"region":{"startLine":195}}}],"partialFingerprints":{"codehealthFindingId/v1":"9056259226aeec6fbb9f21ab6c7ef6394712569b946863f1d9d0b30bcdc30332"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 5): engineering/skills/skill-tester/assets/sample-skill/scripts/text_processor.py:275-280 | ra-qm-team/compliance-team-eu-ai-act/skills/eu-ai-act-specialist/scripts/ai_act_obligation_tracker.py:207-212 | ra-qm-team/skills/eu-ai-act-specialist/scripts/ai_act_obligation_tracker.py:207-212 | research/litreview/skills/litreview/scripts/citation_tracker.py:167-172 | research/litreview/skills/litreview/scripts/framework_recommender.py:162-167 \u2014 before extracting anything, compare \u0060ra-qm-team/compliance-team-eu-ai-act/skills/eu-ai-act-specialist/scripts/ai_act_obligation_tracker.py\u0060 and \u0060ra-qm-team/skills/eu-ai-act-specialist/scripts/ai_act_obligation_tracker.py\u0060 as WHOLE FILES: this scan already matched 11 separate duplicated blocks between them, totalling at least 122 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/skill-tester/assets/sample-skill/scripts/text_processor.py"},"region":{"startLine":275}}}],"partialFingerprints":{"codehealthFindingId/v1":"e2ac76008d3e405d96860196849a446dcf775f15e5c67238c91d8110a1971e87"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 5): marketing/linkedin/skills/linkedin-analytics/scripts/post_performance_analyzer.py:228-233 | marketing/linkedin/skills/linkedin-engagement/scripts/outreach_message_builder.py:223-228 | marketing/linkedin/skills/linkedin-profile/scripts/about_section_builder.py:238-244 | marketing/linkedin/skills/linkedin-profile/scripts/profile_completeness_auditor.py:241-248 | marketing/linkedin/skills/linkedin-strategy/scripts/positioning_brief.py:260-265 \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 before the matched lines, \u0060marketing/linkedin/skills/linkedin-engagement/scripts/outreach_message_builder.py:220\u0060 calls \u0060add_argument\u0060 and \u0060marketing/linkedin/skills/linkedin-analytics/scripts/post_performance_analyzer.py:227\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":"marketing/linkedin/skills/linkedin-analytics/scripts/post_performance_analyzer.py"},"region":{"startLine":228}}}],"partialFingerprints":{"codehealthFindingId/v1":"bf9d44b0a1fe679ab665b151c8323ff1da51704f4dc3e9dc49b09749e9ebb01e"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 5): research-ops/skills/clinical-research/scripts/endpoint_selector.py:161-166 | research-ops/skills/clinical-research/scripts/phase_gate_scorer.py:210-215 | research-ops/skills/market-research/scripts/segmentation_scorer.py:118-123 | research-ops/skills/research-finance/scripts/capex_vs_opex_router.py:161-166 | research-ops/skills/research-finance/scripts/program_budget_planner.py:140-145 \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 before the matched lines, \u0060research-ops/skills/clinical-research/scripts/phase_gate_scorer.py:209\u0060 calls \u0060add_argument\u0060 and \u0060research-ops/skills/clinical-research/scripts/endpoint_selector.py:160\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":"research-ops/skills/clinical-research/scripts/endpoint_selector.py"},"region":{"startLine":161}}}],"partialFingerprints":{"codehealthFindingId/v1":"779f2bf25bf00dac3a22cfc729171e69c3c12fc0f425aa95a6a3303a8f426cc3"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 4): business-growth/skills/revenue-operations/scripts/pipeline_analyzer.py:393-399 | business-growth/skills/revenue-operations/scripts/pipeline_analyzer.py:410-417 | markdown-html/skills/markdown-html-orchestrator/scripts/route_explainer.py:123-128 | productivity/capture/skills/capture/scripts/complexity_estimator.py:146-151 \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. Read the line range as the matched WINDOW rather than a finished unit: at \u0060business-growth/skills/revenue-operations/scripts/pipeline_analyzer.py:393\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":"business-growth/skills/revenue-operations/scripts/pipeline_analyzer.py"},"region":{"startLine":393}}}],"partialFingerprints":{"codehealthFindingId/v1":"58f27b8fcc847e3cda31410e8db11b379c240e54fb9dded98293ef6776d63c1a"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 4): c-level-advisor/skills/vpe-advisor/scripts/delivery_throughput_analyzer.py:228-233 | c-level-advisor/skills/vpe-advisor/scripts/eng_hiring_funnel_calculator.py:230-235 | c-level-advisor/vpe-advisor/skills/vpe-advisor/scripts/delivery_throughput_analyzer.py:228-233 | c-level-advisor/vpe-advisor/skills/vpe-advisor/scripts/eng_hiring_funnel_calculator.py:230-235 \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."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"c-level-advisor/skills/vpe-advisor/scripts/delivery_throughput_analyzer.py"},"region":{"startLine":228}}}],"partialFingerprints":{"codehealthFindingId/v1":"7da7b42f1616443b332fee750c31c3d375e4300be65e3029bbe6bece2e9fa100"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 4): c-level-advisor/skills/vpe-advisor/scripts/eng_hiring_funnel_calculator.py:194-199 | c-level-advisor/skills/vpe-advisor/scripts/eng_team_structure_designer.py:190-195 | c-level-advisor/vpe-advisor/skills/vpe-advisor/scripts/eng_hiring_funnel_calculator.py:194-199 | c-level-advisor/vpe-advisor/skills/vpe-advisor/scripts/eng_team_structure_designer.py:190-195 \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."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"c-level-advisor/skills/vpe-advisor/scripts/eng_hiring_funnel_calculator.py"},"region":{"startLine":194}}}],"partialFingerprints":{"codehealthFindingId/v1":"c8458a1a89c06705d2d108f521e878b86942e14e5d975082ef571f9f64f32ccd"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 4): c-level-advisor/skills/vpe-advisor/scripts/eng_team_structure_designer.py:232-237 | c-level-advisor/vpe-advisor/skills/vpe-advisor/scripts/eng_team_structure_designer.py:232-237 | ra-qm-team/compliance-team-eu-ai-act/skills/eu-ai-act-specialist/scripts/conformity_assessment_planner.py:248-253 | ra-qm-team/skills/eu-ai-act-specialist/scripts/conformity_assessment_planner.py:248-253 \u2014 before extracting anything, compare \u0060c-level-advisor/skills/vpe-advisor/scripts/eng_team_structure_designer.py\u0060 and \u0060c-level-advisor/vpe-advisor/skills/vpe-advisor/scripts/eng_team_structure_designer.py\u0060 as WHOLE FILES: this scan already matched 11 separate duplicated blocks between them, totalling at least 223 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"c-level-advisor/skills/vpe-advisor/scripts/eng_team_structure_designer.py"},"region":{"startLine":232}}}],"partialFingerprints":{"codehealthFindingId/v1":"9a57692d4d2aff0e186bc1f6b68fa7d916efb5f62df5afddaf0ce829330bbd6c"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 4): engineering-team/skills/senior-architect/scripts/architecture_diagram_generator.py:611-617 | engineering-team/skills/senior-architect/scripts/dependency_analyzer.py:569-575 | engineering-team/skills/senior-architect/scripts/project_architect.py:695-701 | engineering/skills/skill-security-auditor/scripts/skill_security_auditor.py:1043-1048 \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."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/skills/senior-architect/scripts/architecture_diagram_generator.py"},"region":{"startLine":611}}}],"partialFingerprints":{"codehealthFindingId/v1":"fc9706830fb03215f315fcac61d60ec098315e836e8eee8fe443151cd6d2ab82"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 4): markdown-html/skills/design-system/scripts/brand_palette_validator.py:307-312 | marketing/landing/skills/landing/scripts/brand_palette_validator.py:243-248 | marketing/landing/skills/landing/scripts/kebab_slug_generator.py:99-104 | productivity/capture/skills/capture/scripts/workspace_inventory.py:182-187 \u2014 before extracting anything, compare \u0060markdown-html/skills/design-system/scripts/brand_palette_validator.py\u0060 and \u0060marketing/landing/skills/landing/scripts/brand_palette_validator.py\u0060 as WHOLE FILES: this scan already matched 12 separate duplicated blocks between them, totalling at least 79 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. Note first that the copies are not typed on the same thing: the declarations holding them bind \u0060argv\u0060 to \u0060list[str]\u0060 in one and \u0060List[str]\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. \u2605 These copies have DRIFTED, and that is worth reading before extracting anything: just before the matched lines, \u0060markdown-html/skills/design-system/scripts/brand_palette_validator.py:304\u0060 calls \u0060add_argument\u0060 and \u0060marketing/landing/skills/landing/scripts/kebab_slug_generator.py:97\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":"markdown-html/skills/design-system/scripts/brand_palette_validator.py"},"region":{"startLine":307}}}],"partialFingerprints":{"codehealthFindingId/v1":"b111c50b27d5f4d246be480bab152fa4d55f8fe6f76537aa0df170ef6c9882cc"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 4): productivity/andreessen/skills/andreessen/scripts/market_first_evaluator.py:186-191 | productivity/andreessen/skills/andreessen/scripts/pmf_signal_scorer.py:181-186 | productivity/roast/skills/roast/scripts/cheapest_test_designer.py:171-176 | productivity/roast/skills/roast/scripts/verdict_synthesizer.py:222-227 \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."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"productivity/andreessen/skills/andreessen/scripts/market_first_evaluator.py"},"region":{"startLine":186}}}],"partialFingerprints":{"codehealthFindingId/v1":"0c2692763f018b428d13e31eb4eda202a3e80a58325b0952ddb88096435446f1"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (4\u20136 lines \u00D7 5): ra-qm-team/skills/soc2-compliance/scripts/gap_analyzer.py:379-386 | research/dossier/skills/dossier/scripts/citation_tracker.py:199-204 | research/dossier/skills/dossier/scripts/citation_tracker.py:210-213 | research/grants/skills/grants/scripts/citation_tracker.py:200-205 | research/litreview/skills/litreview/scripts/citation_tracker.py:165-170 \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."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"ra-qm-team/skills/soc2-compliance/scripts/gap_analyzer.py"},"region":{"startLine":379}}}],"partialFingerprints":{"codehealthFindingId/v1":"f33e91cf40c8312803e88574f9fd17b7d5677e5aca0251bb720e3e530eb10958"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 4): research-ops/skills/clinical-research/scripts/endpoint_selector.py:160-165 | research-ops/skills/market-research/scripts/market_sizer.py:139-144 | research-ops/skills/market-research/scripts/segmentation_scorer.py:117-122 | research-ops/skills/research-finance/scripts/capex_vs_opex_router.py:160-165 \u2014 the copies span different directories, so extracting a shared function means choosing where it lives: put it somewhere all 4 call sites can already reach \u2014 a location they all depend on today, or a new shared one if there is none \u2014 and call it from each site; until then, every change has to be made 4 times. Read the line range as the matched WINDOW rather than a finished unit: at \u0060research-ops/skills/clinical-research/scripts/endpoint_selector.py:160\u0060 it begins part-way through the construct above it, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that. \u2605 These copies have DRIFTED, and that is worth reading before extracting anything: just before the matched lines, \u0060research-ops/skills/research-finance/scripts/capex_vs_opex_router.py:157\u0060 calls \u0060add_argument\u0060 and \u0060research-ops/skills/clinical-research/scripts/endpoint_selector.py:158\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":"research-ops/skills/clinical-research/scripts/endpoint_selector.py"},"region":{"startLine":160}}}],"partialFingerprints":{"codehealthFindingId/v1":"f17991301a652a549bde84fc350d0775a490bf3f3f92e162d176ce55511e159c"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 3): compliance-os/skills/compliance-os/scripts/cross_framework_mapper.py:364-369 | research/pulse/skills/pulse/scripts/citation_tracker.py:419-424 | research/syllabus/skills/syllabus/scripts/citation_tracker.py:151-156 \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":"compliance-os/skills/compliance-os/scripts/cross_framework_mapper.py"},"region":{"startLine":364}}}],"partialFingerprints":{"codehealthFindingId/v1":"ecb52127101f2c8464eb40a78ed34fccbbf0666e6b04c5a968d54f0855871231"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 3): engineering/grill-with-docs/skills/grill-with-docs/scripts/adr_scanner.py:220-225 | engineering/grill-with-docs/skills/grill-with-docs/scripts/context_md_linter.py:246-251 | productivity/capture/skills/capture/scripts/dump_classifier.py:131-136 \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":"engineering/grill-with-docs/skills/grill-with-docs/scripts/adr_scanner.py"},"region":{"startLine":220}}}],"partialFingerprints":{"codehealthFindingId/v1":"564d2306e03eb299a453502e717686438ce70334ff85f1210725e9253576e442"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 3): engineering/skills/agent-designer/agent_evaluator.py:1145-1150 | engineering/skills/agent-designer/agent_planner.py:881-886 | engineering/skills/agent-designer/tool_schema_generator.py:902-907 \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":"engineering/skills/agent-designer/agent_evaluator.py"},"region":{"startLine":1145}}}],"partialFingerprints":{"codehealthFindingId/v1":"5ec4dd660fc50114913bae6d1486e0c135f483c888e94e74bd6f0a0775fbff46"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 3): engineering/skills/slo-architect/scripts/slo_review.py:155-160 | engineering/slo-architect/skills/slo-architect/scripts/slo_review.py:155-160 | research/research/skills/research/scripts/classifier.py:168-173 \u2014 before extracting anything, compare \u0060engineering/skills/slo-architect/scripts/slo_review.py\u0060 and \u0060engineering/slo-architect/skills/slo-architect/scripts/slo_review.py\u0060 as WHOLE FILES: this scan already matched 9 separate duplicated blocks between them, totalling at least 103 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/slo-architect/scripts/slo_review.py"},"region":{"startLine":155}}}],"partialFingerprints":{"codehealthFindingId/v1":"03811ded48a5e1206a4c1ff94f1a863af0c59ce5a220aa17c619ee767c1dbe53"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 3): markdown-html/skills/md-document/scripts/html_renderer.py:505-510 | markdown-html/skills/md-review/scripts/review_html_renderer.py:402-407 | markdown-html/skills/md-slides/scripts/deck_html_renderer.py:461-466 \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. \u2605 These copies have DRIFTED, and that is worth reading before extracting anything: just after the matched lines, \u0060markdown-html/skills/md-review/scripts/review_html_renderer.py:409\u0060 calls \u0060_derive_danger_color\u0060 and \u0060markdown-html/skills/md-slides/scripts/deck_html_renderer.py:468\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":"markdown-html/skills/md-document/scripts/html_renderer.py"},"region":{"startLine":505}}}],"partialFingerprints":{"codehealthFindingId/v1":"1d3367bb498c57cb5a435f20a6c6df91bcbfcc96588770904a444a1e9931560e"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 3): marketing-skill/skills/copy-editing/scripts/readability_scorer.py:205-210 | marketing-skill/skills/page-cro/scripts/conversion_audit.py:358-363 | marketing-skill/skills/seo-audit/scripts/seo_checker.py:306-311 \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. \u2605 These copies have DRIFTED, and that is worth reading before extracting anything: just before the matched lines, \u0060marketing-skill/skills/page-cro/scripts/conversion_audit.py:356\u0060 calls \u0060add_argument\u0060 and \u0060marketing-skill/skills/copy-editing/scripts/readability_scorer.py:203\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":"marketing-skill/skills/copy-editing/scripts/readability_scorer.py"},"region":{"startLine":205}}}],"partialFingerprints":{"codehealthFindingId/v1":"51737eda557c74ba87c7adfdfcebe9f1a4813af86cf3b51061c98aefc9ff944e"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (4\u20136 lines \u00D7 4): marketing/landing/skills/landing/scripts/html_validator.py:269-274 | productivity/email/skills/inbox-setup/scripts/kb_validator.py:235-238 | productivity/email/skills/inbox-triage/scripts/draft_safety_validator.py:171-176 | productivity/reflect/skills/reflect/scripts/directional_recommendation_validator.py:219-224 \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. Note that the copies do not run to the end of the range shown: their LAST lines are different code, not the same code under different names \u2014 the matched region ends inside that line. Extract the lines above it, and read the last line of each site separately. \u2605 These copies have DRIFTED, and that is worth reading before extracting anything: just before the matched lines, \u0060marketing/landing/skills/landing/scripts/html_validator.py:268\u0060 calls \u0060add_argument\u0060 and \u0060productivity/email/skills/inbox-setup/scripts/kb_validator.py:235\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":"marketing/landing/skills/landing/scripts/html_validator.py"},"region":{"startLine":269}}}],"partialFingerprints":{"codehealthFindingId/v1":"8209c55ea4ee04beeae4c7850618711ed9c818b36a588ede25289edee1a9b4b1"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2): business-growth/skills/sales-engineer/scripts/poc_planner.py:667-672 | commercial/skills/commercial-policy/scripts/discount_matrix_builder.py:230-235 \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":"business-growth/skills/sales-engineer/scripts/poc_planner.py"},"region":{"startLine":667}}}],"partialFingerprints":{"codehealthFindingId/v1":"d85a8e318a9428832fc9a010f3875030b5c42cefd93a0eea5e1780e49b649613"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2): c-level-advisor/arquiteto-de-empresa/skills/arquiteto-de-empresa/scripts/index_generator.py:70-75 | c-level-advisor/skills/arquiteto-de-empresa/scripts/index_generator.py:70-75 \u2014 before extracting anything, compare \u0060c-level-advisor/arquiteto-de-empresa/skills/arquiteto-de-empresa/scripts/index_generator.py\u0060 and \u0060c-level-advisor/skills/arquiteto-de-empresa/scripts/index_generator.py\u0060 as WHOLE FILES: this scan already matched 10 separate duplicated blocks between them, totalling at least 135 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"c-level-advisor/arquiteto-de-empresa/skills/arquiteto-de-empresa/scripts/index_generator.py"},"region":{"startLine":70}}}],"partialFingerprints":{"codehealthFindingId/v1":"291978e6938c28589abd14feb3229750a10cc02f5b72bebea378281cec2bea45"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2): c-level-advisor/arquiteto-de-empresa/skills/arquiteto-de-empresa/scripts/index_generator.py:118-123 | c-level-advisor/skills/arquiteto-de-empresa/scripts/index_generator.py:118-123 \u2014 before extracting anything, compare \u0060c-level-advisor/arquiteto-de-empresa/skills/arquiteto-de-empresa/scripts/index_generator.py\u0060 and \u0060c-level-advisor/skills/arquiteto-de-empresa/scripts/index_generator.py\u0060 as WHOLE FILES: this scan already matched 10 separate duplicated blocks between them, totalling at least 135 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The \u0060return\u0060 at the foot of the matched lines is the enclosing body\u0027s own terminal exit, not an early one: it moves with them unchanged, and each site calls the extracted unit from the position that \u0060return\u0060 occupied \u2014 no decision has to be handed back and re-acted on."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"c-level-advisor/arquiteto-de-empresa/skills/arquiteto-de-empresa/scripts/index_generator.py"},"region":{"startLine":118}}}],"partialFingerprints":{"codehealthFindingId/v1":"609ab7b6bf3c98148e4c175f964e4d2aee40865779f2de09639479b2064575bc"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2): c-level-advisor/arquiteto-de-empresa/skills/arquiteto-de-empresa/scripts/index_generator.py:132-137 | c-level-advisor/skills/arquiteto-de-empresa/scripts/index_generator.py:132-137 \u2014 before extracting anything, compare \u0060c-level-advisor/arquiteto-de-empresa/skills/arquiteto-de-empresa/scripts/index_generator.py\u0060 and \u0060c-level-advisor/skills/arquiteto-de-empresa/scripts/index_generator.py\u0060 as WHOLE FILES: this scan already matched 10 separate duplicated blocks between them, totalling at least 135 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The \u0060return\u0060 at the foot of the matched lines is the enclosing body\u0027s own terminal exit, not an early one: it moves with them unchanged, and each site calls the extracted unit from the position that \u0060return\u0060 occupied \u2014 no decision has to be handed back and re-acted on."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"c-level-advisor/arquiteto-de-empresa/skills/arquiteto-de-empresa/scripts/index_generator.py"},"region":{"startLine":132}}}],"partialFingerprints":{"codehealthFindingId/v1":"5e705b31ed3950fc4ebcebdf1c634d4c3c6a3556f444302f272ad0823030a596"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2): c-level-advisor/chief-data-officer-advisor/skills/chief-data-officer-advisor/scripts/ai_training_data_audit.py:370-375 | c-level-advisor/skills/chief-data-officer-advisor/scripts/ai_training_data_audit.py:370-375 \u2014 before extracting anything, compare \u0060c-level-advisor/chief-data-officer-advisor/skills/chief-data-officer-advisor/scripts/ai_training_data_audit.py\u0060 and \u0060c-level-advisor/skills/chief-data-officer-advisor/scripts/ai_training_data_audit.py\u0060 as WHOLE FILES: this scan already matched 8 separate duplicated blocks between them, totalling at least 314 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"c-level-advisor/chief-data-officer-advisor/skills/chief-data-officer-advisor/scripts/ai_training_data_audit.py"},"region":{"startLine":370}}}],"partialFingerprints":{"codehealthFindingId/v1":"a9b2870d6b942bf2457c03c612c75746b4c8eabd3d4393561f36916de6f388dc"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2): c-level-advisor/skills/cfo-advisor/scripts/fundraising_model.py:236-241 | c-level-advisor/skills/cfo-advisor/scripts/unit_economics_analyzer.py:226-231 \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":"c-level-advisor/skills/cfo-advisor/scripts/fundraising_model.py"},"region":{"startLine":236}}}],"partialFingerprints":{"codehealthFindingId/v1":"a3a315d912b5bb860ca705354c31ac0a10d450a5a61204bda892896df2adb240"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2): c-level-advisor/skills/cpo-advisor/scripts/pmf_scorer.py:170-176 | c-level-advisor/skills/cpo-advisor/scripts/pmf_scorer.py:192-197 \u2014 both copies are in the same file, so extract the block 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":"c-level-advisor/skills/cpo-advisor/scripts/pmf_scorer.py"},"region":{"startLine":170}}}],"partialFingerprints":{"codehealthFindingId/v1":"5463cc8d6d1ee097b826305a208bb643dda359ee9ec7de115b414c0e45a0b6f7"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2): c-level-advisor/skills/decision-logger/scripts/decision_tracker.py:322-327 | c-level-advisor/skills/decision-logger/scripts/decision_tracker.py:338-343 \u2014 both copies are in the same file, so extract the block 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":"c-level-advisor/skills/decision-logger/scripts/decision_tracker.py"},"region":{"startLine":322}}}],"partialFingerprints":{"codehealthFindingId/v1":"0bd9292c3de0b5bf82c639d5616f6b515aa775af61d42a60d842c7a12fe45792"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2): commercial/skills/deal-desk/scripts/deal_scorer.py:360-365 | commercial/skills/deal-desk/scripts/discount_approval_router.py:239-244 \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":"commercial/skills/deal-desk/scripts/deal_scorer.py"},"region":{"startLine":360}}}],"partialFingerprints":{"codehealthFindingId/v1":"7a5cda6196c474e1937907f472c15dd0ebb60f5720b92fe242967a7232662de3"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2): engineering-team/google-workspace-cli/skills/google-workspace-cli/scripts/gws_doctor.py:238-243 | engineering-team/google-workspace-cli/skills/google-workspace-cli/scripts/workspace_audit.py:301-306 \u2014 the copies sit in sibling files of one directory, so a shared home is within easy reach: extract the block into a single shared function the call sites can all reach \u2014 a file they already depend on, or a new one alongside them \u2014 and call it from both call sites, so a change lands once."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/google-workspace-cli/skills/google-workspace-cli/scripts/gws_doctor.py"},"region":{"startLine":238}}}],"partialFingerprints":{"codehealthFindingId/v1":"4ace88664c46db972f0fd349ea8f6abea0ca094292351fe1a527ac31e7609dbe"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2): engineering-team/google-workspace-cli/skills/google-workspace-cli/scripts/output_analyzer.py:250-255 | markdown-html/skills/md-slides/scripts/slide_splitter.py:245-250 \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":"engineering-team/google-workspace-cli/skills/google-workspace-cli/scripts/output_analyzer.py"},"region":{"startLine":250}}}],"partialFingerprints":{"codehealthFindingId/v1":"ff15780ef47d0baf374015a949384a3018b57555f89e185cd909d26d820a37d1"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2): engineering-team/skills/incident-commander/scripts/timeline_reconstructor.py:333-338 | engineering-team/skills/incident-commander/scripts/timeline_reconstructor.py:351-356 \u2014 both copies are in the same file, so extract the block into one function there and call it from each site \u2014 the copies drift apart the first time only one of them is edited. Read the line range as the matched WINDOW rather than a finished unit: at \u0060engineering-team/skills/incident-commander/scripts/timeline_reconstructor.py:333\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":"engineering-team/skills/incident-commander/scripts/timeline_reconstructor.py"},"region":{"startLine":333}}}],"partialFingerprints":{"codehealthFindingId/v1":"840be3c912320feca852b95ee3ce81fbba776982c4dd985a94606e7af0ba4cf6"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (4\u20136 lines \u00D7 3): engineering-team/skills/senior-backend/scripts/api_load_tester.py:537-557 | engineering-team/skills/senior-devops/scripts/pipeline_generator.py:183-186 | engineering-team/skills/senior-devops/scripts/terraform_scaffolder.py:462-467 \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. Read the line range as the matched WINDOW rather than a finished unit: at \u0060engineering-team/skills/senior-backend/scripts/api_load_tester.py:537\u0060 it begins part-way through the construct above it, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that. Note that the copies do not run to the end of the range shown: their LAST lines are different code, not the same code under different names \u2014 the matched region ends inside that line. Extract the lines above it, and read the last line of each site separately."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/skills/senior-backend/scripts/api_load_tester.py"},"region":{"startLine":537}}}],"partialFingerprints":{"codehealthFindingId/v1":"8eed806d65978c0facaf3e76b25adf6f5bb37f594c67dd7e5bbdaa3496153067"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2): engineering-team/skills/senior-backend/scripts/database_migration_tool.py:534-539 | engineering-team/skills/senior-backend/scripts/database_migration_tool.py:544-549 \u2014 both copies are in the same file, so extract the block 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":"engineering-team/skills/senior-backend/scripts/database_migration_tool.py"},"region":{"startLine":534}}}],"partialFingerprints":{"codehealthFindingId/v1":"d11d729810c5973d00979e8aa42bffd3acee6394274028d90d777ec93247c66a"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2): engineering-team/skills/senior-computer-vision/scripts/dataset_pipeline_builder.py:1674-1679 | engineering-team/skills/senior-computer-vision/scripts/dataset_pipeline_builder.py:1681-1686 \u2014 both copies are in the same file, so extract the block 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":"engineering-team/skills/senior-computer-vision/scripts/dataset_pipeline_builder.py"},"region":{"startLine":1674}}}],"partialFingerprints":{"codehealthFindingId/v1":"2c1a29dcd1d61f5771b97a82ff12f64e61727d905a67ccfafa6489a3e476f21c"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2): engineering-team/skills/senior-fullstack/scripts/project_scaffolder.py:824-829 | engineering-team/skills/senior-secops/scripts/vulnerability_assessor.py:459-464 \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":"engineering-team/skills/senior-fullstack/scripts/project_scaffolder.py"},"region":{"startLine":824}}}],"partialFingerprints":{"codehealthFindingId/v1":"fedc5316e370d57faf5d9fa4b94ead279890cde68036a49b89d401c935967b2e"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2): engineering-team/skills/senior-qa/scripts/coverage_analyzer.py:489-494 | engineering-team/skills/senior-qa/scripts/coverage_analyzer.py:500-505 \u2014 both copies are in the same file, so extract the block 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":"engineering-team/skills/senior-qa/scripts/coverage_analyzer.py"},"region":{"startLine":489}}}],"partialFingerprints":{"codehealthFindingId/v1":"750d8f4afe09148386859e316caf5afcad791511e302698ab4a42aaea999c589"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2): engineering/agent-harness/skills/agent-harness/scripts/goal_compiler.py:137-142 | engineering/human-gate/skills/human-gate/scripts/review_page_builder.py:825-835 \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":"engineering/agent-harness/skills/agent-harness/scripts/goal_compiler.py"},"region":{"startLine":137}}}],"partialFingerprints":{"codehealthFindingId/v1":"91b7b9d1116a52b3c4aa682546230df58e87fa224419a7fd60390818b1373d06"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2): engineering/claude-coach/skills/claude-coach/scripts/cheat_code_filter.py:139-144 | productivity/weekly-review/skills/weekly-review/scripts/open_loop_scanner.py:175-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. Note first that the copies are not typed on the same thing: the declarations holding them bind \u0060argv\u0060 to \u0060list[str] | None = None\u0060 in one and \u0060List[str]\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":"engineering/claude-coach/skills/claude-coach/scripts/cheat_code_filter.py"},"region":{"startLine":139}}}],"partialFingerprints":{"codehealthFindingId/v1":"417669f9a4fcd25e30f2c61936957776ed3d0fa71f1e786d4e7601fd8a663e7f"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2): engineering/claude-coach/skills/claude-coach/scripts/coach_tip_classifier.py:188-193 | productivity/meetings/skills/meetings/scripts/meeting_cost_calculator.py:148-155 \u2014 the copies span different directories, so extracting a shared function means choosing where it lives: put it somewhere both call sites can already reach \u2014 a location they all depend on today, or a new shared one if there is none \u2014 and call it from each site; until then, every change has to be made twice. Read the line range as the matched WINDOW rather than a finished unit: at \u0060productivity/meetings/skills/meetings/scripts/meeting_cost_calculator.py:148\u0060 it begins part-way through the construct above it, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that. Note first that the copies are not typed on the same thing: the declarations holding them bind \u0060argv\u0060 to \u0060list[str] | None = None\u0060 in one and \u0060List[str]\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":"engineering/claude-coach/skills/claude-coach/scripts/coach_tip_classifier.py"},"region":{"startLine":188}}}],"partialFingerprints":{"codehealthFindingId/v1":"96594337b930fa43a275e1c05338facd305d9a9c19eab2d20f1670c143681d80"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2): engineering/grill-with-docs/skills/grill-with-docs/scripts/adr_scanner.py:221-226 | productivity/email/skills/inbox-setup/scripts/kb_validator.py:239-244 \u2014 the copies span different directories, so extracting a shared function means choosing where it lives: put it somewhere both call sites can already reach \u2014 a location they all depend on today, or a new shared one if there is none \u2014 and call it from each site; until then, every change has to be made twice. \u2605 These copies have DRIFTED, and that is worth reading before extracting anything: just before the matched lines, \u0060productivity/email/skills/inbox-setup/scripts/kb_validator.py:236\u0060 calls \u0060add_argument\u0060 and \u0060engineering/grill-with-docs/skills/grill-with-docs/scripts/adr_scanner.py:219\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":"engineering/grill-with-docs/skills/grill-with-docs/scripts/adr_scanner.py"},"region":{"startLine":221}}}],"partialFingerprints":{"codehealthFindingId/v1":"70ecbca1b65cc310275bae021f77b38e94a974f2ef5062512fdea4280c1739b5"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2): engineering/skills/changelog-generator/scripts/generate_changelog.py:62-67 | marketing-skill/skills/prompt-engineer-toolkit/scripts/prompt_tester.py:42-47 \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":"engineering/skills/changelog-generator/scripts/generate_changelog.py"},"region":{"startLine":62}}}],"partialFingerprints":{"codehealthFindingId/v1":"7b80dfc71312bcf7bf260eb823b00510ed5ea907192b4e4bb1ddc71cedb0ebd0"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2): engineering/skills/database-designer/migration_generator.py:734-739 | engineering/skills/database-designer/migration_generator.py:741-746 \u2014 both copies are in the same file, so extract the block 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":"engineering/skills/database-designer/migration_generator.py"},"region":{"startLine":734}}}],"partialFingerprints":{"codehealthFindingId/v1":"68b68d017e3e875bcb736a96a5a35a7c746f9e4849d4bbc9938e927f2a3017be"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2): engineering/skills/database-designer/schema_analyzer.py:841-848 | research/syllabus/skills/syllabus/scripts/citation_tracker.py:153-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."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/database-designer/schema_analyzer.py"},"region":{"startLine":841}}}],"partialFingerprints":{"codehealthFindingId/v1":"2b9ec315be3ddf50b053df90c34957e6594d1543ec1865dedf7410c57424f6a4"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2): engineering/skills/slo-architect/scripts/slo_designer.py:94-99 | engineering/slo-architect/skills/slo-architect/scripts/slo_designer.py:94-99 \u2014 before extracting anything, compare \u0060engineering/skills/slo-architect/scripts/slo_designer.py\u0060 and \u0060engineering/slo-architect/skills/slo-architect/scripts/slo_designer.py\u0060 as WHOLE FILES: this scan already matched 8 separate duplicated blocks between them, totalling at least 70 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/slo-architect/scripts/slo_designer.py"},"region":{"startLine":94}}}],"partialFingerprints":{"codehealthFindingId/v1":"6a8f486a1893e83fe93d84d8bc9a26fcbf39d7aabf6554a690bbd9c3d579d7a0"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2): engineering/skills/tc-tracker/scripts/tc_create.py:169-174 | engineering/skills/tc-tracker/scripts/tc_update.py:167-172 \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, \u0060engineering/skills/tc-tracker/scripts/tc_update.py:173\u0060 calls \u0060loads\u0060, \u0060read_text\u0060 and \u0060engineering/skills/tc-tracker/scripts/tc_create.py:175\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":"engineering/skills/tc-tracker/scripts/tc_create.py"},"region":{"startLine":169}}}],"partialFingerprints":{"codehealthFindingId/v1":"3a955377b2fd103e7d6ad3e52a4be358ff13d43f060f36fb96a02de2934df9a6"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2): engineering/skills/tc-tracker/scripts/tc_create.py:168-173 | engineering/skills/tc-tracker/scripts/tc_status.py:154-159 \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, \u0060engineering/skills/tc-tracker/scripts/tc_create.py:174\u0060 calls \u0060loads\u0060, \u0060read_text\u0060 and \u0060engineering/skills/tc-tracker/scripts/tc_status.py:160\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":"engineering/skills/tc-tracker/scripts/tc_create.py"},"region":{"startLine":168}}}],"partialFingerprints":{"codehealthFindingId/v1":"adccc8970681663658fbf3bb16d7a6dcc11399bf6064bdd29549399459a5723e"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2): engineering/skills/tech-debt-tracker/scripts/debt_dashboard.py:911-916 | engineering/skills/tech-debt-tracker/scripts/debt_prioritizer.py:804-809 \u2014 the copies sit in sibling files of one directory, so a shared home is within easy reach: extract the block into a single shared function the call sites can all reach \u2014 a file they already depend on, or a new one alongside them \u2014 and call it from both call sites, so a change lands once. \u2605 These copies have DRIFTED, and that is worth reading before extracting anything: just before the matched lines, \u0060engineering/skills/tech-debt-tracker/scripts/debt_dashboard.py:910\u0060 calls \u0060add_argument\u0060 and \u0060engineering/skills/tech-debt-tracker/scripts/debt_prioritizer.py:803\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":"engineering/skills/tech-debt-tracker/scripts/debt_dashboard.py"},"region":{"startLine":911}}}],"partialFingerprints":{"codehealthFindingId/v1":"1fdc7c3d03168da8a7eb3b7d37f316544803fe96fac122c17c73a03762dc392a"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2): finance/skills/financial-analyst/scripts/forecast_builder.py:404-409 | finance/skills/financial-analyst/scripts/forecast_builder.py:447-452 \u2014 both copies are in the same file, so extract the block into one function there and call it from each site \u2014 the copies drift apart the first time only one of them is edited."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"finance/skills/financial-analyst/scripts/forecast_builder.py"},"region":{"startLine":404}}}],"partialFingerprints":{"codehealthFindingId/v1":"c8190a888b3ed51d70f8d34bfb6c6a14bac68525a4860cb17de1222489803c4d"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2): finance/skills/stock-analysis/scripts/ratios.py:1120-1125 | finance/skills/stock-analysis/scripts/ratios.py:1160-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 \u0060finance/skills/stock-analysis/scripts/ratios.py:1120\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":"finance/skills/stock-analysis/scripts/ratios.py"},"region":{"startLine":1120}}}],"partialFingerprints":{"codehealthFindingId/v1":"1f5363d5540d2ba7d0bdcf29b6d1903d15f7d15afe145a6945a68a5e6fd93694"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2): finance/skills/stock-analysis/scripts/ratios.py:2110-2115 | finance/skills/stock-analysis/scripts/ratios.py:2159-2164 \u2014 both copies are in the same file, so extract the block 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":"finance/skills/stock-analysis/scripts/ratios.py"},"region":{"startLine":2110}}}],"partialFingerprints":{"codehealthFindingId/v1":"e0e24a261f9c22271e011ce049f051310902c7bae87131cf3d1388bcec435436"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5\u20136 lines \u00D7 3): marketing-skill/skills/churn-prevention/scripts/churn_impact_calculator.py:134-139 | marketing-skill/skills/churn-prevention/scripts/churn_impact_calculator.py:140-145 | marketing-skill/skills/churn-prevention/scripts/churn_impact_calculator.py:146-150 \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":"marketing-skill/skills/churn-prevention/scripts/churn_impact_calculator.py"},"region":{"startLine":134}}}],"partialFingerprints":{"codehealthFindingId/v1":"088da745eec7c0d33bba9ff47f33f740a87d2b5686d2f234e415cc04a8d83ec3"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2): marketing-skill/skills/site-architecture/scripts/sitemap_analyzer.py:272-277 | marketing-skill/skills/site-architecture/scripts/sitemap_analyzer.py:280-285 \u2014 both copies are in the same file, so extract the block 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":"marketing-skill/skills/site-architecture/scripts/sitemap_analyzer.py"},"region":{"startLine":272}}}],"partialFingerprints":{"codehealthFindingId/v1":"04873366f91f7dff81222b98c7d750450da2224996b302e6ffe2fcb6ce9043d7"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2): productivity/deep-work/skills/deep-work/scripts/time_block_planner.py:145-150 | productivity/deep-work/skills/deep-work/scripts/time_block_planner.py:183-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":"productivity/deep-work/skills/deep-work/scripts/time_block_planner.py"},"region":{"startLine":145}}}],"partialFingerprints":{"codehealthFindingId/v1":"ba84e16855fa31a90f1abdf1ec97cced85b8b5d5102040dd915a1c9986ff483a"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (3\u20136 lines \u00D7 4): engineering/skills/interview-system-designer/hiring_calibrator.py:1130-1132 | project-management/skills/atlassian-admin/scripts/permission_audit_tool.py:383-388 | project-management/skills/jira-expert/scripts/workflow_validator.py:339-342 | project-management/skills/jira-expert/scripts/workflow_validator.py:345-351 \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. \u2605 These copies have DRIFTED, and that is worth reading before extracting anything: just after the matched lines, \u0060engineering/skills/interview-system-designer/hiring_calibrator.py:1135\u0060 calls \u0060get\u0060 and \u0060project-management/skills/atlassian-admin/scripts/permission_audit_tool.py:390\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":"engineering/skills/interview-system-designer/hiring_calibrator.py"},"region":{"startLine":1130}}}],"partialFingerprints":{"codehealthFindingId/v1":"f1d8a9481952a2983bb5405f320a78097b5f8bce1180cdfd6e964a7bc73dee69"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2): research-ops/skills/market-research/scripts/market_sizer.py:140-145 | research-ops/skills/product-research/scripts/saturation_planner.py:114-119 \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":"research-ops/skills/market-research/scripts/market_sizer.py"},"region":{"startLine":140}}}],"partialFingerprints":{"codehealthFindingId/v1":"46d9f72277e113b026279be777d406ef717d33aacc5b3f09740845e8dab76005"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2): research/patent/skills/patent/scripts/citation_tracker.py:170-175 | research/patent/skills/patent/scripts/citation_tracker.py:177-182 \u2014 both copies are in the same file, so extract the block 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":"research/patent/skills/patent/scripts/citation_tracker.py"},"region":{"startLine":170}}}],"partialFingerprints":{"codehealthFindingId/v1":"92d9835d105355e8113202614e532dd00d248ee7ff35e49a03fe9fbe07751e2f"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2): research/patent/skills/patent/scripts/citation_tracker.py:220-225 | research/syllabus/skills/syllabus/scripts/citation_tracker.py:196-201 \u2014 before extracting anything, compare \u0060research/patent/skills/patent/scripts/citation_tracker.py\u0060 and \u0060research/syllabus/skills/syllabus/scripts/citation_tracker.py\u0060 as WHOLE FILES: this scan already matched 6 separate duplicated blocks between them, totalling at least 43 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. Read the line range as the matched WINDOW rather than a finished unit: at \u0060research/patent/skills/patent/scripts/citation_tracker.py:220\u0060 it begins part-way through the construct above it, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that. \u2605 These copies have DRIFTED, and that is worth reading before extracting anything: just before the matched lines, \u0060research/patent/skills/patent/scripts/citation_tracker.py:219\u0060 calls \u0060action_record_lens_byok\u0060 and \u0060research/syllabus/skills/syllabus/scripts/citation_tracker.py:195\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":"research/patent/skills/patent/scripts/citation_tracker.py"},"region":{"startLine":220}}}],"partialFingerprints":{"codehealthFindingId/v1":"3491ed6daa5a6d6cf88339b0d88e064d39019929f437524b152cbf34bb75a1af"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (4\u20136 lines \u00D7 3): project-management/skills/jira-expert/scripts/jql_query_builder.py:421-424 | research/patent/skills/patent/scripts/sub_use_case_router.py:202-207 | research/patent/skills/patent/scripts/sub_use_case_router.py:210-215 \u2014 there are 3 copies across 2 file(s) \u2014 more copies than files, so at least one file holds the block twice. Extract it once into a single shared function every call site can reach and call it from all 3 sites; resolving a subset leaves the remainder to drift apart."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"project-management/skills/jira-expert/scripts/jql_query_builder.py"},"region":{"startLine":421}}}],"partialFingerprints":{"codehealthFindingId/v1":"84f4c63a60b0c0406c536226808debe0c7f40327ba21c3bf00843c9d98fef4d7"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2): research/syllabus/skills/syllabus/scripts/citation_tracker.py:98-103 | research/syllabus/skills/syllabus/scripts/citation_tracker.py:122-127 \u2014 both copies are in the same file, so extract the block into one function there and call it from each site \u2014 the copies drift apart the first time only one of them is edited. 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":"research/syllabus/skills/syllabus/scripts/citation_tracker.py"},"region":{"startLine":98}}}],"partialFingerprints":{"codehealthFindingId/v1":"2496f6fc4467ad9a94e127e51e00a040f0b7686ac8871d33b6e2bea38e874054"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2): scripts/sync-codex-skills.py:442-447 | scripts/sync-gemini-skills.py:279-284 \u2014 the copies sit in sibling files of one directory, so a shared home is within easy reach: extract the block into a single shared function the call sites can all reach \u2014 a file they already depend on, or a new one alongside them \u2014 and call it from both call sites, so a change lands once."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"scripts/sync-codex-skills.py"},"region":{"startLine":442}}}],"partialFingerprints":{"codehealthFindingId/v1":"9fe6c1957cadda530b364436e77e70037b296df0bdf029a701bceeea96c3fafc"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 11): research-ops/skills/clinical-research/scripts/endpoint_selector.py:160-165 | research-ops/skills/clinical-research/scripts/sample_size_estimator.py:172-176 | research-ops/skills/market-research/scripts/market_sizer.py:139-144 | research-ops/skills/market-research/scripts/sample_size_planner.py:153-157 | research-ops/skills/market-research/scripts/segmentation_scorer.py:117-122 | research-ops/skills/product-research/scripts/insight_synthesizer.py:96-101 | research-ops/skills/product-research/scripts/saturation_planner.py:114-118 | research-ops/skills/product-research/scripts/study_designer.py:116-121 | research-ops/skills/research-finance/scripts/burn_runway_tracker.py:131-135 | research-ops/skills/research-finance/scripts/capex_vs_opex_router.py:160-165 | research-ops/skills/research-finance/scripts/program_budget_planner.py:140-144 \u2014 the copies span different directories, so extracting a shared function means choosing where it lives: put it somewhere all 11 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 11 times. Read the line range as the matched WINDOW rather than a finished unit: at \u0060research-ops/skills/clinical-research/scripts/endpoint_selector.py:160\u0060 it begins part-way through the construct above it, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that. \u2605 These copies have DRIFTED, and that is worth reading before extracting anything: just before the matched lines, \u0060research-ops/skills/research-finance/scripts/capex_vs_opex_router.py:157\u0060 calls \u0060add_argument\u0060 and \u0060research-ops/skills/clinical-research/scripts/endpoint_selector.py:158\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":"research-ops/skills/clinical-research/scripts/endpoint_selector.py"},"region":{"startLine":160}}}],"partialFingerprints":{"codehealthFindingId/v1":"34c7352da98e7203a41a72187b69f0ae3b6bca5900dd86054afb092080b77ca3"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 7): engineering/skills/database-designer/migration_generator.py:1085-1091 | engineering/skills/migration-architect/scripts/rollback_generator.py:955-961 | engineering/skills/slo-architect/scripts/slo_designer.py:94-98 | engineering/slo-architect/skills/slo-architect/scripts/slo_designer.py:94-98 | productivity/email/skills/inbox-triage/scripts/search_window_calculator.py:88-92 | research/litreview/skills/litreview/scripts/citation_tracker.py:168-173 | research/pulse/skills/pulse/scripts/time_window_calculator.py:92-96 \u2014 before extracting anything, compare \u0060engineering/skills/slo-architect/scripts/slo_designer.py\u0060 and \u0060engineering/slo-architect/skills/slo-architect/scripts/slo_designer.py\u0060 as WHOLE FILES: this scan already matched 8 separate duplicated blocks between them, totalling at least 70 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. Read the line range as the matched WINDOW rather than a finished unit: at \u0060research/litreview/skills/litreview/scripts/citation_tracker.py:168\u0060 it does not close everything it opens, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that. Note that the copies do not run to the end of the range shown: their LAST lines are different code, not the same code under different names \u2014 the matched region ends inside that line. Extract the lines above it, and read the last line of each site separately. \u2605 These copies have DRIFTED, and that is worth reading before extracting anything: just after the matched lines, \u0060engineering/skills/database-designer/migration_generator.py:1093\u0060 calls \u0060enumerate\u0060 and \u0060engineering/skills/slo-architect/scripts/slo_designer.py:99\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":"engineering/skills/database-designer/migration_generator.py"},"region":{"startLine":1085}}}],"partialFingerprints":{"codehealthFindingId/v1":"f0d8cd0dd2e67f98982520009137b0e7101511e7f3f3db515e04939da7c741b7"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 6): business-growth/skills/sales-engineer/scripts/poc_planner.py:601-607 | c-level-advisor/skills/vpe-advisor/scripts/eng_team_structure_designer.py:232-236 | c-level-advisor/vpe-advisor/skills/vpe-advisor/scripts/eng_team_structure_designer.py:232-236 | marketing-skill/skills/local-seo-manager/scripts/nap_checker.py:248-253 | ra-qm-team/compliance-team-eu-ai-act/skills/eu-ai-act-specialist/scripts/conformity_assessment_planner.py:248-252 | ra-qm-team/skills/eu-ai-act-specialist/scripts/conformity_assessment_planner.py:248-252 \u2014 before extracting anything, compare \u0060c-level-advisor/skills/vpe-advisor/scripts/eng_team_structure_designer.py\u0060 and \u0060c-level-advisor/vpe-advisor/skills/vpe-advisor/scripts/eng_team_structure_designer.py\u0060 as WHOLE FILES: this scan already matched 11 separate duplicated blocks between them, totalling at least 223 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. 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":"business-growth/skills/sales-engineer/scripts/poc_planner.py"},"region":{"startLine":601}}}],"partialFingerprints":{"codehealthFindingId/v1":"97d4bbdad26e75595b545f85777e18830807b8c229265b67927445e83eb5013e"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 6): engineering/chaos-engineering/skills/chaos-engineering/scripts/experiment_designer.py:68-72 | engineering/chaos-engineering/skills/chaos-engineering/scripts/experiment_postmortem.py:82-86 | engineering/skills/chaos-engineering/scripts/experiment_designer.py:68-72 | engineering/skills/chaos-engineering/scripts/experiment_postmortem.py:82-86 | engineering/skills/slo-architect/scripts/slo_designer.py:90-94 | engineering/slo-architect/skills/slo-architect/scripts/slo_designer.py:90-94 \u2014 before extracting anything, compare \u0060engineering/chaos-engineering/skills/chaos-engineering/scripts/experiment_designer.py\u0060 and \u0060engineering/skills/chaos-engineering/scripts/experiment_designer.py\u0060 as WHOLE FILES: this scan already matched 7 separate duplicated blocks between them, totalling at least 111 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/chaos-engineering/skills/chaos-engineering/scripts/experiment_designer.py"},"region":{"startLine":68}}}],"partialFingerprints":{"codehealthFindingId/v1":"6682c070ec498b883045182ceb613852901f3b3bd08a6c113c20dcedf93c125b"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 6): engineering/skills/slo-architect/scripts/error_budget_calculator.py:130-134 | engineering/slo-architect/skills/slo-architect/scripts/error_budget_calculator.py:130-134 | marketing/linkedin/skills/linkedin-engagement/scripts/outreach_volume_guard.py:169-173 | marketing/linkedin/skills/linkedin-strategy/scripts/cadence_planner.py:232-237 | marketing/linkedin/skills/linkedin-strategy/scripts/newsletter_planner.py:216-220 | research/research/skills/research/scripts/fallback_decomposer.py:88-92 \u2014 before extracting anything, compare \u0060engineering/skills/slo-architect/scripts/error_budget_calculator.py\u0060 and \u0060engineering/slo-architect/skills/slo-architect/scripts/error_budget_calculator.py\u0060 as WHOLE FILES: this scan already matched 7 separate duplicated blocks between them, totalling at least 89 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. Read the line range as the matched WINDOW rather than a finished unit: at \u0060marketing/linkedin/skills/linkedin-strategy/scripts/cadence_planner.py:232\u0060 it begins part-way through the construct above it, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that. \u2605 These copies have DRIFTED, and that is worth reading before extracting anything: just before the matched lines, \u0060marketing/linkedin/skills/linkedin-engagement/scripts/outreach_volume_guard.py:168\u0060 calls \u0060add_argument\u0060 and \u0060marketing/linkedin/skills/linkedin-strategy/scripts/cadence_planner.py:232\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":"engineering/skills/slo-architect/scripts/error_budget_calculator.py"},"region":{"startLine":130}}}],"partialFingerprints":{"codehealthFindingId/v1":"0cfa4636b7ab7e2293abea2aa4af0304393985a04c73bafcaac42b9a72bd20f1"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 5): business-growth/skills/sales-engineer/scripts/poc_planner.py:594-598 | business-growth/skills/sales-engineer/scripts/rfp_response_analyzer.py:429-433 | engineering/skills/database-designer/index_optimizer.py:804-808 | engineering/skills/database-designer/migration_generator.py:1083-1087 | engineering/skills/database-designer/schema_analyzer.py:837-841 \u2014 the copies span different directories, so extracting a shared function means choosing where it lives: put it somewhere all 5 call sites can already reach \u2014 a location they all depend on today, or a new shared one if there is none \u2014 and call it from each site; until then, every change has to be made 5 times."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"business-growth/skills/sales-engineer/scripts/poc_planner.py"},"region":{"startLine":594}}}],"partialFingerprints":{"codehealthFindingId/v1":"c36af206dbe50d037738b79d3f635dcd9408c3398a4749b0e7d7574a4acfcae9"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 5): compliance-os/skills/compliance-os/scripts/cross_framework_mapper.py:364-368 | ra-qm-team/compliance-team-eu-ai-act/skills/eu-ai-act-specialist/scripts/conformity_assessment_planner.py:244-248 | ra-qm-team/skills/eu-ai-act-specialist/scripts/conformity_assessment_planner.py:244-248 | research/pulse/skills/pulse/scripts/citation_tracker.py:419-423 | research/syllabus/skills/syllabus/scripts/citation_tracker.py:151-155 \u2014 the copies span different directories, so extracting a shared function means choosing where it lives: put it somewhere all 5 call sites can already reach \u2014 a location they all depend on today, or a new shared one if there is none \u2014 and call it from each site; until then, every change has to be made 5 times."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"compliance-os/skills/compliance-os/scripts/cross_framework_mapper.py"},"region":{"startLine":364}}}],"partialFingerprints":{"codehealthFindingId/v1":"7b9e7941cb046a10d7b0b7764aafe3bc03b7be3fa8f8cf6651efb0b8b15a2157"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 5): engineering/agenthub/skills/agenthub/scripts/dag_analyzer.py:234-240 | engineering/agenthub/skills/agenthub/scripts/hub_init.py:184-190 | ra-qm-team/skills/capa-officer/scripts/root_cause_analyzer.py:439-443 | ra-qm-team/skills/regulatory-affairs-head/scripts/regulatory_pathway_analyzer.py:498-502 | ra-qm-team/skills/risk-management-specialist/scripts/fmea_analyzer.py:363-367 \u2014 the copies span different directories, so extracting a shared function means choosing where it lives: put it somewhere all 5 call sites can already reach \u2014 a location they all depend on today, or a new shared one if there is none \u2014 and call it from each site; until then, every change has to be made 5 times."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/agenthub/skills/agenthub/scripts/dag_analyzer.py"},"region":{"startLine":234}}}],"partialFingerprints":{"codehealthFindingId/v1":"fe469da1846c183739a5ec1eea63ad8c34cf4b740b24581accd38fe89863a4ee"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (4\u20135 lines \u00D7 6): engineering/docker-development/skills/docker-development/scripts/compose_validator.py:342-346 | engineering/docker-development/skills/docker-development/scripts/dockerfile_analyzer.py:361-364 | engineering/helm-chart-builder/skills/helm-chart-builder/scripts/chart_analyzer.py:465-469 | engineering/helm-chart-builder/skills/helm-chart-builder/scripts/values_validator.py:391-395 | engineering/terraform-patterns/skills/terraform-patterns/scripts/tf_module_analyzer.py:411-415 | engineering/terraform-patterns/skills/terraform-patterns/scripts/tf_security_scanner.py:516-520 \u2014 the copies span different directories, so extracting a shared function means choosing where it lives: put it somewhere all 6 call sites can already reach \u2014 a location they all depend on today, or a new shared one if there is none \u2014 and call it from each site; until then, every change has to be made 6 times."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/docker-development/skills/docker-development/scripts/compose_validator.py"},"region":{"startLine":342}}}],"partialFingerprints":{"codehealthFindingId/v1":"31957f41741b18d28b0ef6d3339d83ba05471d79f773263a49235eddfb9b6eb2"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 5): engineering/skills/changelog-generator/scripts/generate_changelog.py:64-68 | engineering/skills/slo-architect/scripts/slo_designer.py:127-131 | engineering/slo-architect/skills/slo-architect/scripts/slo_designer.py:127-131 | marketing-skill/skills/aeo/scripts/citation_tracker.py:285-289 | productivity/roast/skills/roast/scripts/brief_builder.py:121-125 \u2014 before extracting anything, compare \u0060engineering/skills/slo-architect/scripts/slo_designer.py\u0060 and \u0060engineering/slo-architect/skills/slo-architect/scripts/slo_designer.py\u0060 as WHOLE FILES: this scan already matched 8 separate duplicated blocks between them, totalling at least 70 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/changelog-generator/scripts/generate_changelog.py"},"region":{"startLine":64}}}],"partialFingerprints":{"codehealthFindingId/v1":"8929f821fb2bfa1c69cad61272133a0d30b37108ebf9fadc35cbf4c4b686aef4"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 5): markdown-html/skills/design-system/scripts/brand_palette_validator.py:306-310 | marketing/landing/skills/landing/scripts/brand_palette_validator.py:242-246 | marketing/landing/skills/landing/scripts/kebab_slug_generator.py:98-102 | productivity/capture/skills/capture/scripts/workspace_inventory.py:181-185 | research/dossier/skills/dossier/scripts/source_tier_classifier.py:210-214 \u2014 before extracting anything, compare \u0060markdown-html/skills/design-system/scripts/brand_palette_validator.py\u0060 and \u0060marketing/landing/skills/landing/scripts/brand_palette_validator.py\u0060 as WHOLE FILES: this scan already matched 12 separate duplicated blocks between them, totalling at least 79 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. Note first that the copies are not typed on the same thing: the declarations holding them bind \u0060argv\u0060 to \u0060list[str]\u0060 in one and \u0060List[str]\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. \u2605 These copies have DRIFTED, and that is worth reading before extracting anything: just before the matched lines, \u0060markdown-html/skills/design-system/scripts/brand_palette_validator.py:304\u0060 calls \u0060add_argument\u0060 and \u0060marketing/landing/skills/landing/scripts/kebab_slug_generator.py:97\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":"markdown-html/skills/design-system/scripts/brand_palette_validator.py"},"region":{"startLine":306}}}],"partialFingerprints":{"codehealthFindingId/v1":"21be1ac76e17f279ad512f334958cd5272e344e665f112f3b3c2f436ed701ff1"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 4): business-growth/skills/sales-engineer/scripts/poc_planner.py:699-704 | ra-qm-team/compliance-team-eu-ai-act/skills/eu-ai-act-specialist/scripts/ai_act_obligation_tracker.py:208-212 | ra-qm-team/skills/eu-ai-act-specialist/scripts/ai_act_obligation_tracker.py:208-212 | research/litreview/skills/litreview/scripts/framework_recommender.py:163-167 \u2014 before extracting anything, compare \u0060ra-qm-team/compliance-team-eu-ai-act/skills/eu-ai-act-specialist/scripts/ai_act_obligation_tracker.py\u0060 and \u0060ra-qm-team/skills/eu-ai-act-specialist/scripts/ai_act_obligation_tracker.py\u0060 as WHOLE FILES: this scan already matched 11 separate duplicated blocks between them, totalling at least 122 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. \u2605 These copies have DRIFTED, and that is worth reading before extracting anything: just after the matched lines, \u0060research/litreview/skills/litreview/scripts/framework_recommender.py:169\u0060 calls \u0060sum\u0060, \u0060values\u0060, \u0060join\u0060 and \u0060business-growth/skills/sales-engineer/scripts/poc_planner.py:706\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":"business-growth/skills/sales-engineer/scripts/poc_planner.py"},"region":{"startLine":699}}}],"partialFingerprints":{"codehealthFindingId/v1":"a30d33ddc937b80bc61b8b7b10b13ec81f3ef6b04569a8191375211581943ce1"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 4): c-level-advisor/chief-ai-officer-advisor/skills/chief-ai-officer-advisor/scripts/model_buildvsbuy_calculator.py:283-287 | c-level-advisor/chief-data-officer-advisor/skills/chief-data-officer-advisor/scripts/data_product_strategy_picker.py:280-284 | c-level-advisor/skills/chief-ai-officer-advisor/scripts/model_buildvsbuy_calculator.py:283-287 | c-level-advisor/skills/chief-data-officer-advisor/scripts/data_product_strategy_picker.py:280-284 \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."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"c-level-advisor/chief-ai-officer-advisor/skills/chief-ai-officer-advisor/scripts/model_buildvsbuy_calculator.py"},"region":{"startLine":283}}}],"partialFingerprints":{"codehealthFindingId/v1":"33b927ed1d26489c3dd94194ac04f82e6259d6f5352a4378b3c66d591a1fd41d"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 4): engineering-team/skills/azure-cloud-architect/scripts/architecture_designer.py:496-500 | engineering/skills/migration-architect/scripts/rollback_generator.py:955-961 | productivity/email/skills/inbox-triage/scripts/search_window_calculator.py:88-92 | research/pulse/skills/pulse/scripts/time_window_calculator.py:92-96 \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. \u2605 These copies have DRIFTED, and that is worth reading before extracting anything: just after the matched lines, \u0060engineering/skills/migration-architect/scripts/rollback_generator.py:963\u0060 calls \u0060items\u0060 and \u0060productivity/email/skills/inbox-triage/scripts/search_window_calculator.py:93\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":"engineering-team/skills/azure-cloud-architect/scripts/architecture_designer.py"},"region":{"startLine":496}}}],"partialFingerprints":{"codehealthFindingId/v1":"73ca3eb81c1e218c436a7d1ad6cc5dd32da31f8aa8eed5bfa3b7db7660590e60"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 4): marketing/linkedin/skills/linkedin-content/scripts/format_picker.py:213-218 | marketing/linkedin/skills/linkedin-content/scripts/repurpose_splitter.py:207-212 | ra-qm-team/skills/quality-documentation-manager/scripts/document_version_control.py:388-392 | ra-qm-team/skills/quality-manager-qmr/scripts/quality_effectiveness_monitor.py:430-434 \u2014 the copies span different directories, so extracting a shared function means choosing where it lives: put it somewhere all 4 call sites can already reach \u2014 a location they all depend on today, or a new shared one if there is none \u2014 and call it from each site; until then, every change has to be made 4 times. Read the line range as the matched WINDOW rather than a finished unit: at \u0060marketing/linkedin/skills/linkedin-content/scripts/format_picker.py:213\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":"marketing/linkedin/skills/linkedin-content/scripts/format_picker.py"},"region":{"startLine":213}}}],"partialFingerprints":{"codehealthFindingId/v1":"4681a24bd9f27b5c29a15d839d95c3b4a635a481b9508051a60cc0fc4fdf56c2"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 4): marketing/linkedin/skills/linkedin-engagement/scripts/outreach_message_builder.py:221-225 | marketing/linkedin/skills/linkedin-profile/scripts/about_section_builder.py:236-241 | marketing/linkedin/skills/linkedin-profile/scripts/headline_scorer.py:259-264 | marketing/linkedin/skills/linkedin-strategy/scripts/positioning_brief.py:258-262 \u2014 the copies span different directories, so extracting a shared function means choosing where it lives: put it somewhere all 4 call sites can already reach \u2014 a location they all depend on today, or a new shared one if there is none \u2014 and call it from each site; until then, every change has to be made 4 times. Read the line range as the matched WINDOW rather than a finished unit: at \u0060marketing/linkedin/skills/linkedin-engagement/scripts/outreach_message_builder.py:221\u0060 it begins part-way through the construct above it, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that. Note that the copies do not run to the end of the range shown: their LAST lines are different code, not the same code under different names \u2014 the matched region ends inside that line. Extract the lines above it, and read the last line of each site separately. \u2605 These copies have DRIFTED, and that is worth reading before extracting anything: just before the matched lines, \u0060marketing/linkedin/skills/linkedin-engagement/scripts/outreach_message_builder.py:219\u0060 calls \u0060add_argument\u0060 and \u0060marketing/linkedin/skills/linkedin-profile/scripts/headline_scorer.py:259\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":"marketing/linkedin/skills/linkedin-engagement/scripts/outreach_message_builder.py"},"region":{"startLine":221}}}],"partialFingerprints":{"codehealthFindingId/v1":"7eb48d72b788bb2c78a81a84bbdba44c3027f7636e27dee0f69a597fb7474a59"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 3): business-growth/skills/sales-engineer/scripts/poc_planner.py:594-598 | business-growth/skills/sales-engineer/scripts/rfp_response_analyzer.py:429-433 | finance/skills/saas-metrics-coach/scripts/quick_ratio_calculator.py:103-109 \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":"business-growth/skills/sales-engineer/scripts/poc_planner.py"},"region":{"startLine":594}}}],"partialFingerprints":{"codehealthFindingId/v1":"bbc24fe81596807d6cb54bcb04cd35163e3edf36d830066ea10ebaee9a6e4e47"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 3): business-growth/skills/sales-engineer/scripts/poc_planner.py:593-597 | business-growth/skills/sales-engineer/scripts/rfp_response_analyzer.py:428-432 | engineering/skills/dependency-auditor/scripts/license_checker.py:881-885 \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":"business-growth/skills/sales-engineer/scripts/poc_planner.py"},"region":{"startLine":593}}}],"partialFingerprints":{"codehealthFindingId/v1":"6fb6e1843b33a6c38feb947b5b5a46d48d8d7d118a27d8b2d1d937bee85125ca"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 3): business-growth/skills/sales-engineer/scripts/poc_planner.py:699-704 | engineering/skills/slo-architect/scripts/slo_designer.py:94-98 | engineering/slo-architect/skills/slo-architect/scripts/slo_designer.py:94-98 \u2014 before extracting anything, compare \u0060engineering/skills/slo-architect/scripts/slo_designer.py\u0060 and \u0060engineering/slo-architect/skills/slo-architect/scripts/slo_designer.py\u0060 as WHOLE FILES: this scan already matched 8 separate duplicated blocks between them, totalling at least 70 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"business-growth/skills/sales-engineer/scripts/poc_planner.py"},"region":{"startLine":699}}}],"partialFingerprints":{"codehealthFindingId/v1":"6eb4ddca28b997cef5bd1cf4ec6cc7b0a36ed3908d8fbc647cf408904a525ce5"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 3): c-level-advisor/skills/cpo-advisor/scripts/pmf_scorer.py:171-176 | c-level-advisor/skills/cpo-advisor/scripts/pmf_scorer.py:193-197 | c-level-advisor/skills/cpo-advisor/scripts/pmf_scorer.py:222-226 \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":"c-level-advisor/skills/cpo-advisor/scripts/pmf_scorer.py"},"region":{"startLine":171}}}],"partialFingerprints":{"codehealthFindingId/v1":"bd804fa2f40bb9f3d210c38cde490abcdea37b392650e99b148dcb777662a73b"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 3): commercial/skills/commercial-forecaster/scripts/cohort_arr_projector.py:253-257 | commercial/skills/commercial-forecaster/scripts/funnel_confidence_scorer.py:165-169 | commercial/skills/pricing-strategist/scripts/wtp_analyzer.py:230-234 \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":"commercial/skills/commercial-forecaster/scripts/cohort_arr_projector.py"},"region":{"startLine":253}}}],"partialFingerprints":{"codehealthFindingId/v1":"9829d021057728df399e7c1bc0a8f03fd028072e25f38ec680971570d9a1e5b4"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (3\u20135 lines \u00D7 7): engineering-team/skills/senior-prompt-engineer/scripts/agent_orchestrator.py:255-259 | engineering-team/skills/senior-prompt-engineer/scripts/agent_orchestrator.py:266-268 | engineering-team/skills/senior-prompt-engineer/scripts/agent_orchestrator.py:270-275 | engineering-team/skills/senior-prompt-engineer/scripts/agent_orchestrator.py:289-291 | engineering-team/skills/senior-prompt-engineer/scripts/agent_orchestrator.py:295-299 | engineering-team/skills/senior-prompt-engineer/scripts/agent_orchestrator.py:311-315 | engineering-team/skills/senior-prompt-engineer/scripts/agent_orchestrator.py:322-324 \u2014 all 7 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 \u0060engineering-team/skills/senior-prompt-engineer/scripts/agent_orchestrator.py:255\u0060 it does not close everything it opens, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that. Note that the copies do not run to the end of the range shown: their LAST lines are different code, not the same code under different names \u2014 the matched region ends inside that line. Extract the lines above it, and read the last line of each site separately. \u2605 These copies have DRIFTED, and that is worth reading before extracting anything: just after the matched lines, \u0060engineering-team/skills/senior-prompt-engineer/scripts/agent_orchestrator.py:300\u0060 calls \u0060join\u0060 and \u0060engineering-team/skills/senior-prompt-engineer/scripts/agent_orchestrator.py:259\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":"engineering-team/skills/senior-prompt-engineer/scripts/agent_orchestrator.py"},"region":{"startLine":255}}}],"partialFingerprints":{"codehealthFindingId/v1":"dd44526ffb95dcaaa9ad0384904635edd43390f27968750c572b82ff9f6773c5"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 3): engineering/chaos-engineering/skills/chaos-engineering/scripts/experiment_designer.py:72-76 | engineering/skills/chaos-engineering/scripts/experiment_designer.py:72-76 | research/pulse/skills/pulse/scripts/time_window_calculator.py:93-97 \u2014 before extracting anything, compare \u0060engineering/chaos-engineering/skills/chaos-engineering/scripts/experiment_designer.py\u0060 and \u0060engineering/skills/chaos-engineering/scripts/experiment_designer.py\u0060 as WHOLE FILES: this scan already matched 7 separate duplicated blocks between them, totalling at least 111 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/chaos-engineering/skills/chaos-engineering/scripts/experiment_designer.py"},"region":{"startLine":72}}}],"partialFingerprints":{"codehealthFindingId/v1":"7585adcaf4b0f9f0ad143e1405ff939d467676911ae892180556676c2e33e079"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 3): engineering/chaos-engineering/skills/chaos-engineering/scripts/experiment_designer.py:82-86 | engineering/skills/chaos-engineering/scripts/experiment_designer.py:82-86 | research/pulse/skills/pulse/scripts/citation_tracker.py:418-422 \u2014 before extracting anything, compare \u0060engineering/chaos-engineering/skills/chaos-engineering/scripts/experiment_designer.py\u0060 and \u0060engineering/skills/chaos-engineering/scripts/experiment_designer.py\u0060 as WHOLE FILES: this scan already matched 7 separate duplicated blocks between them, totalling at least 111 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/chaos-engineering/skills/chaos-engineering/scripts/experiment_designer.py"},"region":{"startLine":82}}}],"partialFingerprints":{"codehealthFindingId/v1":"2b339df7875553461f97b72143ff6e51155316f91bdb0af76591359d9b20be64"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 3): engineering/chaos-engineering/skills/chaos-engineering/scripts/experiment_designer.py:119-123 | engineering/skills/chaos-engineering/scripts/experiment_designer.py:119-123 | research/research/skills/research/scripts/routing_transparency_logger.py:131-136 \u2014 before extracting anything, compare \u0060engineering/chaos-engineering/skills/chaos-engineering/scripts/experiment_designer.py\u0060 and \u0060engineering/skills/chaos-engineering/scripts/experiment_designer.py\u0060 as WHOLE FILES: this scan already matched 7 separate duplicated blocks between them, totalling at least 111 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. Read the line range as the matched WINDOW rather than a finished unit: at \u0060research/research/skills/research/scripts/routing_transparency_logger.py:131\u0060 it begins part-way through the construct above it, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that. \u2605 These copies have DRIFTED, and that is worth reading before extracting anything: just after the matched lines, \u0060research/research/skills/research/scripts/routing_transparency_logger.py:137\u0060 calls \u0060add_argument\u0060 and \u0060engineering/chaos-engineering/skills/chaos-engineering/scripts/experiment_designer.py:124\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":"engineering/chaos-engineering/skills/chaos-engineering/scripts/experiment_designer.py"},"region":{"startLine":119}}}],"partialFingerprints":{"codehealthFindingId/v1":"0af77da566c8708765cf9a395cce7e74ce057ce62b9ac414f69e7fe3eece84b0"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 3): engineering/skill-doctor/skills/skill-doctor/scripts/score_aggregator.py:73-78 | markdown-html/skills/design-system/scripts/brand_palette_validator.py:304-308 | marketing/landing/skills/landing/scripts/brand_palette_validator.py:240-244 \u2014 before extracting anything, compare \u0060markdown-html/skills/design-system/scripts/brand_palette_validator.py\u0060 and \u0060marketing/landing/skills/landing/scripts/brand_palette_validator.py\u0060 as WHOLE FILES: this scan already matched 12 separate duplicated blocks between them, totalling at least 79 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. 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":"engineering/skill-doctor/skills/skill-doctor/scripts/score_aggregator.py"},"region":{"startLine":73}}}],"partialFingerprints":{"codehealthFindingId/v1":"f2c749960b0bda45a67b8506e663a82aafc5a47cc7afdc2c914686b8b6199874"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 3): markdown-html/skills/design-system/scripts/brand_palette_validator.py:303-307 | marketing/landing/skills/landing/scripts/brand_palette_validator.py:239-243 | productivity/roast/skills/roast/scripts/brief_builder.py:120-124 \u2014 before extracting anything, compare \u0060markdown-html/skills/design-system/scripts/brand_palette_validator.py\u0060 and \u0060marketing/landing/skills/landing/scripts/brand_palette_validator.py\u0060 as WHOLE FILES: this scan already matched 12 separate duplicated blocks between them, totalling at least 79 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. \u2605 These copies have DRIFTED, and that is worth reading before extracting anything: just after the matched lines, \u0060productivity/roast/skills/roast/scripts/brief_builder.py:126\u0060 calls \u0060add_argument\u0060 and \u0060markdown-html/skills/design-system/scripts/brand_palette_validator.py:309\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":"markdown-html/skills/design-system/scripts/brand_palette_validator.py"},"region":{"startLine":303}}}],"partialFingerprints":{"codehealthFindingId/v1":"2b5526a5a6fef4e0f2aa5cec6a29f0b9e0c84cc057f6549e3601f5283a35b460"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 3): marketing-skill/skills/local-seo-manager/scripts/nap_checker.py:252-256 | ra-qm-team/compliance-team-eu-ai-act/skills/eu-ai-act-specialist/scripts/ai_act_obligation_tracker.py:206-210 | ra-qm-team/skills/eu-ai-act-specialist/scripts/ai_act_obligation_tracker.py:206-210 \u2014 before extracting anything, compare \u0060ra-qm-team/compliance-team-eu-ai-act/skills/eu-ai-act-specialist/scripts/ai_act_obligation_tracker.py\u0060 and \u0060ra-qm-team/skills/eu-ai-act-specialist/scripts/ai_act_obligation_tracker.py\u0060 as WHOLE FILES: this scan already matched 11 separate duplicated blocks between them, totalling at least 122 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"marketing-skill/skills/local-seo-manager/scripts/nap_checker.py"},"region":{"startLine":252}}}],"partialFingerprints":{"codehealthFindingId/v1":"1753cd8c36682308fb9da42b0e56b01840cc7b9fa09f2d4b146ebf6483438e22"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 3): research-ops/skills/market-research/scripts/onboard.py:54-58 | research-ops/skills/product-research/scripts/onboard.py:63-67 | research-ops/skills/research-finance/scripts/onboard.py:57-61 \u2014 before extracting anything, compare \u0060research-ops/skills/market-research/scripts/onboard.py\u0060 and \u0060research-ops/skills/product-research/scripts/onboard.py\u0060 as WHOLE FILES: this scan already matched 5 separate duplicated blocks between them, totalling at least 60 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"research-ops/skills/market-research/scripts/onboard.py"},"region":{"startLine":54}}}],"partialFingerprints":{"codehealthFindingId/v1":"a8622860c0d3f6ec0875c0e7fd495b1532f9b19f235f13c2fd743f9b2d8a8742"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (4\u20135 lines \u00D7 3): agent-launcher/skills/grade-iterate/scripts/eval_scaffold.py:81-84 | agent-launcher/skills/interview/scripts/interview_planner.py:190-194 | agent-launcher/skills/run-without-you/scripts/deployment_builder.py:127-131 \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, \u0060agent-launcher/skills/grade-iterate/scripts/eval_scaffold.py:84\u0060 calls \u0060Path\u0060, \u0060write_text\u0060 and \u0060agent-launcher/skills/interview/scripts/interview_planner.py:194\u0060 does not \u2014 after which the two agree again for 5 more lines. One of those two behaviours is the intended one and the other is what a copy-paste left behind, so decide which BEFORE unifying them: extracting the shared part will silently settle it, and if the copy that skips the call is the wrong one, that bug is already live."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"agent-launcher/skills/grade-iterate/scripts/eval_scaffold.py"},"region":{"startLine":81}}}],"partialFingerprints":{"codehealthFindingId/v1":"78cbd417f71d67c7ffb36dc7a08b9d50444f211ea716f2931637dbad517210bc"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): agent-launcher/skills/interview/scripts/primitives_validator.py:135-139 | agent-launcher/skills/stage-launch/scripts/payload_validator.py:135-139 \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":"agent-launcher/skills/interview/scripts/primitives_validator.py"},"region":{"startLine":135}}}],"partialFingerprints":{"codehealthFindingId/v1":"80571be646e47d06e6bc5da086f02c217416499d2d4ee38c3349924d1819e569"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): business-growth/skills/customer-success-manager/scripts/churn_risk_analyzer.py:196-200 | business-growth/skills/customer-success-manager/scripts/churn_risk_analyzer.py:228-232 \u2014 both copies are in the same file, so extract the block into one function there and call it from each site \u2014 the copies drift apart the first time only one of them is edited."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"business-growth/skills/customer-success-manager/scripts/churn_risk_analyzer.py"},"region":{"startLine":196}}}],"partialFingerprints":{"codehealthFindingId/v1":"22ae6ad5ef9d957742533d01902323364fdfc702a5c41a1f83c63e953862ee0c"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): c-level-advisor/arquiteto-de-empresa/skills/arquiteto-de-empresa/scripts/index_generator.py:127-131 | c-level-advisor/skills/arquiteto-de-empresa/scripts/index_generator.py:127-131 \u2014 before extracting anything, compare \u0060c-level-advisor/arquiteto-de-empresa/skills/arquiteto-de-empresa/scripts/index_generator.py\u0060 and \u0060c-level-advisor/skills/arquiteto-de-empresa/scripts/index_generator.py\u0060 as WHOLE FILES: this scan already matched 10 separate duplicated blocks between them, totalling at least 135 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"c-level-advisor/arquiteto-de-empresa/skills/arquiteto-de-empresa/scripts/index_generator.py"},"region":{"startLine":127}}}],"partialFingerprints":{"codehealthFindingId/v1":"d0335255d57de8c7e10178486d6253894a9ea8512f86fd92af10761da019f489"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): c-level-advisor/chief-customer-officer-advisor/skills/chief-customer-officer-advisor/scripts/customer_segmentation_designer.py:307-311 | c-level-advisor/skills/chief-customer-officer-advisor/scripts/customer_segmentation_designer.py:307-311 \u2014 before extracting anything, compare \u0060c-level-advisor/chief-customer-officer-advisor/skills/chief-customer-officer-advisor/scripts/customer_segmentation_designer.py\u0060 and \u0060c-level-advisor/skills/chief-customer-officer-advisor/scripts/customer_segmentation_designer.py\u0060 as WHOLE FILES: this scan already matched 11 separate duplicated blocks between them, totalling at least 146 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The \u0060return\u0060 at the foot of the matched lines is the enclosing body\u0027s own terminal exit, not an early one: it moves with them unchanged, and each site calls the extracted unit from the position that \u0060return\u0060 occupied \u2014 no decision has to be handed back and re-acted on."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"c-level-advisor/chief-customer-officer-advisor/skills/chief-customer-officer-advisor/scripts/customer_segmentation_designer.py"},"region":{"startLine":307}}}],"partialFingerprints":{"codehealthFindingId/v1":"3d4a4bb2652a4697c08be649a8c3f0a78d80de2c3aec03a47fde4660aeb7000b"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): c-level-advisor/chief-customer-officer-advisor/skills/chief-customer-officer-advisor/scripts/retention_decomposition_analyzer.py:269-273 | c-level-advisor/skills/chief-customer-officer-advisor/scripts/retention_decomposition_analyzer.py:269-273 \u2014 before extracting anything, compare \u0060c-level-advisor/chief-customer-officer-advisor/skills/chief-customer-officer-advisor/scripts/retention_decomposition_analyzer.py\u0060 and \u0060c-level-advisor/skills/chief-customer-officer-advisor/scripts/retention_decomposition_analyzer.py\u0060 as WHOLE FILES: this scan already matched 9 separate duplicated blocks between them, totalling at least 171 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The \u0060return\u0060 at the foot of the matched lines is the enclosing body\u0027s own terminal exit, not an early one: it moves with them unchanged, and each site calls the extracted unit from the position that \u0060return\u0060 occupied \u2014 no decision has to be handed back and re-acted on."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"c-level-advisor/chief-customer-officer-advisor/skills/chief-customer-officer-advisor/scripts/retention_decomposition_analyzer.py"},"region":{"startLine":269}}}],"partialFingerprints":{"codehealthFindingId/v1":"a263b62bb19ae02f6fcbcc6c72593932ef3f9b93a1517243315273274c77d189"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): c-level-advisor/skills/cro-advisor/scripts/churn_analyzer.py:504-508 | c-level-advisor/skills/cro-advisor/scripts/revenue_forecast_model.py:328-332 \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 \u0060c-level-advisor/skills/cro-advisor/scripts/churn_analyzer.py:504\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":"c-level-advisor/skills/cro-advisor/scripts/churn_analyzer.py"},"region":{"startLine":504}}}],"partialFingerprints":{"codehealthFindingId/v1":"470ed82503d915b3fdb729b8d6921e345c17a044524b1414c9004eb5d34e1f37"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): c-level-advisor/skills/cro-advisor/scripts/revenue_forecast_model.py:344-348 | c-level-advisor/skills/cro-advisor/scripts/revenue_forecast_model.py:395-399 \u2014 both copies are in the same file, so extract the block 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 \u0060c-level-advisor/skills/cro-advisor/scripts/revenue_forecast_model.py:344\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":"c-level-advisor/skills/cro-advisor/scripts/revenue_forecast_model.py"},"region":{"startLine":344}}}],"partialFingerprints":{"codehealthFindingId/v1":"fc93627cd62c38b003ce97de97fb5a58806bbead6d42d233be184e6538d214b8"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): commercial/skills/commercial-policy/scripts/discount_matrix_builder.py:267-273 | commercial/skills/pricing-strategist/scripts/packaging_designer.py:227-231 \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 \u0060commercial/skills/commercial-policy/scripts/discount_matrix_builder.py:267\u0060 it begins part-way through the construct above it, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that. Note first that the copies are not typed on the same thing: the declarations holding them bind \u0060argv\u0060 to \u0060list[str]\u0060 in one and \u0060list[str] | None = 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":"commercial/skills/commercial-policy/scripts/discount_matrix_builder.py"},"region":{"startLine":267}}}],"partialFingerprints":{"codehealthFindingId/v1":"9b748d67efca5c4d06804946862cd113f779177c373bf1a37a22438710e56069"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): commercial/skills/partnerships-architect/scripts/joint_gtm_planner.py:315-319 | commercial/skills/partnerships-architect/scripts/joint_gtm_planner.py:321-325 \u2014 both copies are in the same file, so extract the block 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":"commercial/skills/partnerships-architect/scripts/joint_gtm_planner.py"},"region":{"startLine":315}}}],"partialFingerprints":{"codehealthFindingId/v1":"9984fced47a3b02cab9f8ae57548ca2ea674915ee2dcbe1dd2c7709dfef8b677"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): commercial/skills/rfp-responder/scripts/rfp_parser.py:246-250 | engineering/skills/interview-system-designer/loop_designer.py:804-809 \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":"commercial/skills/rfp-responder/scripts/rfp_parser.py"},"region":{"startLine":246}}}],"partialFingerprints":{"codehealthFindingId/v1":"54e5770019c417ec9f576c5230b6ca6e7172d692403ce3757ccdb44c430a73b6"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): engineering-team/google-workspace-cli/skills/google-workspace-cli/scripts/gws_recipe_runner.py:393-398 | engineering-team/google-workspace-cli/skills/google-workspace-cli/scripts/output_analyzer.py:245-249 \u2014 the copies sit in sibling files of one directory, so a shared home is within easy reach: extract the block into a single shared function the call sites can all reach \u2014 a file they already depend on, or a new one alongside them \u2014 and call it from both call sites, so a change lands once. Read the line range as the matched WINDOW rather than a finished unit: at \u0060engineering-team/google-workspace-cli/skills/google-workspace-cli/scripts/gws_recipe_runner.py:393\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":"engineering-team/google-workspace-cli/skills/google-workspace-cli/scripts/gws_recipe_runner.py"},"region":{"startLine":393}}}],"partialFingerprints":{"codehealthFindingId/v1":"e61e1aaaa4dc02f3bcae35835bc1635beb00777804d1441483ef3bc5b156dcfc"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): engineering-team/skills/azure-cloud-architect/scripts/architecture_designer.py:496-500 | engineering/skills/skill-tester/assets/sample-skill/scripts/text_processor.py:276-280 \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":"engineering-team/skills/azure-cloud-architect/scripts/architecture_designer.py"},"region":{"startLine":496}}}],"partialFingerprints":{"codehealthFindingId/v1":"75c8f95d9b198413ce4c3db800740daea4a6c33b7e450f4915e87d46020a95dc"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): engineering-team/skills/code-reviewer/scripts/code_quality_checker.py:951-955 | engineering/llm-wiki/skills/llm-wiki/scripts/ingest_source.py:162-166 \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 \u0060engineering-team/skills/code-reviewer/scripts/code_quality_checker.py:951\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":"engineering-team/skills/code-reviewer/scripts/code_quality_checker.py"},"region":{"startLine":951}}}],"partialFingerprints":{"codehealthFindingId/v1":"379cb3b8a1514d7001e77457d2e92a1eac5ab64d80f230d864ecc12a4f3fee47"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): engineering-team/skills/incident-commander/scripts/incident_classifier.py:695-701 | research/grants/skills/grants/scripts/fiscal_year_calculator.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."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/skills/incident-commander/scripts/incident_classifier.py"},"region":{"startLine":695}}}],"partialFingerprints":{"codehealthFindingId/v1":"809db902f107bb2f9eec0f7aa1f0f0e6481d7552c63278e5cc3f1c32975e27e7"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): engineering-team/skills/senior-frontend/scripts/component_generator.py:226-230 | engineering-team/skills/senior-frontend/scripts/frontend_scaffolder.py:902-906 \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. Note first that the copies are not typed on the same thing: the declarations holding them bind \u0060result\u0060 to \u0060dict\u0060 in one and \u0060Dict\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":"engineering-team/skills/senior-frontend/scripts/component_generator.py"},"region":{"startLine":226}}}],"partialFingerprints":{"codehealthFindingId/v1":"f031ec682608be049c3ad8d84d6735b7b0cc6f8d4450170344085ab753537a27"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): engineering-team/skills/senior-prompt-engineer/scripts/agent_orchestrator.py:279-283 | engineering-team/skills/senior-prompt-engineer/scripts/agent_orchestrator.py:301-305 \u2014 both copies are in the same file, so extract the block into one function there and call it from each site \u2014 the copies drift apart the first time only one of them is edited. Read the line range as the matched WINDOW rather than a finished unit: at \u0060engineering-team/skills/senior-prompt-engineer/scripts/agent_orchestrator.py:279\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":"engineering-team/skills/senior-prompt-engineer/scripts/agent_orchestrator.py"},"region":{"startLine":279}}}],"partialFingerprints":{"codehealthFindingId/v1":"d3039c7b3182b1dad1aa054815a96c7b2be68fa5c7ba4fec02a7fbd7d8c98d0d"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): engineering-team/skills/senior-prompt-engineer/scripts/agent_orchestrator.py:491-495 | engineering/skills/database-designer/index_optimizer.py:871-876 \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":"engineering-team/skills/senior-prompt-engineer/scripts/agent_orchestrator.py"},"region":{"startLine":491}}}],"partialFingerprints":{"codehealthFindingId/v1":"3faed022bfce16edf15010f1a892db49daa95a42137bf968d6eeadcb4b702951"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): engineering-team/skills/tdd-guide/scripts/metrics_calculator.py:432-436 | engineering-team/skills/tdd-guide/scripts/metrics_calculator.py:441-445 \u2014 both copies are in the same file, so extract the block 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":"engineering-team/skills/tdd-guide/scripts/metrics_calculator.py"},"region":{"startLine":432}}}],"partialFingerprints":{"codehealthFindingId/v1":"e4236e996df074c7f1e3ead3de62af96322f25e38f46ca3354fa1022ce3fe996"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): engineering/feature-flags-architect/skills/feature-flags-architect/scripts/rollout_planner.py:86-90 | engineering/skills/feature-flags-architect/scripts/rollout_planner.py:86-90 \u2014 before extracting anything, compare \u0060engineering/feature-flags-architect/skills/feature-flags-architect/scripts/rollout_planner.py\u0060 and \u0060engineering/skills/feature-flags-architect/scripts/rollout_planner.py\u0060 as WHOLE FILES: this scan already matched 5 separate duplicated blocks between them, totalling at least 68 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/feature-flags-architect/skills/feature-flags-architect/scripts/rollout_planner.py"},"region":{"startLine":86}}}],"partialFingerprints":{"codehealthFindingId/v1":"065070f6402d9cdba7bb38611bf069b256fa9ea657cc72040315ad49a00d2246"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): engineering/kubernetes-operator/skills/kubernetes-operator/scripts/crd_validator.py:66-70 | engineering/skills/kubernetes-operator/scripts/crd_validator.py:66-70 \u2014 before extracting anything, compare \u0060engineering/kubernetes-operator/skills/kubernetes-operator/scripts/crd_validator.py\u0060 and \u0060engineering/skills/kubernetes-operator/scripts/crd_validator.py\u0060 as WHOLE FILES: this scan already matched 8 separate duplicated blocks between them, totalling at least 79 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The \u0060return\u0060 at the foot of the matched lines is the enclosing body\u0027s own terminal exit, not an early one: it moves with them unchanged, and each site calls the extracted unit from the position that \u0060return\u0060 occupied \u2014 no decision has to be handed back and re-acted on."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/kubernetes-operator/skills/kubernetes-operator/scripts/crd_validator.py"},"region":{"startLine":66}}}],"partialFingerprints":{"codehealthFindingId/v1":"cdc1532f2d692e6c5c0dbdb127bfc0ef43a7a9ab57258818fc20149399136bd5"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): engineering/kubernetes-operator/skills/kubernetes-operator/scripts/crd_validator.py:99-103 | engineering/skills/kubernetes-operator/scripts/crd_validator.py:99-103 \u2014 before extracting anything, compare \u0060engineering/kubernetes-operator/skills/kubernetes-operator/scripts/crd_validator.py\u0060 and \u0060engineering/skills/kubernetes-operator/scripts/crd_validator.py\u0060 as WHOLE FILES: this scan already matched 8 separate duplicated blocks between them, totalling at least 79 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/kubernetes-operator/skills/kubernetes-operator/scripts/crd_validator.py"},"region":{"startLine":99}}}],"partialFingerprints":{"codehealthFindingId/v1":"1746a3283dff4a18523a592f7cffebb2875ffc2013dde07aa6dea7c7fb55a4c9"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): engineering/memory-engineering/skills/memory-engineering/scripts/memory_density_auditor.py:552-556 | engineering/skills/tech-debt-tracker/scripts/debt_scanner.py:591-595 \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":"engineering/memory-engineering/skills/memory-engineering/scripts/memory_density_auditor.py"},"region":{"startLine":552}}}],"partialFingerprints":{"codehealthFindingId/v1":"301eb42a29f8fbdf0534da6b4a159e364ff2c7186ace9102114168ce8d6e359c"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): engineering/skills/interview-system-designer/loop_designer.py:832-836 | engineering/skills/interview-system-designer/question_bank_generator.py:977-981 \u2014 the copies sit in sibling files of one directory, so a shared home is within easy reach: extract the block into a single shared function the call sites can all reach \u2014 a file they already depend on, or a new one alongside them \u2014 and call it from both call sites, so a change lands once. \u2605 These copies have DRIFTED, and that is worth reading before extracting anything: just before the matched lines, \u0060engineering/skills/interview-system-designer/question_bank_generator.py:976\u0060 calls \u0060add_argument\u0060 and \u0060engineering/skills/interview-system-designer/loop_designer.py:831\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":"engineering/skills/interview-system-designer/loop_designer.py"},"region":{"startLine":832}}}],"partialFingerprints":{"codehealthFindingId/v1":"dbc096d65248e41d299803d17a5a0517b71a4450f7aaeb9ed7a10e6a64c50001"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): engineering/skills/observability-designer/scripts/slo_designer.py:566-570 | engineering/skills/observability-designer/scripts/slo_designer.py:573-577 \u2014 both copies are in the same file, so extract the block into one function there and call it from each site \u2014 the copies drift apart the first time only one of them is edited."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/observability-designer/scripts/slo_designer.py"},"region":{"startLine":566}}}],"partialFingerprints":{"codehealthFindingId/v1":"c27ddef80ed02d29cb568e07c1b49a6288f4befe93fe3a1ac6d1247796119750"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): engineering/skills/slo-architect/scripts/slo_designer.py:79-83 | engineering/slo-architect/skills/slo-architect/scripts/slo_designer.py:79-83 \u2014 before extracting anything, compare \u0060engineering/skills/slo-architect/scripts/slo_designer.py\u0060 and \u0060engineering/slo-architect/skills/slo-architect/scripts/slo_designer.py\u0060 as WHOLE FILES: this scan already matched 8 separate duplicated blocks between them, totalling at least 70 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/slo-architect/scripts/slo_designer.py"},"region":{"startLine":79}}}],"partialFingerprints":{"codehealthFindingId/v1":"e9a9488c69519c4299cbc6914df23b8bbe87acbef87270f8a27d860e391e2da7"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): engineering/skills/tc-tracker/scripts/tc_validator.py:191-195 | engineering/skills/tc-tracker/scripts/tc_validator.py:211-215 \u2014 both copies are in the same file, so extract the block into one function there and call it from each site \u2014 the copies drift apart the first time only one of them is edited."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/tc-tracker/scripts/tc_validator.py"},"region":{"startLine":191}}}],"partialFingerprints":{"codehealthFindingId/v1":"47f05ddda7ea3f1eca9a4e512f44c3ba363aea860e25919f3bb08c9f654b4e07"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): engineering/skills/tech-debt-tracker/scripts/debt_dashboard.py:849-853 | research/pulse/skills/pulse/scripts/time_window_calculator.py:94-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."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/tech-debt-tracker/scripts/debt_dashboard.py"},"region":{"startLine":849}}}],"partialFingerprints":{"codehealthFindingId/v1":"7142ec7218cdc204996b9b0c1d34067d82d869d0b2654c8fbc511f391bcd821a"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): finance/skills/financial-analyst/scripts/ratio_calculator.py:195-199 | finance/skills/financial-analyst/scripts/ratio_calculator.py:241-245 \u2014 both copies are in the same file, so extract the block into one function there and call it from each site \u2014 the copies drift apart the first time only one of them is edited."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"finance/skills/financial-analyst/scripts/ratio_calculator.py"},"region":{"startLine":195}}}],"partialFingerprints":{"codehealthFindingId/v1":"c553c6a05ba17d03db374ffafc02d56f2d34f99668e7f115df5a2b40270dcf38"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (2\u20135 lines \u00D7 3): finance/skills/saas-metrics-coach/scripts/quick_ratio_calculator.py:112-116 | finance/skills/saas-metrics-coach/scripts/unit_economics_simulator.py:130-134 | finance/skills/saas-metrics-coach/scripts/unit_economics_simulator.py:137-138 \u2014 there are 3 copies across 2 file(s) \u2014 more copies than files, so at least one file holds the block twice. Extract it once into a single shared function every call site can reach and call it from all 3 sites; resolving a subset leaves the remainder to drift apart."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"finance/skills/saas-metrics-coach/scripts/quick_ratio_calculator.py"},"region":{"startLine":112}}}],"partialFingerprints":{"codehealthFindingId/v1":"7301358c0d2b92f998825e53cc9eb227551f2f8a4b9b721def0625f523ea36f0"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): finance/skills/stock-analysis/scripts/ratios.py:1637-1641 | finance/skills/stock-analysis/scripts/ratios.py:1644-1648 \u2014 both copies are in the same file, so extract the block into one function there and call it from each site \u2014 the copies drift apart the first time only one of them is edited. Read the line range as the matched WINDOW rather than a finished unit: at \u0060finance/skills/stock-analysis/scripts/ratios.py:1637\u0060 it begins part-way through the construct above it, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that. Note that the copies do not run to the end of the range shown: their LAST lines are different code, not the same code under different names \u2014 the matched region ends inside that line. Extract the lines above it, and read the last line of each site separately."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"finance/skills/stock-analysis/scripts/ratios.py"},"region":{"startLine":1637}}}],"partialFingerprints":{"codehealthFindingId/v1":"6edf381dcef8ea603bbeb03a5543f50197fbd1400f07fbe0a91e49ed8a2d4229"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): finance/skills/stock-analysis/scripts/valuation.py:398-403 | finance/skills/stock-analysis/scripts/valuation.py:462-466 \u2014 both copies are in the same file, so extract the block 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 \u0060finance/skills/stock-analysis/scripts/valuation.py:398\u0060 it begins part-way through the construct above it, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that. The \u0060return\u0060 at the foot of the matched lines is the enclosing body\u0027s own terminal exit, not an early one: it moves with them unchanged, and each site calls the extracted unit from the position that \u0060return\u0060 occupied \u2014 no decision has to be handed back and re-acted on."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"finance/skills/stock-analysis/scripts/valuation.py"},"region":{"startLine":398}}}],"partialFingerprints":{"codehealthFindingId/v1":"848a7e79b141203fae7474868d4ca0f935b511863f5e023de538434a6255ae71"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): markdown-html/skills/design-system/scripts/brand_palette_validator.py:53-57 | marketing/landing/skills/landing/scripts/brand_palette_validator.py:49-53 \u2014 before extracting anything, compare \u0060markdown-html/skills/design-system/scripts/brand_palette_validator.py\u0060 and \u0060marketing/landing/skills/landing/scripts/brand_palette_validator.py\u0060 as WHOLE FILES: this scan already matched 12 separate duplicated blocks between them, totalling at least 79 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. Note first that the copies are not typed on the same thing: the declarations holding them bind \u0060rgb\u0060 to \u0060tuple[int, int, int]\u0060 in one and \u0060Tuple[int, int, int]\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":"markdown-html/skills/design-system/scripts/brand_palette_validator.py"},"region":{"startLine":53}}}],"partialFingerprints":{"codehealthFindingId/v1":"35c029a65c99a29311e88a0e4898734b3241b4717f519958690bce91992e2abf"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): marketing-skill/skills/campaign-analytics/scripts/attribution_analyzer.py:216-220 | productivity/email/skills/inbox-setup/scripts/voice_sample_analyzer.py:218-222 \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":"marketing-skill/skills/campaign-analytics/scripts/attribution_analyzer.py"},"region":{"startLine":216}}}],"partialFingerprints":{"codehealthFindingId/v1":"f2b80b6b8efd9153aeb6326424e8178bb0ed02cbfc7c42a0e342cc9fee12df30"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): marketing/landing/skills/landing/scripts/kebab_slug_generator.py:89-93 | research/pulse/skills/pulse/scripts/topic_slug_generator.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 \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":"marketing/landing/skills/landing/scripts/kebab_slug_generator.py"},"region":{"startLine":89}}}],"partialFingerprints":{"codehealthFindingId/v1":"55554f1e0645c910a1088d96b69c20f042080c93a21df0ca99a0fcebd2dc8d5d"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): marketing/linkedin/skills/linkedin-content/scripts/post_linter.py:302-306 | research/pulse/skills/pulse/scripts/citation_tracker.py:490-494 \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 \u0060research/pulse/skills/pulse/scripts/citation_tracker.py:490\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":"marketing/linkedin/skills/linkedin-content/scripts/post_linter.py"},"region":{"startLine":302}}}],"partialFingerprints":{"codehealthFindingId/v1":"b66cdb9a979f305ac6063233c42ca233fcd45a6ccb66eda0d590007e7028f4a6"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): marketing/linkedin/skills/linkedin-engagement/scripts/outreach_message_builder.py:216-221 | productivity/roast/skills/roast/scripts/brief_builder.py:122-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. 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":"marketing/linkedin/skills/linkedin-engagement/scripts/outreach_message_builder.py"},"region":{"startLine":216}}}],"partialFingerprints":{"codehealthFindingId/v1":"00021291475256a8322239a44125825b3a06e43f284197491b9a5327a92bf2ed"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): marketing/linkedin/skills/linkedin-skills/scripts/linkedin_policy_gate.py:263-267 | marketing/linkedin/skills/linkedin-skills/scripts/linkedin_policy_gate.py:270-274 \u2014 both copies are in the same file, so extract the block into one function there and call it from each site \u2014 the copies drift apart the first time only one of them is edited."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"marketing/linkedin/skills/linkedin-skills/scripts/linkedin_policy_gate.py"},"region":{"startLine":263}}}],"partialFingerprints":{"codehealthFindingId/v1":"af79d87f4fc6dd87f2bc8d97e18b833bbae8598d6307382a3e4407f531595b70"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): productivity/email/skills/inbox-setup/scripts/section_progress_tracker.py:186-190 | research/litreview/skills/litreview/scripts/citation_tracker.py:183-187 \u2014 before extracting anything, compare \u0060productivity/email/skills/inbox-setup/scripts/section_progress_tracker.py\u0060 and \u0060research/litreview/skills/litreview/scripts/citation_tracker.py\u0060 as WHOLE FILES: this scan already matched 6 separate duplicated blocks between them, totalling at least 70 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"productivity/email/skills/inbox-setup/scripts/section_progress_tracker.py"},"region":{"startLine":186}}}],"partialFingerprints":{"codehealthFindingId/v1":"b979aa542c2fd7f74906229e0257f7d8bf6bfa1d8a2b1e787bbf2d73f532ea14"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): productivity/handoff/skills/handoff/scripts/cleanup.py:125-129 | productivity/handoff/skills/handoff/scripts/config_loader.py:128-132 \u2014 the copies sit in sibling files of one directory, so a shared home is within easy reach: extract the block into a single shared function the call sites can all reach \u2014 a file they already depend on, or a new one alongside them \u2014 and call it from both call sites, so a change lands once."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"productivity/handoff/skills/handoff/scripts/cleanup.py"},"region":{"startLine":125}}}],"partialFingerprints":{"codehealthFindingId/v1":"5229d94cd28fdfa6025b96fc4e304bbdd07b05214a7251d5d4e6a673ee9d00e2"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): ra-qm-team/compliance-team-iso42001/skills/iso42001-specialist/scripts/aims_audit_scheduler.py:221-225 | ra-qm-team/skills/iso42001-specialist/scripts/aims_audit_scheduler.py:221-225 \u2014 before extracting anything, compare \u0060ra-qm-team/compliance-team-iso42001/skills/iso42001-specialist/scripts/aims_audit_scheduler.py\u0060 and \u0060ra-qm-team/skills/iso42001-specialist/scripts/aims_audit_scheduler.py\u0060 as WHOLE FILES: this scan already matched 9 separate duplicated blocks between them, totalling at least 151 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The \u0060return\u0060 at the foot of the matched lines is the enclosing body\u0027s own terminal exit, not an early one: it moves with them unchanged, and each site calls the extracted unit from the position that \u0060return\u0060 occupied \u2014 no decision has to be handed back and re-acted on."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"ra-qm-team/compliance-team-iso42001/skills/iso42001-specialist/scripts/aims_audit_scheduler.py"},"region":{"startLine":221}}}],"partialFingerprints":{"codehealthFindingId/v1":"a472b565f01960440ec10ceb586f03062ef0ff4dc39d1f3ce827897709b32c66"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): research/grants/skills/grants/scripts/citation_tracker.py:107-111 | research/syllabus/skills/syllabus/scripts/citation_tracker.py:94-98 \u2014 before extracting anything, compare \u0060research/grants/skills/grants/scripts/citation_tracker.py\u0060 and \u0060research/syllabus/skills/syllabus/scripts/citation_tracker.py\u0060 as WHOLE FILES: this scan already matched 4 separate duplicated blocks between them, totalling at least 48 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. Read the line range as the matched WINDOW rather than a finished unit: at \u0060research/grants/skills/grants/scripts/citation_tracker.py:107\u0060 it begins part-way through the construct above it, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"research/grants/skills/grants/scripts/citation_tracker.py"},"region":{"startLine":107}}}],"partialFingerprints":{"codehealthFindingId/v1":"a46df67c75fdf602bed4faf794fd7c72a26bba3488b1ce0c7b17398c1f12fe7d"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): research/patent/skills/patent/scripts/citation_tracker.py:166-170 | research/syllabus/skills/syllabus/scripts/citation_tracker.py:149-153 \u2014 before extracting anything, compare \u0060research/patent/skills/patent/scripts/citation_tracker.py\u0060 and \u0060research/syllabus/skills/syllabus/scripts/citation_tracker.py\u0060 as WHOLE FILES: this scan already matched 6 separate duplicated blocks between them, totalling at least 43 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"research/patent/skills/patent/scripts/citation_tracker.py"},"region":{"startLine":166}}}],"partialFingerprints":{"codehealthFindingId/v1":"4c04a82fc66d6393ed2178addd167e70f217901c48268c68639c73ce66ea1861"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): scripts/check_frontmatter.py:162-166 | scripts/check_paths.py:160-164 \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":"scripts/check_frontmatter.py"},"region":{"startLine":162}}}],"partialFingerprints":{"codehealthFindingId/v1":"d9218f9f81582fcb5bf7be0e52227f6b9b102d230608e9858e65f9eb5bef10d4"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): scripts/check_frontmatter.py:167-171 | scripts/check_paths.py:165-169 \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":"scripts/check_frontmatter.py"},"region":{"startLine":167}}}],"partialFingerprints":{"codehealthFindingId/v1":"95feb7fcbdc87659b8cb8b809fc5f74a44afa73f7c3058b7a3af5f3e0aea57b1"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): scripts/generate-docs.py:484-488 | scripts/generate-docs.py:517-521 \u2014 both copies are in the same file, so extract the block 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/generate-docs.py"},"region":{"startLine":484}}}],"partialFingerprints":{"codehealthFindingId/v1":"55ac19fdd6168e8ac0e31b95c2b64c667260ff698733e3c6a07d4755187da681"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (39 lines \u00D7 4): project-management/skills/atlassian-admin/scripts/permission_audit_tool.py:427-465 | project-management/skills/confluence-expert/scripts/content_audit_analyzer.py:415-453 | project-management/skills/confluence-expert/scripts/space_structure_generator.py:475-513 | project-management/skills/jira-expert/scripts/workflow_validator.py:382-420 \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":"project-management/skills/atlassian-admin/scripts/permission_audit_tool.py"},"region":{"startLine":427}}}],"partialFingerprints":{"codehealthFindingId/v1":"d2206ec3797b0e579a1ebb90589832d7a8db56b4742e79f1c4ea2e3a64f8ff12"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2): business-growth/skills/revenue-operations/scripts/forecast_accuracy_tracker.py:399-404 | business-growth/skills/revenue-operations/scripts/gtm_efficiency_calculator.py:498-503 \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":"business-growth/skills/revenue-operations/scripts/forecast_accuracy_tracker.py"},"region":{"startLine":399}}}],"partialFingerprints":{"codehealthFindingId/v1":"e0acc2c45291c2b7668efd98816d93e0c2c7c6391d33ff21fdd547b9ba6682be"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (8 lines \u00D7 2): business-operations/skills/procurement-optimizer/scripts/purchasing_cycle_analyzer.py:40-47 | business-operations/skills/procurement-optimizer/scripts/supplier_consolidation.py:58-65 \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":"business-operations/skills/procurement-optimizer/scripts/purchasing_cycle_analyzer.py"},"region":{"startLine":40}}}],"partialFingerprints":{"codehealthFindingId/v1":"0c76b8dc896bbe1a3b56a67c19e16768eee83b8dd637a525cf13f833225d7aa9"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2): c-level-advisor/arquiteto-de-empresa/skills/arquiteto-de-empresa/scripts/scaffold_bundle.py:53-58 | c-level-advisor/skills/arquiteto-de-empresa/scripts/scaffold_bundle.py:53-58 \u2014 before extracting anything, compare \u0060c-level-advisor/arquiteto-de-empresa/skills/arquiteto-de-empresa/scripts/scaffold_bundle.py\u0060 and \u0060c-level-advisor/skills/arquiteto-de-empresa/scripts/scaffold_bundle.py\u0060 as WHOLE FILES: this scan already matched 7 separate duplicated blocks between them, totalling at least 108 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"c-level-advisor/arquiteto-de-empresa/skills/arquiteto-de-empresa/scripts/scaffold_bundle.py"},"region":{"startLine":53}}}],"partialFingerprints":{"codehealthFindingId/v1":"1a358254818441ef26d7d689459b3f0cdebeb7952a66110d898fa0834174475f"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2): c-level-advisor/arquiteto-de-empresa/skills/arquiteto-de-empresa/scripts/scaffold_bundle.py:62-67 | c-level-advisor/skills/arquiteto-de-empresa/scripts/scaffold_bundle.py:62-67 \u2014 before extracting anything, compare \u0060c-level-advisor/arquiteto-de-empresa/skills/arquiteto-de-empresa/scripts/scaffold_bundle.py\u0060 and \u0060c-level-advisor/skills/arquiteto-de-empresa/scripts/scaffold_bundle.py\u0060 as WHOLE FILES: this scan already matched 7 separate duplicated blocks between them, totalling at least 108 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The \u0060return\u0060 at the foot of the matched lines is the enclosing body\u0027s own terminal exit, not an early one: it moves with them unchanged, and each site calls the extracted unit from the position that \u0060return\u0060 occupied \u2014 no decision has to be handed back and re-acted on."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"c-level-advisor/arquiteto-de-empresa/skills/arquiteto-de-empresa/scripts/scaffold_bundle.py"},"region":{"startLine":62}}}],"partialFingerprints":{"codehealthFindingId/v1":"1df23e5eeb8a50fa2db2ddc9ffcf8c4145da8b56413439f6bbbba23ae9a647a9"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9 lines \u00D7 2): c-level-advisor/arquiteto-de-empresa/skills/arquiteto-de-empresa/scripts/scaffold_bundle.py:116-124 | c-level-advisor/skills/arquiteto-de-empresa/scripts/scaffold_bundle.py:116-124 \u2014 before extracting anything, compare \u0060c-level-advisor/arquiteto-de-empresa/skills/arquiteto-de-empresa/scripts/scaffold_bundle.py\u0060 and \u0060c-level-advisor/skills/arquiteto-de-empresa/scripts/scaffold_bundle.py\u0060 as WHOLE FILES: this scan already matched 7 separate duplicated blocks between them, totalling at least 108 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The \u0060return\u0060 at the foot of the matched lines is the enclosing body\u0027s own terminal exit, not an early one: it moves with them unchanged, and each site calls the extracted unit from the position that \u0060return\u0060 occupied \u2014 no decision has to be handed back and re-acted on."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"c-level-advisor/arquiteto-de-empresa/skills/arquiteto-de-empresa/scripts/scaffold_bundle.py"},"region":{"startLine":116}}}],"partialFingerprints":{"codehealthFindingId/v1":"c4a5ac07f9e1fafc8ed3ffb10a29c8c32000e1924fc1cfc044a2a4bf9606cba3"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): c-level-advisor/chief-ai-officer-advisor/skills/chief-ai-officer-advisor/scripts/ai_cost_economics.py:84-88 | c-level-advisor/skills/chief-ai-officer-advisor/scripts/ai_cost_economics.py:84-88 \u2014 before extracting anything, compare \u0060c-level-advisor/chief-ai-officer-advisor/skills/chief-ai-officer-advisor/scripts/ai_cost_economics.py\u0060 and \u0060c-level-advisor/skills/chief-ai-officer-advisor/scripts/ai_cost_economics.py\u0060 as WHOLE FILES: this scan already matched 11 separate duplicated blocks between them, totalling at least 231 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"c-level-advisor/chief-ai-officer-advisor/skills/chief-ai-officer-advisor/scripts/ai_cost_economics.py"},"region":{"startLine":84}}}],"partialFingerprints":{"codehealthFindingId/v1":"7d5fdfccafec9a4bd5f577855d2dca967df7df8906745bf7fc3ac28ad968e798"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (36 lines \u00D7 2): c-level-advisor/chief-ai-officer-advisor/skills/chief-ai-officer-advisor/scripts/ai_risk_classifier.py:262-297 | c-level-advisor/skills/chief-ai-officer-advisor/scripts/ai_risk_classifier.py:262-297 \u2014 before extracting anything, compare \u0060c-level-advisor/chief-ai-officer-advisor/skills/chief-ai-officer-advisor/scripts/ai_risk_classifier.py\u0060 and \u0060c-level-advisor/skills/chief-ai-officer-advisor/scripts/ai_risk_classifier.py\u0060 as WHOLE FILES: this scan already matched 11 separate duplicated blocks between them, totalling at least 356 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The \u0060return\u0060 at the foot of the matched lines is the enclosing body\u0027s own terminal exit, not an early one: it moves with them unchanged, and each site calls the extracted unit from the position that \u0060return\u0060 occupied \u2014 no decision has to be handed back and re-acted on."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"c-level-advisor/chief-ai-officer-advisor/skills/chief-ai-officer-advisor/scripts/ai_risk_classifier.py"},"region":{"startLine":262}}}],"partialFingerprints":{"codehealthFindingId/v1":"400e0319ba6f86ba2e18afd56d814b94c0b746a189d861aaac6dc4489a3dd927"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (14 lines \u00D7 2): c-level-advisor/chief-ai-officer-advisor/skills/chief-ai-officer-advisor/scripts/ai_risk_classifier.py:342-355 | c-level-advisor/skills/chief-ai-officer-advisor/scripts/ai_risk_classifier.py:342-355 \u2014 before extracting anything, compare \u0060c-level-advisor/chief-ai-officer-advisor/skills/chief-ai-officer-advisor/scripts/ai_risk_classifier.py\u0060 and \u0060c-level-advisor/skills/chief-ai-officer-advisor/scripts/ai_risk_classifier.py\u0060 as WHOLE FILES: this scan already matched 11 separate duplicated blocks between them, totalling at least 356 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"c-level-advisor/chief-ai-officer-advisor/skills/chief-ai-officer-advisor/scripts/ai_risk_classifier.py"},"region":{"startLine":342}}}],"partialFingerprints":{"codehealthFindingId/v1":"37e221527fced108581787ca6e7fe30756901a29f7d5d4043e8e688a5c0424fc"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 2): c-level-advisor/chief-ai-officer-advisor/skills/chief-ai-officer-advisor/scripts/model_buildvsbuy_calculator.py:97-103 | c-level-advisor/skills/chief-ai-officer-advisor/scripts/model_buildvsbuy_calculator.py:97-103 \u2014 before extracting anything, compare \u0060c-level-advisor/chief-ai-officer-advisor/skills/chief-ai-officer-advisor/scripts/model_buildvsbuy_calculator.py\u0060 and \u0060c-level-advisor/skills/chief-ai-officer-advisor/scripts/model_buildvsbuy_calculator.py\u0060 as WHOLE FILES: this scan already matched 12 separate duplicated blocks between them, totalling at least 251 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The \u0060return\u0060 at the foot of the matched lines is the enclosing body\u0027s own terminal exit, not an early one: it moves with them unchanged, and each site calls the extracted unit from the position that \u0060return\u0060 occupied \u2014 no decision has to be handed back and re-acted on."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"c-level-advisor/chief-ai-officer-advisor/skills/chief-ai-officer-advisor/scripts/model_buildvsbuy_calculator.py"},"region":{"startLine":97}}}],"partialFingerprints":{"codehealthFindingId/v1":"5f0a852fcb76ef9f598c593d3d2a3886b31f98768c246f21f7db2fdd4edb9f9f"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): c-level-advisor/chief-customer-officer-advisor/skills/chief-customer-officer-advisor/scripts/customer_segmentation_designer.py:179-183 | c-level-advisor/skills/chief-customer-officer-advisor/scripts/customer_segmentation_designer.py:179-183 \u2014 before extracting anything, compare \u0060c-level-advisor/chief-customer-officer-advisor/skills/chief-customer-officer-advisor/scripts/customer_segmentation_designer.py\u0060 and \u0060c-level-advisor/skills/chief-customer-officer-advisor/scripts/customer_segmentation_designer.py\u0060 as WHOLE FILES: this scan already matched 11 separate duplicated blocks between them, totalling at least 146 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The \u0060return\u0060 at the foot of the matched lines is the enclosing body\u0027s own terminal exit, not an early one: it moves with them unchanged, and each site calls the extracted unit from the position that \u0060return\u0060 occupied \u2014 no decision has to be handed back and re-acted on."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"c-level-advisor/chief-customer-officer-advisor/skills/chief-customer-officer-advisor/scripts/customer_segmentation_designer.py"},"region":{"startLine":179}}}],"partialFingerprints":{"codehealthFindingId/v1":"a0dc8127c84c64f11fc7b59d37d8abfe51e3fc65f09dabfcb7083b893cda4699"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (14 lines \u00D7 2): c-level-advisor/chief-customer-officer-advisor/skills/chief-customer-officer-advisor/scripts/retention_decomposition_analyzer.py:217-230 | c-level-advisor/skills/chief-customer-officer-advisor/scripts/retention_decomposition_analyzer.py:217-230 \u2014 before extracting anything, compare \u0060c-level-advisor/chief-customer-officer-advisor/skills/chief-customer-officer-advisor/scripts/retention_decomposition_analyzer.py\u0060 and \u0060c-level-advisor/skills/chief-customer-officer-advisor/scripts/retention_decomposition_analyzer.py\u0060 as WHOLE FILES: this scan already matched 9 separate duplicated blocks between them, totalling at least 171 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"c-level-advisor/chief-customer-officer-advisor/skills/chief-customer-officer-advisor/scripts/retention_decomposition_analyzer.py"},"region":{"startLine":217}}}],"partialFingerprints":{"codehealthFindingId/v1":"c97ce37bbcf27543a0474820e032ab511d28a9f7cba4c582351fecfa93f5a1a1"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (10 lines \u00D7 2): c-level-advisor/chief-data-officer-advisor/skills/chief-data-officer-advisor/scripts/data_asset_valuator.py:261-270 | c-level-advisor/skills/chief-data-officer-advisor/scripts/data_asset_valuator.py:261-270 \u2014 before extracting anything, compare \u0060c-level-advisor/chief-data-officer-advisor/skills/chief-data-officer-advisor/scripts/data_asset_valuator.py\u0060 and \u0060c-level-advisor/skills/chief-data-officer-advisor/scripts/data_asset_valuator.py\u0060 as WHOLE FILES: this scan already matched 12 separate duplicated blocks between them, totalling at least 283 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"c-level-advisor/chief-data-officer-advisor/skills/chief-data-officer-advisor/scripts/data_asset_valuator.py"},"region":{"startLine":261}}}],"partialFingerprints":{"codehealthFindingId/v1":"65ba1003b986fe008ae82420e16dd655fae5dd9d045dde7ef2327a5455e2b697"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (11 lines \u00D7 4): c-level-advisor/skills/ceo-advisor/scripts/strategy_analyzer.py:138-148 | engineering-team/skills/code-reviewer/scripts/code_quality_checker.py:823-833 | engineering-team/skills/tech-stack-evaluator/scripts/security_assessor.py:230-248 | product-team/skills/competitive-teardown/scripts/competitive_matrix_builder.py:78-88 \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 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 \u0060score\u0060 to \u0060float\u0060 in one and \u0060int\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":"c-level-advisor/skills/ceo-advisor/scripts/strategy_analyzer.py"},"region":{"startLine":138}}}],"partialFingerprints":{"codehealthFindingId/v1":"90e53cee0da987130620ceced67538ae4e32f89dd5e3058ac791e780e4fd6400"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 5): c-level-advisor/skills/ciso-advisor/scripts/compliance_tracker.py:554-558 | c-level-advisor/skills/cmo-advisor/scripts/growth_model_simulator.py:249-253 | c-level-advisor/skills/cmo-advisor/scripts/marketing_budget_modeler.py:248-252 | c-level-advisor/skills/cro-advisor/scripts/churn_analyzer.py:398-402 | c-level-advisor/skills/cro-advisor/scripts/revenue_forecast_model.py:272-276 \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 after the matched lines, \u0060c-level-advisor/skills/cmo-advisor/scripts/marketing_budget_modeler.py:255\u0060 calls \u0060fmt_ratio\u0060 and \u0060c-level-advisor/skills/cmo-advisor/scripts/growth_model_simulator.py:256\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":"c-level-advisor/skills/ciso-advisor/scripts/compliance_tracker.py"},"region":{"startLine":554}}}],"partialFingerprints":{"codehealthFindingId/v1":"55646f15dd1a051ba73d9de40028d1b7b86bebfaf8e900eeac603e59c53f4a1c"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 4): c-level-advisor/skills/cro-advisor/scripts/churn_analyzer.py:410-418 | marketing-skill/skills/ab-test-setup/scripts/sample_size_calculator.py:208-212 | marketing-skill/skills/launch-strategy/scripts/launch_readiness_scorer.py:205-209 | marketing-skill/skills/signup-flow-cro/scripts/funnel_drop_analyzer.py:200-204 \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":"c-level-advisor/skills/cro-advisor/scripts/churn_analyzer.py"},"region":{"startLine":410}}}],"partialFingerprints":{"codehealthFindingId/v1":"b41458c5c08ee84c279668b4a7ec34f4fa475dea26a269b66c7f67c70f778cf4"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (8 lines \u00D7 2): c-level-advisor/skills/vpe-advisor/scripts/delivery_throughput_analyzer.py:60-67 | c-level-advisor/vpe-advisor/skills/vpe-advisor/scripts/delivery_throughput_analyzer.py:60-67 \u2014 before extracting anything, compare \u0060c-level-advisor/skills/vpe-advisor/scripts/delivery_throughput_analyzer.py\u0060 and \u0060c-level-advisor/vpe-advisor/skills/vpe-advisor/scripts/delivery_throughput_analyzer.py\u0060 as WHOLE FILES: this scan already matched 12 separate duplicated blocks between them, totalling at least 119 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"c-level-advisor/skills/vpe-advisor/scripts/delivery_throughput_analyzer.py"},"region":{"startLine":60}}}],"partialFingerprints":{"codehealthFindingId/v1":"5c4298b73fb91f43899c51fdbd7574053ece4c8e8bf07a1b819e979fd56510f6"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): c-level-advisor/skills/vpe-advisor/scripts/delivery_throughput_analyzer.py:106-110 | c-level-advisor/vpe-advisor/skills/vpe-advisor/scripts/delivery_throughput_analyzer.py:106-110 \u2014 before extracting anything, compare \u0060c-level-advisor/skills/vpe-advisor/scripts/delivery_throughput_analyzer.py\u0060 and \u0060c-level-advisor/vpe-advisor/skills/vpe-advisor/scripts/delivery_throughput_analyzer.py\u0060 as WHOLE FILES: this scan already matched 12 separate duplicated blocks between them, totalling at least 119 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"c-level-advisor/skills/vpe-advisor/scripts/delivery_throughput_analyzer.py"},"region":{"startLine":106}}}],"partialFingerprints":{"codehealthFindingId/v1":"1a4fb10bc26bcb8b21f82258d6626e1ac2d98fd456a5b54f766901e4bc9f59b2"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (29 lines \u00D7 2): c-level-advisor/skills/vpe-advisor/scripts/eng_team_structure_designer.py:89-117 | c-level-advisor/vpe-advisor/skills/vpe-advisor/scripts/eng_team_structure_designer.py:89-117 \u2014 before extracting anything, compare \u0060c-level-advisor/skills/vpe-advisor/scripts/eng_team_structure_designer.py\u0060 and \u0060c-level-advisor/vpe-advisor/skills/vpe-advisor/scripts/eng_team_structure_designer.py\u0060 as WHOLE FILES: this scan already matched 11 separate duplicated blocks between them, totalling at least 223 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"c-level-advisor/skills/vpe-advisor/scripts/eng_team_structure_designer.py"},"region":{"startLine":89}}}],"partialFingerprints":{"codehealthFindingId/v1":"20055177abe7506561d78520512d23cb1096441d13a037db0033d9508aea83dc"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (22 lines \u00D7 2): c-level-advisor/skills/vpe-advisor/scripts/eng_team_structure_designer.py:121-142 | c-level-advisor/vpe-advisor/skills/vpe-advisor/scripts/eng_team_structure_designer.py:121-142 \u2014 before extracting anything, compare \u0060c-level-advisor/skills/vpe-advisor/scripts/eng_team_structure_designer.py\u0060 and \u0060c-level-advisor/vpe-advisor/skills/vpe-advisor/scripts/eng_team_structure_designer.py\u0060 as WHOLE FILES: this scan already matched 11 separate duplicated blocks between them, totalling at least 223 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"c-level-advisor/skills/vpe-advisor/scripts/eng_team_structure_designer.py"},"region":{"startLine":121}}}],"partialFingerprints":{"codehealthFindingId/v1":"2b8c93663a59648d2e8e43ed3506e289677150198f75213beda1655955939638"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (8 lines \u00D7 2): commercial/skills/deal-desk/scripts/deal_scorer.py:284-291 | research-ops/skills/clinical-research/scripts/phase_gate_scorer.py:157-164 \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":"commercial/skills/deal-desk/scripts/deal_scorer.py"},"region":{"startLine":284}}}],"partialFingerprints":{"codehealthFindingId/v1":"b807ba53355ddae46f2f06d4b3de40d8a41599ec51d0321532b4292225a44f19"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (27 lines \u00D7 2): engineering-team/skills/tech-stack-evaluator/scripts/ecosystem_analyzer.py:29-55 | engineering-team/skills/tech-stack-evaluator/scripts/migration_analyzer.py:38-66 \u2014 the copies sit in sibling files of one directory, so a shared home is within easy reach: extract the block into a single shared function the call sites can all reach \u2014 a file they already depend on, or a new one alongside them \u2014 and call it from both call sites, so a change lands once. The \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":"engineering-team/skills/tech-stack-evaluator/scripts/ecosystem_analyzer.py"},"region":{"startLine":29}}}],"partialFingerprints":{"codehealthFindingId/v1":"01573c05bcf336b4538d16d7540452dc619c811f944dc825fcb393f80fb0a302"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (8 lines \u00D7 2): engineering/autoresearch-agent/skills/autoresearch-agent/scripts/log_results.py:26-33 | engineering/autoresearch-agent/skills/autoresearch-agent/scripts/run_experiment.py:24-31 \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":"engineering/autoresearch-agent/skills/autoresearch-agent/scripts/log_results.py"},"region":{"startLine":26}}}],"partialFingerprints":{"codehealthFindingId/v1":"db2a5bbd4d46fbb9f55f4cb853402c44430530954ca9c703b10a367876100f15"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (31 lines \u00D7 2): engineering/chaos-engineering/skills/chaos-engineering/scripts/experiment_designer.py:27-57 | engineering/skills/chaos-engineering/scripts/experiment_designer.py:27-57 \u2014 before extracting anything, compare \u0060engineering/chaos-engineering/skills/chaos-engineering/scripts/experiment_designer.py\u0060 and \u0060engineering/skills/chaos-engineering/scripts/experiment_designer.py\u0060 as WHOLE FILES: this scan already matched 7 separate duplicated blocks between them, totalling at least 111 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The \u0060return\u0060 at the foot of the matched lines is the enclosing body\u0027s own terminal exit, not an early one: it moves with them unchanged, and each site calls the extracted unit from the position that \u0060return\u0060 occupied \u2014 no decision has to be handed back and re-acted on."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/chaos-engineering/skills/chaos-engineering/scripts/experiment_designer.py"},"region":{"startLine":27}}}],"partialFingerprints":{"codehealthFindingId/v1":"75063ae789356e1861fcb08b883fc128c20334587ad496a2cd082c8f45bd5064"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 3): engineering/data-quality-auditor/skills/data-quality-auditor/scripts/data_profiler.py:22-26 | engineering/data-quality-auditor/skills/data-quality-auditor/scripts/missing_value_analyzer.py:22-26 | engineering/data-quality-auditor/skills/data-quality-auditor/scripts/outlier_detector.py:30-34 \u2014 the copies sit in sibling files of one directory, so a shared home is within easy reach: extract the block into a single shared function the call sites can all reach \u2014 a file they already depend on, or a new one alongside them \u2014 and call it from all 3 call sites, so a change lands once. The \u0060return\u0060 at the foot of the matched lines is the enclosing body\u0027s own terminal exit, not an early one: it moves with them unchanged, and each site calls the extracted unit from the position that \u0060return\u0060 occupied \u2014 no decision has to be handed back and re-acted on."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/data-quality-auditor/skills/data-quality-auditor/scripts/data_profiler.py"},"region":{"startLine":22}}}],"partialFingerprints":{"codehealthFindingId/v1":"79524599f9b59aabd1f200786e9e4094e87abee6955e9d7e236f06693aa0b0ea"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): engineering/feature-flags-architect/skills/feature-flags-architect/scripts/flag_debt_scanner.py:72-76 | engineering/skills/feature-flags-architect/scripts/flag_debt_scanner.py:72-76 \u2014 before extracting anything, compare \u0060engineering/feature-flags-architect/skills/feature-flags-architect/scripts/flag_debt_scanner.py\u0060 and \u0060engineering/skills/feature-flags-architect/scripts/flag_debt_scanner.py\u0060 as WHOLE FILES: this scan already matched 7 separate duplicated blocks between them, totalling at least 77 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The \u0060return\u0060 at the foot of the matched lines is the enclosing body\u0027s own terminal exit, not an early one: it moves with them unchanged, and each site calls the extracted unit from the position that \u0060return\u0060 occupied \u2014 no decision has to be handed back and re-acted on."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/feature-flags-architect/skills/feature-flags-architect/scripts/flag_debt_scanner.py"},"region":{"startLine":72}}}],"partialFingerprints":{"codehealthFindingId/v1":"6c8acf6436dcd8b8d3d7af1ddc07934e58c5b3a8f135faf9e65f60d082a48b8a"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 2): engineering/feature-flags-architect/skills/feature-flags-architect/scripts/rollout_planner.py:32-38 | engineering/skills/feature-flags-architect/scripts/rollout_planner.py:32-38 \u2014 before extracting anything, compare \u0060engineering/feature-flags-architect/skills/feature-flags-architect/scripts/rollout_planner.py\u0060 and \u0060engineering/skills/feature-flags-architect/scripts/rollout_planner.py\u0060 as WHOLE FILES: this scan already matched 5 separate duplicated blocks between them, totalling at least 68 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/feature-flags-architect/skills/feature-flags-architect/scripts/rollout_planner.py"},"region":{"startLine":32}}}],"partialFingerprints":{"codehealthFindingId/v1":"620f097f8672956d7e79fbf2878192a6f0c942aefd9c7bb862e98baf527fda42"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 2): engineering/feature-flags-architect/skills/feature-flags-architect/scripts/rollout_planner.py:42-48 | engineering/skills/feature-flags-architect/scripts/rollout_planner.py:42-48 \u2014 before extracting anything, compare \u0060engineering/feature-flags-architect/skills/feature-flags-architect/scripts/rollout_planner.py\u0060 and \u0060engineering/skills/feature-flags-architect/scripts/rollout_planner.py\u0060 as WHOLE FILES: this scan already matched 5 separate duplicated blocks between them, totalling at least 68 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The \u0060return\u0060 at the foot of the matched lines is the enclosing body\u0027s own terminal exit, not an early one: it moves with them unchanged, and each site calls the extracted unit from the position that \u0060return\u0060 occupied \u2014 no decision has to be handed back and re-acted on."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/feature-flags-architect/skills/feature-flags-architect/scripts/rollout_planner.py"},"region":{"startLine":42}}}],"partialFingerprints":{"codehealthFindingId/v1":"9d37636a4c5f41686249fb5617f76208561ffb059ad64be6e7fd2f803c4f825d"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9 lines \u00D7 2): engineering/kubernetes-operator/skills/kubernetes-operator/scripts/crd_validator.py:28-36 | engineering/skills/kubernetes-operator/scripts/crd_validator.py:28-36 \u2014 before extracting anything, compare \u0060engineering/kubernetes-operator/skills/kubernetes-operator/scripts/crd_validator.py\u0060 and \u0060engineering/skills/kubernetes-operator/scripts/crd_validator.py\u0060 as WHOLE FILES: this scan already matched 8 separate duplicated blocks between them, totalling at least 79 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The \u0060return\u0060 at the foot of the matched lines is the enclosing body\u0027s own terminal exit, not an early one: it moves with them unchanged, and each site calls the extracted unit from the position that \u0060return\u0060 occupied \u2014 no decision has to be handed back and re-acted on."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/kubernetes-operator/skills/kubernetes-operator/scripts/crd_validator.py"},"region":{"startLine":28}}}],"partialFingerprints":{"codehealthFindingId/v1":"9237d95607beb6b19aeee9df83920321653a2e0c41db7bd6ae4cb1ada18e261e"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 2): engineering/kubernetes-operator/skills/kubernetes-operator/scripts/crd_validator.py:74-80 | engineering/skills/kubernetes-operator/scripts/crd_validator.py:74-80 \u2014 before extracting anything, compare \u0060engineering/kubernetes-operator/skills/kubernetes-operator/scripts/crd_validator.py\u0060 and \u0060engineering/skills/kubernetes-operator/scripts/crd_validator.py\u0060 as WHOLE FILES: this scan already matched 8 separate duplicated blocks between them, totalling at least 79 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/kubernetes-operator/skills/kubernetes-operator/scripts/crd_validator.py"},"region":{"startLine":74}}}],"partialFingerprints":{"codehealthFindingId/v1":"e45677d462d5728065fb6265182bed5df1c8cd68fddd19be676d2591a264adcc"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 4): engineering/kubernetes-operator/skills/kubernetes-operator/scripts/reconcile_lint.py:29-33 | engineering/skills/kubernetes-operator/scripts/reconcile_lint.py:29-33 | engineering/skills/slo-architect/scripts/slo_review.py:31-35 | engineering/slo-architect/skills/slo-architect/scripts/slo_review.py:31-35 \u2014 before extracting anything, compare \u0060engineering/kubernetes-operator/skills/kubernetes-operator/scripts/reconcile_lint.py\u0060 and \u0060engineering/skills/kubernetes-operator/scripts/reconcile_lint.py\u0060 as WHOLE FILES: this scan already matched 9 separate duplicated blocks between them, totalling at least 127 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/kubernetes-operator/skills/kubernetes-operator/scripts/reconcile_lint.py"},"region":{"startLine":29}}}],"partialFingerprints":{"codehealthFindingId/v1":"b635eccbcd5a247ce7bd92c321572a906ddd3db796b6e40e4df0a6ccfd1f2936"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 2): engineering/kubernetes-operator/skills/kubernetes-operator/scripts/reconcile_lint.py:126-132 | engineering/skills/kubernetes-operator/scripts/reconcile_lint.py:126-132 \u2014 before extracting anything, compare \u0060engineering/kubernetes-operator/skills/kubernetes-operator/scripts/reconcile_lint.py\u0060 and \u0060engineering/skills/kubernetes-operator/scripts/reconcile_lint.py\u0060 as WHOLE FILES: this scan already matched 9 separate duplicated blocks between them, totalling at least 127 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/kubernetes-operator/skills/kubernetes-operator/scripts/reconcile_lint.py"},"region":{"startLine":126}}}],"partialFingerprints":{"codehealthFindingId/v1":"72119eb53d632a60baad912636a6489164ca3dd197cd843719fd68ee3602da05"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2): engineering/kubernetes-operator/skills/kubernetes-operator/scripts/reconcile_lint.py:136-141 | engineering/skills/kubernetes-operator/scripts/reconcile_lint.py:136-141 \u2014 before extracting anything, compare \u0060engineering/kubernetes-operator/skills/kubernetes-operator/scripts/reconcile_lint.py\u0060 and \u0060engineering/skills/kubernetes-operator/scripts/reconcile_lint.py\u0060 as WHOLE FILES: this scan already matched 9 separate duplicated blocks between them, totalling at least 127 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The \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":"engineering/kubernetes-operator/skills/kubernetes-operator/scripts/reconcile_lint.py"},"region":{"startLine":136}}}],"partialFingerprints":{"codehealthFindingId/v1":"9de71cd65792cbb17c7f11cf84cbe6f7b7ffa5cf43ba4b5af4341202dde80003"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): engineering/llm-wiki/skills/llm-wiki/scripts/export_marp.py:74-78 | engineering/llm-wiki/skills/llm-wiki/scripts/init_vault.py:77-81 \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":"engineering/llm-wiki/skills/llm-wiki/scripts/export_marp.py"},"region":{"startLine":74}}}],"partialFingerprints":{"codehealthFindingId/v1":"49ddce697b5b66e3fa385aef6f3bd5c3c9515ec64198ebc5a2259ae1a2694bbd"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2): engineering/skills/codebase-onboarding/scripts/codebase_analyzer.py:66-71 | engineering/skills/env-secrets-manager/scripts/env_auditor.py:53-58 \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":"engineering/skills/codebase-onboarding/scripts/codebase_analyzer.py"},"region":{"startLine":66}}}],"partialFingerprints":{"codehealthFindingId/v1":"b0b40561f38ff623bdf831d62d0da5a49b2dc72b211016741e436e84b8d4b789"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 2): engineering/skills/codebase-onboarding/scripts/codebase_analyzer.py:140-146 | engineering/skills/performance-profiler/scripts/performance_profiler.py:105-111 \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":"engineering/skills/codebase-onboarding/scripts/codebase_analyzer.py"},"region":{"startLine":140}}}],"partialFingerprints":{"codehealthFindingId/v1":"6805122edfa9c7f72a1faa4a2f75d5a2f6fbe339b3728f3f9383ea47b3c93f58"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): engineering/skills/codebase-onboarding/scripts/codebase_analyzer.py:183-187 | engineering/skills/env-secrets-manager/scripts/env_auditor.py:100-104 \u2014 the copies span different directories, so extracting a shared function means choosing where it lives: put it somewhere both call sites can already reach \u2014 a location they all depend on today, or a new shared one if there is none \u2014 and call it from each site; until then, every change has to be made twice. The \u0060return\u0060 at the foot of the matched lines is the enclosing body\u0027s own terminal exit, not an early one: it moves with them unchanged, and each site calls the extracted unit from the position that \u0060return\u0060 occupied \u2014 no decision has to be handed back and re-acted on."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/codebase-onboarding/scripts/codebase_analyzer.py"},"region":{"startLine":183}}}],"partialFingerprints":{"codehealthFindingId/v1":"dd663d67f867fab44d3bdee8ee42c0154062427b1b281cd15b01b060587808a3"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (8 lines \u00D7 3): engineering/skills/observability-designer/scripts/alert_optimizer.py:73-80 | engineering/skills/observability-designer/scripts/dashboard_generator.py:122-129 | engineering/skills/observability-designer/scripts/slo_designer.py:80-87 \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":"engineering/skills/observability-designer/scripts/alert_optimizer.py"},"region":{"startLine":73}}}],"partialFingerprints":{"codehealthFindingId/v1":"173088672deec00297c4b3b575f66040a9cd70d56ae5daf79664b138f085e290"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): engineering/skills/slo-architect/scripts/error_budget_calculator.py:83-87 | engineering/slo-architect/skills/slo-architect/scripts/error_budget_calculator.py:83-87 \u2014 before extracting anything, compare \u0060engineering/skills/slo-architect/scripts/error_budget_calculator.py\u0060 and \u0060engineering/slo-architect/skills/slo-architect/scripts/error_budget_calculator.py\u0060 as WHOLE FILES: this scan already matched 7 separate duplicated blocks between them, totalling at least 89 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/slo-architect/scripts/error_budget_calculator.py"},"region":{"startLine":83}}}],"partialFingerprints":{"codehealthFindingId/v1":"182e088c69cdb55dcfb3e7ae3492c83ed57f9fedb271c55da2758f19d7f6dc8d"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 2): engineering/skills/slo-architect/scripts/slo_review.py:46-52 | engineering/slo-architect/skills/slo-architect/scripts/slo_review.py:46-52 \u2014 before extracting anything, compare \u0060engineering/skills/slo-architect/scripts/slo_review.py\u0060 and \u0060engineering/slo-architect/skills/slo-architect/scripts/slo_review.py\u0060 as WHOLE FILES: this scan already matched 9 separate duplicated blocks between them, totalling at least 103 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/slo-architect/scripts/slo_review.py"},"region":{"startLine":46}}}],"partialFingerprints":{"codehealthFindingId/v1":"9f1a9569384fbf087db80b5d1f91b190d667d9eb25238bcb10f0354c97ed0125"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 2): engineering/skills/slo-architect/scripts/slo_review.py:119-125 | engineering/slo-architect/skills/slo-architect/scripts/slo_review.py:119-125 \u2014 before extracting anything, compare \u0060engineering/skills/slo-architect/scripts/slo_review.py\u0060 and \u0060engineering/slo-architect/skills/slo-architect/scripts/slo_review.py\u0060 as WHOLE FILES: this scan already matched 9 separate duplicated blocks between them, totalling at least 103 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/slo-architect/scripts/slo_review.py"},"region":{"startLine":119}}}],"partialFingerprints":{"codehealthFindingId/v1":"55062fcc041eac9c585b479b7b7d5bb7fdbe582f60f74ad29e96aef259e90ff9"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2): engineering/skills/slo-architect/scripts/slo_review.py:129-134 | engineering/slo-architect/skills/slo-architect/scripts/slo_review.py:129-134 \u2014 before extracting anything, compare \u0060engineering/skills/slo-architect/scripts/slo_review.py\u0060 and \u0060engineering/slo-architect/skills/slo-architect/scripts/slo_review.py\u0060 as WHOLE FILES: this scan already matched 9 separate duplicated blocks between them, totalling at least 103 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The \u0060return\u0060 at the foot of the matched lines is the enclosing body\u0027s own terminal exit, not an early one: it moves with them unchanged, and each site calls the extracted unit from the position that \u0060return\u0060 occupied \u2014 no decision has to be handed back and re-acted on."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/slo-architect/scripts/slo_review.py"},"region":{"startLine":129}}}],"partialFingerprints":{"codehealthFindingId/v1":"bdef11105c6b29b5879c68cca810e9ffd366068031107178e39c54545bf74f0f"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (20 lines \u00D7 2): engineering/skills/tech-debt-tracker/scripts/debt_dashboard.py:281-300 | engineering/skills/tech-debt-tracker/scripts/debt_prioritizer.py:387-406 \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":"engineering/skills/tech-debt-tracker/scripts/debt_dashboard.py"},"region":{"startLine":281}}}],"partialFingerprints":{"codehealthFindingId/v1":"c2e67a8c72ac3e6341c2a1f55a5d4794f7d9c703cc41f57b198cac69da189f59"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9 lines \u00D7 2): engineering/statistical-analyst/skills/statistical-analyst/scripts/hypothesis_tester.py:36-44 | engineering/statistical-analyst/skills/statistical-analyst/scripts/sample_size_calculator.py:35-43 \u2014 the copies sit in sibling files of one directory, so a shared home is within easy reach: extract the block into a single shared function the call sites can all reach \u2014 a file they already depend on, or a new one alongside them \u2014 and call it from both call sites, so a change lands once. 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":"engineering/statistical-analyst/skills/statistical-analyst/scripts/hypothesis_tester.py"},"region":{"startLine":36}}}],"partialFingerprints":{"codehealthFindingId/v1":"0e221477d82af49424dc9922aa8123b00640c47e5bbe1fc8287fdccd87a94a58"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2): engineering/universal-scraping-architect/skills/universal-scraping-architect/scripts/firecrawl_example.py:50-55 | engineering/universal-scraping-architect/skills/universal-scraping-architect/scripts/local_bs4_example.py:63-68 \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":"engineering/universal-scraping-architect/skills/universal-scraping-architect/scripts/firecrawl_example.py"},"region":{"startLine":50}}}],"partialFingerprints":{"codehealthFindingId/v1":"8cf3c66703f465d1293424e714bb7b768ad53aa3bcc35e46bc815b167eeb1966"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (13 lines \u00D7 4): finance/skills/financial-analyst/scripts/budget_variance_analyzer.py:31-43 | finance/skills/financial-analyst/scripts/dcf_valuation.py:34-46 | finance/skills/financial-analyst/scripts/forecast_builder.py:33-45 | finance/skills/financial-analyst/scripts/ratio_calculator.py:30-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 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":"finance/skills/financial-analyst/scripts/budget_variance_analyzer.py"},"region":{"startLine":31}}}],"partialFingerprints":{"codehealthFindingId/v1":"db306d950c867ba6d23053fa3b170e9875dc522b5125469b830c02ad276ff900"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 5): markdown-html/skills/design-system/scripts/config_loader.py:71-76 | research-ops/skills/clinical-research/scripts/config_loader.py:51-56 | research-ops/skills/market-research/scripts/config_loader.py:46-51 | research-ops/skills/product-research/scripts/config_loader.py:46-51 | research-ops/skills/research-finance/scripts/config_loader.py:47-52 \u2014 before extracting anything, compare \u0060markdown-html/skills/design-system/scripts/config_loader.py\u0060 and \u0060research-ops/skills/clinical-research/scripts/config_loader.py\u0060 as WHOLE FILES: this scan already matched 6 separate duplicated blocks between them, totalling at least 60 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"markdown-html/skills/design-system/scripts/config_loader.py"},"region":{"startLine":71}}}],"partialFingerprints":{"codehealthFindingId/v1":"c12855b0342628cca8388427d320a1a543802b6c53db1ab0d0623a324d9ecabe"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (10 lines \u00D7 3): markdown-html/skills/md-document/scripts/html_renderer.py:342-352 | markdown-html/skills/md-review/scripts/review_html_renderer.py:97-106 | markdown-html/skills/md-slides/scripts/deck_html_renderer.py:69-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":"markdown-html/skills/md-document/scripts/html_renderer.py"},"region":{"startLine":342}}}],"partialFingerprints":{"codehealthFindingId/v1":"083fec17924ccfc0d3c29fe0a4dbd7f7000a05ba790ffde4eba5eca1f3433e0f"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2): marketing/linkedin/skills/linkedin-analytics/scripts/pattern_miner.py:89-94 | marketing/linkedin/skills/linkedin-analytics/scripts/post_performance_analyzer.py:75-80 \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":"marketing/linkedin/skills/linkedin-analytics/scripts/pattern_miner.py"},"region":{"startLine":89}}}],"partialFingerprints":{"codehealthFindingId/v1":"ae8f5b23b206c36b5d1a008d7d8e196dddeb46b40350b1906db53919f416c2cc"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (14 lines \u00D7 6): productivity/email/skills/inbox-setup/scripts/section_progress_tracker.py:63-76 | research/dossier/skills/dossier/scripts/citation_tracker.py:69-99 | research/grants/skills/grants/scripts/citation_tracker.py:69-95 | research/litreview/skills/litreview/scripts/citation_tracker.py:73-87 | research/pulse/skills/pulse/scripts/citation_tracker.py:299-314 | research/syllabus/skills/syllabus/scripts/citation_tracker.py:61-82 \u2014 the copies span different directories, so extracting a shared function means choosing where it lives: put it somewhere all 6 call sites can already reach \u2014 a location they all depend on today, or a new shared one if there is none \u2014 and call it from each site; until then, every change has to be made 6 times. 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, \u0060research/grants/skills/grants/scripts/citation_tracker.py:64\u0060 calls \u0060now_ts\u0060, \u0060now\u0060, \u0060timestamp\u0060 and \u0060productivity/email/skills/inbox-setup/scripts/section_progress_tracker.py:59\u0060 does not \u2014 after which the two agree again for 2 more lines. One of those two behaviours is the intended one and the other is what a copy-paste left behind, so decide which BEFORE unifying them: extracting the shared part will silently settle it, and if the copy that skips the call is the wrong one, that bug is already live."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"productivity/email/skills/inbox-setup/scripts/section_progress_tracker.py"},"region":{"startLine":63}}}],"partialFingerprints":{"codehealthFindingId/v1":"3dcbfd8ad1228cc0b343c72915cf12f1eb3d25eee8196559107fd84b0fe62d49"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 7): productivity/email/skills/inbox-setup/scripts/section_progress_tracker.py:134-138 | research/dossier/skills/dossier/scripts/citation_tracker.py:157-161 | research/grants/skills/grants/scripts/citation_tracker.py:168-172 | research/litreview/skills/litreview/scripts/citation_tracker.py:132-136 | research/patent/skills/patent/scripts/citation_tracker.py:153-157 | research/pulse/skills/pulse/scripts/citation_tracker.py:387-391 | research/syllabus/skills/syllabus/scripts/citation_tracker.py:135-139 \u2014 the copies span different directories, so extracting a shared function means choosing where it lives: put it somewhere all 7 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 7 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":"productivity/email/skills/inbox-setup/scripts/section_progress_tracker.py"},"region":{"startLine":134}}}],"partialFingerprints":{"codehealthFindingId/v1":"21cd7e767f62d1c0d232217d1aff71d87d2d65a7b3b66b996b864b237d277d10"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (8 lines \u00D7 2): ra-qm-team/compliance-team-iso42001/skills/iso42001-specialist/scripts/ai_risk_register_builder.py:74-81 | ra-qm-team/skills/iso42001-specialist/scripts/ai_risk_register_builder.py:74-81 \u2014 before extracting anything, compare \u0060ra-qm-team/compliance-team-iso42001/skills/iso42001-specialist/scripts/ai_risk_register_builder.py\u0060 and \u0060ra-qm-team/skills/iso42001-specialist/scripts/ai_risk_register_builder.py\u0060 as WHOLE FILES: this scan already matched 12 separate duplicated blocks between them, totalling at least 132 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"ra-qm-team/compliance-team-iso42001/skills/iso42001-specialist/scripts/ai_risk_register_builder.py"},"region":{"startLine":74}}}],"partialFingerprints":{"codehealthFindingId/v1":"0253a71078c6119fbad8992002ed57fe0b3cb9809c288e2acb74a1e350f23b52"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 2): ra-qm-team/compliance-team-iso42001/skills/iso42001-specialist/scripts/ai_risk_register_builder.py:90-96 | ra-qm-team/skills/iso42001-specialist/scripts/ai_risk_register_builder.py:90-96 \u2014 before extracting anything, compare \u0060ra-qm-team/compliance-team-iso42001/skills/iso42001-specialist/scripts/ai_risk_register_builder.py\u0060 and \u0060ra-qm-team/skills/iso42001-specialist/scripts/ai_risk_register_builder.py\u0060 as WHOLE FILES: this scan already matched 12 separate duplicated blocks between them, totalling at least 132 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"ra-qm-team/compliance-team-iso42001/skills/iso42001-specialist/scripts/ai_risk_register_builder.py"},"region":{"startLine":90}}}],"partialFingerprints":{"codehealthFindingId/v1":"2a6b673a549f340c1f40e67172b0c6060a7dda7f2fcd244949e46a3d5f2f7d90"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): ra-qm-team/compliance-team-iso42001/skills/iso42001-specialist/scripts/ai_risk_register_builder.py:101-105 | ra-qm-team/skills/iso42001-specialist/scripts/ai_risk_register_builder.py:101-105 \u2014 before extracting anything, compare \u0060ra-qm-team/compliance-team-iso42001/skills/iso42001-specialist/scripts/ai_risk_register_builder.py\u0060 and \u0060ra-qm-team/skills/iso42001-specialist/scripts/ai_risk_register_builder.py\u0060 as WHOLE FILES: this scan already matched 12 separate duplicated blocks between them, totalling at least 132 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"ra-qm-team/compliance-team-iso42001/skills/iso42001-specialist/scripts/ai_risk_register_builder.py"},"region":{"startLine":101}}}],"partialFingerprints":{"codehealthFindingId/v1":"70a120a3622c73d9223bb8f3ca3e86641bc5641dddc4b2399970fbb7c7bded77"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 2): ra-qm-team/compliance-team-iso42001/skills/iso42001-specialist/scripts/aims_gap_analyzer.py:127-133 | ra-qm-team/skills/iso42001-specialist/scripts/aims_gap_analyzer.py:127-133 \u2014 before extracting anything, compare \u0060ra-qm-team/compliance-team-iso42001/skills/iso42001-specialist/scripts/aims_gap_analyzer.py\u0060 and \u0060ra-qm-team/skills/iso42001-specialist/scripts/aims_gap_analyzer.py\u0060 as WHOLE FILES: this scan already matched 8 separate duplicated blocks between them, totalling at least 105 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"ra-qm-team/compliance-team-iso42001/skills/iso42001-specialist/scripts/aims_gap_analyzer.py"},"region":{"startLine":127}}}],"partialFingerprints":{"codehealthFindingId/v1":"b5223fcb63a4f097cfc82afb361e0af86e57bf7e9a4d6b5910190f8327db2efc"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (10 lines \u00D7 3): research-ops/skills/market-research/scripts/config_loader.py:65-74 | research-ops/skills/product-research/scripts/config_loader.py:65-74 | research-ops/skills/research-finance/scripts/config_loader.py:66-75 \u2014 before extracting anything, compare \u0060research-ops/skills/market-research/scripts/config_loader.py\u0060 and \u0060research-ops/skills/product-research/scripts/config_loader.py\u0060 as WHOLE FILES: this scan already matched 6 separate duplicated blocks between them, totalling at least 56 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"research-ops/skills/market-research/scripts/config_loader.py"},"region":{"startLine":65}}}],"partialFingerprints":{"codehealthFindingId/v1":"c07e89cbeec18f43ce9fb231e4963bab8749615b597680eb0336662ce935e992"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 3): research-ops/skills/market-research/scripts/config_loader.py:83-87 | research-ops/skills/product-research/scripts/config_loader.py:83-87 | research-ops/skills/research-finance/scripts/config_loader.py:84-88 \u2014 before extracting anything, compare \u0060research-ops/skills/market-research/scripts/config_loader.py\u0060 and \u0060research-ops/skills/product-research/scripts/config_loader.py\u0060 as WHOLE FILES: this scan already matched 6 separate duplicated blocks between them, totalling at least 56 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The \u0060return\u0060 at the foot of the matched lines is the enclosing body\u0027s own terminal exit, not an early one: it moves with them unchanged, and each site calls the extracted unit from the position that \u0060return\u0060 occupied \u2014 no decision has to be handed back and re-acted on."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"research-ops/skills/market-research/scripts/config_loader.py"},"region":{"startLine":83}}}],"partialFingerprints":{"codehealthFindingId/v1":"e5436331c4d78b61c92e51fea13e0ff32920a7c1c4f4f5b31258625eee3085fa"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 3): research-ops/skills/market-research/scripts/onboard.py:42-47 | research-ops/skills/product-research/scripts/onboard.py:51-56 | research-ops/skills/research-finance/scripts/onboard.py:45-50 \u2014 before extracting anything, compare \u0060research-ops/skills/market-research/scripts/onboard.py\u0060 and \u0060research-ops/skills/product-research/scripts/onboard.py\u0060 as WHOLE FILES: this scan already matched 5 separate duplicated blocks between them, totalling at least 60 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"research-ops/skills/market-research/scripts/onboard.py"},"region":{"startLine":42}}}],"partialFingerprints":{"codehealthFindingId/v1":"99dd8d1aa259e6d982d83c44ee04afe03e6cf627256fb374998cb9aef8cd7c85"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): research/dossier/skills/dossier/scripts/citation_tracker.py:114-118 | research/grants/skills/grants/scripts/citation_tracker.py:117-121 \u2014 the copies span different directories, so extracting a shared function means choosing where it lives: put it somewhere both call sites can already reach \u2014 a location they all depend on today, or a new shared one if there is none \u2014 and call it from each site; until then, every change has to be made twice. The \u0060return\u0060 at the foot of the matched lines is the enclosing body\u0027s own terminal exit, not an early one: it moves with them unchanged, and each site calls the extracted unit from the position that \u0060return\u0060 occupied \u2014 no decision has to be handed back and re-acted on."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"research/dossier/skills/dossier/scripts/citation_tracker.py"},"region":{"startLine":114}}}],"partialFingerprints":{"codehealthFindingId/v1":"221148ae0b3b7500c3077ceb1a6ede1d9cc0f6af09cf30247d5eaf18bd1efc0f"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9 lines \u00D7 2): engineering/skills/changelog-generator/scripts/commit_linter.py:81-89 | engineering/skills/changelog-generator/scripts/generate_changelog.py:118-129 \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":"engineering/skills/changelog-generator/scripts/commit_linter.py"},"region":{"startLine":81}}}],"partialFingerprints":{"codehealthFindingId/v1":"c594747bc96e7a2eddbc8e268f079c57fcbaedc8d6e6c3074c6df077a017e195"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): agent-launcher/skills/interview/scripts/primitives_validator.py:55-59 | agent-launcher/skills/interview/scripts/primitives_validator.py:62-66 \u2014 both copies are in the same file, so extract the block 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":"agent-launcher/skills/interview/scripts/primitives_validator.py"},"region":{"startLine":55}}}],"partialFingerprints":{"codehealthFindingId/v1":"339f2f5dbe44cb8a22b0cc61bf6a7ea6dd5b028cfb4f8961f49046fd69575147"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (12 lines \u00D7 2): c-level-advisor/arquiteto-de-empresa/skills/arquiteto-de-empresa/scripts/okf_linter.py:125-136 | c-level-advisor/skills/arquiteto-de-empresa/scripts/okf_linter.py:125-136 \u2014 before extracting anything, compare \u0060c-level-advisor/arquiteto-de-empresa/skills/arquiteto-de-empresa/scripts/okf_linter.py\u0060 and \u0060c-level-advisor/skills/arquiteto-de-empresa/scripts/okf_linter.py\u0060 as WHOLE FILES: this scan already matched 7 separate duplicated blocks between them, totalling at least 147 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The \u0060return\u0060 at the foot of the matched lines is the enclosing body\u0027s own terminal exit, not an early one: it moves with them unchanged, and each site calls the extracted unit from the position that \u0060return\u0060 occupied \u2014 no decision has to be handed back and re-acted on."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"c-level-advisor/arquiteto-de-empresa/skills/arquiteto-de-empresa/scripts/okf_linter.py"},"region":{"startLine":125}}}],"partialFingerprints":{"codehealthFindingId/v1":"192c05152cb27eefd0f58f55cb6f49777f6daffefa6194790f3325795d8e0624"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2): c-level-advisor/skills/cro-advisor/scripts/revenue_forecast_model.py:334-339 | c-level-advisor/skills/cro-advisor/scripts/revenue_forecast_model.py:362-367 \u2014 both copies are in the same file, so extract the block 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":"c-level-advisor/skills/cro-advisor/scripts/revenue_forecast_model.py"},"region":{"startLine":334}}}],"partialFingerprints":{"codehealthFindingId/v1":"d9085b5282989716774290cfcd4ae9177ae4db50faa58d866c0de8b114079b2b"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): commercial/skills/partnerships-architect/scripts/joint_gtm_planner.py:126-130 | commercial/skills/partnerships-architect/scripts/revshare_modeler.py:105-109 \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":"commercial/skills/partnerships-architect/scripts/joint_gtm_planner.py"},"region":{"startLine":126}}}],"partialFingerprints":{"codehealthFindingId/v1":"5731b5ee8fffe96b0af6a87ec5005235bbd660b789da9fe682507931b6ee9305"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 2): commercial/skills/partnerships-architect/scripts/partner_tier_classifier.py:308-314 | commercial/skills/partnerships-architect/scripts/partner_tier_classifier.py:319-325 \u2014 both copies are in the same file, so extract the block 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":"commercial/skills/partnerships-architect/scripts/partner_tier_classifier.py"},"region":{"startLine":308}}}],"partialFingerprints":{"codehealthFindingId/v1":"3a15a079abd077454414c6dd1ba7422cf1b40563f3d4cc00fdc2dfed522a1980"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): engineering-team/skills/incident-commander/scripts/pir_generator.py:1201-1205 | research/notebooklm/skills/notebooklm/scripts/action_router.py:213-217 \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":"engineering-team/skills/incident-commander/scripts/pir_generator.py"},"region":{"startLine":1201}}}],"partialFingerprints":{"codehealthFindingId/v1":"06793b271979d854a38ca81f98093b77d7be7944625d9fdedc3b8217315b267c"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 4): engineering/feature-flags-architect/skills/feature-flags-architect/scripts/flag_debt_scanner.py:27-31 | engineering/feature-flags-architect/skills/feature-flags-architect/scripts/kill_switch_audit.py:27-31 | engineering/skills/feature-flags-architect/scripts/flag_debt_scanner.py:27-31 | engineering/skills/feature-flags-architect/scripts/kill_switch_audit.py:27-31 \u2014 before extracting anything, compare \u0060engineering/feature-flags-architect/skills/feature-flags-architect/scripts/flag_debt_scanner.py\u0060 and \u0060engineering/skills/feature-flags-architect/scripts/flag_debt_scanner.py\u0060 as WHOLE FILES: this scan already matched 7 separate duplicated blocks between them, totalling at least 77 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/feature-flags-architect/skills/feature-flags-architect/scripts/flag_debt_scanner.py"},"region":{"startLine":27}}}],"partialFingerprints":{"codehealthFindingId/v1":"d8d656a5d99a68c99ad0b520546e26aa16fd1114be753f3daf4218ca9163b17f"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): engineering/skills/ship-gate/scripts/ship_gate_scanner.py:1040-1044 | engineering/skills/ship-gate/scripts/ship_gate_scanner.py:1182-1186 \u2014 both copies are in the same file, so extract the block 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":"engineering/skills/ship-gate/scripts/ship_gate_scanner.py"},"region":{"startLine":1040}}}],"partialFingerprints":{"codehealthFindingId/v1":"c1a7a999828b4c8bee7a7f1957cb434419d0f7c12d78e7533383e9327b60651d"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): finance/skills/stock-analysis/scripts/ratios.py:1069-1073 | finance/skills/stock-analysis/scripts/ratios.py:1091-1095 \u2014 both copies are in the same file, so extract the block into one function there and call it from each site \u2014 the copies drift apart the first time only one of them is edited. Read the line range as the matched WINDOW rather than a finished unit: at \u0060finance/skills/stock-analysis/scripts/ratios.py:1069\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":"finance/skills/stock-analysis/scripts/ratios.py"},"region":{"startLine":1069}}}],"partialFingerprints":{"codehealthFindingId/v1":"91eb091d9be999b18dd498bddaa92be7808c2a7c178046ceb2f1fb8e0aa40028"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): finance/skills/stock-analysis/scripts/ratios.py:1127-1131 | finance/skills/stock-analysis/scripts/ratios.py:1169-1173 \u2014 both copies are in the same file, so extract the block 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 \u0060finance/skills/stock-analysis/scripts/ratios.py:1127\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, \u0060finance/skills/stock-analysis/scripts/ratios.py:1167\u0060 calls \u0060add\u0060 and \u0060finance/skills/stock-analysis/scripts/ratios.py:1125\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":"finance/skills/stock-analysis/scripts/ratios.py"},"region":{"startLine":1127}}}],"partialFingerprints":{"codehealthFindingId/v1":"9ec8d678f3582bf38a49f2a17ec849479220b9a9a8826797ecdc26bbe78f54a5"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2): finance/skills/stock-analysis/scripts/score.py:1359-1364 | finance/skills/stock-analysis/scripts/score.py:1508-1513 \u2014 both copies are in the same file, so extract the block 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":"finance/skills/stock-analysis/scripts/score.py"},"region":{"startLine":1359}}}],"partialFingerprints":{"codehealthFindingId/v1":"be2345fd98fd68929d51c7cc9e5275980888319072966dc30c91b8eca81d77a4"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): markdown-html/skills/design-system/scripts/brand_palette_validator.py:41-45 | marketing/landing/skills/landing/scripts/brand_palette_validator.py:37-41 \u2014 before extracting anything, compare \u0060markdown-html/skills/design-system/scripts/brand_palette_validator.py\u0060 and \u0060marketing/landing/skills/landing/scripts/brand_palette_validator.py\u0060 as WHOLE FILES: this scan already matched 12 separate duplicated blocks between them, totalling at least 79 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The \u0060return\u0060 at the foot of the matched lines is the enclosing body\u0027s own terminal exit, not an early one: it moves with them unchanged, and each site calls the extracted unit from the position that \u0060return\u0060 occupied \u2014 no decision has to be handed back and re-acted on."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"markdown-html/skills/design-system/scripts/brand_palette_validator.py"},"region":{"startLine":41}}}],"partialFingerprints":{"codehealthFindingId/v1":"e1c82434d9702b48a640010b5baf9501fda63c3cced85165bb414fa931b15456"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): markdown-html/skills/design-system/scripts/brand_palette_validator.py:81-85 | marketing/landing/skills/landing/scripts/brand_palette_validator.py:80-84 \u2014 before extracting anything, compare \u0060markdown-html/skills/design-system/scripts/brand_palette_validator.py\u0060 and \u0060marketing/landing/skills/landing/scripts/brand_palette_validator.py\u0060 as WHOLE FILES: this scan already matched 12 separate duplicated blocks between them, totalling at least 79 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. The \u0060return\u0060 at the foot of the matched lines is the enclosing body\u0027s own terminal exit, not an early one: it moves with them unchanged, and each site calls the extracted unit from the position that \u0060return\u0060 occupied \u2014 no decision has to be handed back and re-acted on. Note first that the copies are not typed on the same thing: the declarations holding them bind \u0060rgb\u0060 to \u0060tuple[int, int, int]\u0060 in one and \u0060Tuple[int, int, int]\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":"markdown-html/skills/design-system/scripts/brand_palette_validator.py"},"region":{"startLine":81}}}],"partialFingerprints":{"codehealthFindingId/v1":"a05b4401e5990d4fe55e6f48faac63d3a1a14c5e3d3522a85623a48503a0118a"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): marketing-skill/skills/ad-creative/scripts/ad_copy_validator.py:177-181 | marketing-skill/skills/ad-creative/scripts/ad_copy_validator.py:198-202 \u2014 both copies are in the same file, so extract the block into one function there and call it from each site \u2014 the copies drift apart the first time only one of them is edited."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"marketing-skill/skills/ad-creative/scripts/ad_copy_validator.py"},"region":{"startLine":177}}}],"partialFingerprints":{"codehealthFindingId/v1":"0a9da65d4cf05bec469fc840aa4f1fd76b90b7738724a9c402bbde2809db0bd8"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): marketing-skill/skills/campaign-analytics/scripts/campaign_roi_calculator.py:357-361 | marketing-skill/skills/campaign-analytics/scripts/campaign_roi_calculator.py:365-369 \u2014 both copies are in the same file, so extract the block 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":"marketing-skill/skills/campaign-analytics/scripts/campaign_roi_calculator.py"},"region":{"startLine":357}}}],"partialFingerprints":{"codehealthFindingId/v1":"11abb8c4adf63a3bb79cc7a60d43a4b3a3d7799a3cc1345bb0cf36c67ec9bd56"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): marketing-skill/skills/paid-ads/scripts/ad_health_scorer.py:200-204 | marketing-skill/skills/seo-audit/scripts/seo_health_scorer.py:202-206 \u2014 the copies span different directories, so extracting a shared function means choosing where it lives: put it somewhere both call sites can already reach \u2014 a location they all depend on today, or a new shared one if there is none \u2014 and call it from each site; until then, every change has to be made twice."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"marketing-skill/skills/paid-ads/scripts/ad_health_scorer.py"},"region":{"startLine":200}}}],"partialFingerprints":{"codehealthFindingId/v1":"40e2c29589940579356aad3ab3430e064e8be4c72fd0c378e09ff791dfb74124"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): marketing/linkedin/skills/linkedin-engagement/scripts/comment_target_planner.py:212-216 | marketing/linkedin/skills/linkedin-strategy/scripts/cadence_planner.py:210-214 \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":"marketing/linkedin/skills/linkedin-engagement/scripts/comment_target_planner.py"},"region":{"startLine":212}}}],"partialFingerprints":{"codehealthFindingId/v1":"5462c07f46ab5b820bcdaf22aeec5e209de4b89af3d5d6a9c6369e3914715877"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (8 lines \u00D7 3): marketing/linkedin/skills/linkedin-skills/scripts/linkedin_goal_router.py:103-110 | product-team/skills/product-skills/scripts/product_goal_router.py:137-144 | project-management/skills/pm-skills/scripts/pm_goal_router.py:108-115 \u2014 before extracting anything, compare \u0060marketing/linkedin/skills/linkedin-skills/scripts/linkedin_goal_router.py\u0060 and \u0060product-team/skills/product-skills/scripts/product_goal_router.py\u0060 as WHOLE FILES: this scan already matched 8 separate duplicated blocks between them, totalling at least 79 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"marketing/linkedin/skills/linkedin-skills/scripts/linkedin_goal_router.py"},"region":{"startLine":103}}}],"partialFingerprints":{"codehealthFindingId/v1":"179ac5319a66421d1a962737f25b8529f23dbd6c1bdca6237825d39a9070cb14"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2): project-management/skills/scrum-master/scripts/velocity_analyzer.py:464-469 | project-management/skills/scrum-master/scripts/velocity_analyzer.py:473-478 \u2014 both copies are in the same file, so extract the block 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":"project-management/skills/scrum-master/scripts/velocity_analyzer.py"},"region":{"startLine":464}}}],"partialFingerprints":{"codehealthFindingId/v1":"1f3c714d21c5b465f46a7fb0a5caca377eeac563fc0291141983fa7b3465d360"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (51 lines \u00D7 2): engineering/kubernetes-operator/skills/kubernetes-operator/assets/reconcile_skeleton.go:30-80 | engineering/skills/kubernetes-operator/assets/reconcile_skeleton.go:30-80 \u2014 before extracting anything, compare \u0060engineering/kubernetes-operator/skills/kubernetes-operator/assets/reconcile_skeleton.go\u0060 and \u0060engineering/skills/kubernetes-operator/assets/reconcile_skeleton.go\u0060 as WHOLE FILES: this scan already matched 4 separate duplicated blocks between them, totalling at least 81 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. Each matched range is the entire body of the declaration above it, so the region is already a complete unit: move that whole declaration to the shared location and have each site call it, rather than lifting the lines out of their bodies. Any \u0060return\u0060 inside it is the body\u0027s own exit and keeps its meaning in the moved unit."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/kubernetes-operator/skills/kubernetes-operator/assets/reconcile_skeleton.go"},"region":{"startLine":30}}}],"partialFingerprints":{"codehealthFindingId/v1":"69fa0b8f8aeef529930282f342eaecf856cf3a04253d6c67163358a56c8eff0f"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (14 lines \u00D7 2): engineering/kubernetes-operator/skills/kubernetes-operator/assets/reconcile_skeleton.go:85-98 | engineering/skills/kubernetes-operator/assets/reconcile_skeleton.go:85-98 \u2014 before extracting anything, compare \u0060engineering/kubernetes-operator/skills/kubernetes-operator/assets/reconcile_skeleton.go\u0060 and \u0060engineering/skills/kubernetes-operator/assets/reconcile_skeleton.go\u0060 as WHOLE FILES: this scan already matched 4 separate duplicated blocks between them, totalling at least 81 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. Read the line range as the matched WINDOW rather than a finished unit: at \u0060engineering/kubernetes-operator/skills/kubernetes-operator/assets/reconcile_skeleton.go:85\u0060 it runs out through the closing brace of the declaration holding it \u2014 the window is that declaration\u0027s tail, not a fragment that begins part-way through something, so those exact 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":"engineering/kubernetes-operator/skills/kubernetes-operator/assets/reconcile_skeleton.go"},"region":{"startLine":85}}}],"partialFingerprints":{"codehealthFindingId/v1":"7fc334c175082aa2a3c4b383e788fc8f0109ff7ebed2b4c2c07827c9ef237784"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9 lines \u00D7 2): engineering/kubernetes-operator/skills/kubernetes-operator/assets/reconcile_skeleton.go:101-109 | engineering/skills/kubernetes-operator/assets/reconcile_skeleton.go:101-109 \u2014 before extracting anything, compare \u0060engineering/kubernetes-operator/skills/kubernetes-operator/assets/reconcile_skeleton.go\u0060 and \u0060engineering/skills/kubernetes-operator/assets/reconcile_skeleton.go\u0060 as WHOLE FILES: this scan already matched 4 separate duplicated blocks between them, totalling at least 81 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. Each matched range is the entire body of the declaration above it, so the region is already a complete unit: move that whole declaration to the shared location and have each site call it, rather than lifting the lines out of their bodies. Any \u0060return\u0060 inside it is the body\u0027s own exit and keeps its meaning in the moved unit."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/kubernetes-operator/skills/kubernetes-operator/assets/reconcile_skeleton.go"},"region":{"startLine":101}}}],"partialFingerprints":{"codehealthFindingId/v1":"430514d49d14118a82ff42c23ce990c80247f6f53779e33547fd0d86ddfc2627"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 2): engineering/kubernetes-operator/skills/kubernetes-operator/assets/reconcile_skeleton.go:116-122 | engineering/skills/kubernetes-operator/assets/reconcile_skeleton.go:116-122 \u2014 before extracting anything, compare \u0060engineering/kubernetes-operator/skills/kubernetes-operator/assets/reconcile_skeleton.go\u0060 and \u0060engineering/skills/kubernetes-operator/assets/reconcile_skeleton.go\u0060 as WHOLE FILES: this scan already matched 4 separate duplicated blocks between them, totalling at least 81 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/kubernetes-operator/skills/kubernetes-operator/assets/reconcile_skeleton.go"},"region":{"startLine":116}}}],"partialFingerprints":{"codehealthFindingId/v1":"d565e9c7321163b3f8fdb3b912ed729095a0a7a9889247269553afd7efc6c934"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (20\u201322 lines \u00D7 2): marketing-skill/skills/app-store-optimization/scripts/ab_test_planner.py:225-246 | marketing-skill/skills/app-store-optimization/scripts/ab_test_planner.py:282-301 \u2014 both copies are in the same file, so extract the block 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":"marketing-skill/skills/app-store-optimization/scripts/ab_test_planner.py"},"region":{"startLine":225}}}],"partialFingerprints":{"codehealthFindingId/v1":"c5178313b7d6cc3f21ba36e32592690394d2c9ae0779c9cbddd5972b74b21fe9"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (17 lines \u00D7 2): engineering/skills/spec-driven-workflow/scripts/spec_validator.py:143-159 | engineering/skills/spec-driven-workflow/scripts/spec_validator.py:173-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. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/spec-driven-workflow/scripts/spec_validator.py"},"region":{"startLine":143}}}],"partialFingerprints":{"codehealthFindingId/v1":"da73fba18607119bdf7241f984631c215c838d35b9885f2dfe43201db4118ecf"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (11 lines \u00D7 2): engineering/skills/spec-driven-workflow/scripts/spec_validator.py:213-223 | engineering/skills/spec-driven-workflow/scripts/spec_validator.py:267-277 \u2014 both copies are in the same file, so extract the block 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":"engineering/skills/spec-driven-workflow/scripts/spec_validator.py"},"region":{"startLine":213}}}],"partialFingerprints":{"codehealthFindingId/v1":"fa609b31f97c38bf9d6202f520e0ac7f1337f15db35e48a9a651da77078b065c"}},{"ruleId":"D6","level":"warning","message":{"text":"Low cohesion: UserService (LCOM4 5): UserService\u0027s methods fall into 5 groups that share no field and call none of each other, against a bar of more than 3 for this run (LCOM4, configurable \u2014 your repository\u0027s bar is the one quoted here). Each group is a set of methods reachable from one another through shared fields or direct calls, so 5 groups means the type has that many internally-connected clusters with nothing tying them together. Types whose shape makes a high count expected \u2014 and which would otherwise dominate this list \u2014 are excluded before this row is raised, so this is a genuine split candidate rather than a metric reading. It is still a shape, not a defect: confirm the groups match responsibilities you can name before splitting."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/skills/code-reviewer/assets/sample_csharp_clean.cs"},"region":{"startLine":25}}}],"partialFingerprints":{"codehealthFindingId/v1":"074ac88f6a84c0a9ec906648f58e79eb6239413e75b3cc5c4c5707f8291951c7"}},{"ruleId":"D6","level":"warning","message":{"text":"Low cohesion: LaunchChecklistGenerator (LCOM4 5): LaunchChecklistGenerator\u0027s methods fall into 5 groups that share no field and call none of each other, against a bar of more than 3 for this run (LCOM4, configurable \u2014 your repository\u0027s bar is the one quoted here). Each group is a set of methods reachable from one another through shared fields or direct calls, so 5 groups means the type has that many internally-connected clusters with nothing tying them together. Types whose shape makes a high count expected \u2014 and which would otherwise dominate this list \u2014 are excluded before this row is raised, so this is a genuine split candidate rather than a metric reading. It is still a shape, not a defect: confirm the groups match responsibilities you can name before splitting."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"marketing-skill/skills/app-store-optimization/scripts/launch_checklist.py"},"region":{"startLine":10}}}],"partialFingerprints":{"codehealthFindingId/v1":"a391e736bc6c759d8f4f3e199be410110afe62ab2c78441ca2a2f10a500a70ac"}},{"ruleId":"D6","level":"warning","message":{"text":"Low cohesion: LocalizationHelper (LCOM4 4): LocalizationHelper\u0027s methods fall into 4 groups that share no field and call none of each other, against a bar of more than 3 for this run (LCOM4, configurable \u2014 your repository\u0027s bar is the one quoted here). Each group is a set of methods reachable from one another through shared fields or direct calls, so 4 groups means the type has that many internally-connected clusters with nothing tying them together. Types whose shape makes a high count expected \u2014 and which would otherwise dominate this list \u2014 are excluded before this row is raised, so this is a genuine split candidate rather than a metric reading. It is still a shape, not a defect: confirm the groups match responsibilities you can name before splitting."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"marketing-skill/skills/app-store-optimization/scripts/localization_helper.py"},"region":{"startLine":9}}}],"partialFingerprints":{"codehealthFindingId/v1":"1ce9b238c5017c10f6b5ca64eee26c44491714b230697ccedb3b18f87ca79baf"}},{"ruleId":"D6","level":"warning","message":{"text":"Low cohesion: ReviewAnalyzer (LCOM4 4): ReviewAnalyzer\u0027s methods fall into 4 groups that share no field and call none of each other, against a bar of more than 3 for this run (LCOM4, configurable \u2014 your repository\u0027s bar is the one quoted here). Each group is a set of methods reachable from one another through shared fields or direct calls, so 4 groups means the type has that many internally-connected clusters with nothing tying them together. Types whose shape makes a high count expected \u2014 and which would otherwise dominate this list \u2014 are excluded before this row is raised, so this is a genuine split candidate rather than a metric reading. It is still a shape, not a defect: confirm the groups match responsibilities you can name before splitting."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"marketing-skill/skills/app-store-optimization/scripts/review_analyzer.py"},"region":{"startLine":11}}}],"partialFingerprints":{"codehealthFindingId/v1":"d850ff274c8636272e041260db6ec5325cb58c407d220a143dc5e91b4077b17c"}},{"ruleId":"D11","level":"error","message":{"text":"Test suite declares a test script but contains no test files: engineering/skills/dependency-auditor/test-project/: The jest suite in engineering/skills/dependency-auditor/test-project/ was installed and launched successfully, and the runner then found no test files to run \u2014 No tests found, exiting with code 1. The package declares a test script, so it reads as a tested package to anyone who checks its manifest, but there is nothing behind the declaration: no test case exists, so it cannot detect a regression and its presence overstates how much of this repository is tested. The ask is the owner\u0027s: write the first test for this package, or remove the test script from a package that has none. This is not a report that the tests FAIL \u2014 there are none."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"c8bcec616f7f7cef7aad119fb1927e6366eea5d45db23b9b4065a088049f69f8"}},{"ruleId":"D13","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"260a7de7bf895ef8a4be8d8de8fba63c73f9ec5ceaeab64305c8a5db555eb529"},"taxa":[{"id":"CWE-259","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-798","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"A07:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"ruleId":"D13","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"add0214e553dcea201b3d23fc87d1078200c8cd56b3a0f970fd391cb1257e45d"},"taxa":[{"id":"CWE-259","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-798","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"A07:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"ruleId":"D13","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"a8907cb230eb5c4d2645342b4e351b5f43af42d63214dad4238a3e491df2a581"},"taxa":[{"id":"CWE-259","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-798","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"A07:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"ruleId":"D13","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"88e9b9615001181d509010a964818c2803858f4570807eafe4e9bd31ec44eca1"},"taxa":[{"id":"CWE-259","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-798","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"A07:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"ruleId":"D13","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"7630a11445272e73772ba57ccd3bf5641cddc7fb2aa6f5f2975344c8cc0d23cf"},"taxa":[{"id":"CWE-259","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-798","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"A07:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"ruleId":"D13","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"297731131dad4f8b7d61b3d202e2aa3cf679cc1438b61dc9f0021c18219a079d"},"taxa":[{"id":"CWE-259","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-798","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"A07:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"ruleId":"D13","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"1ecc1318e705ce20ec2cebe6daf08d15699df843bb3a0ee7ab6143b317df2031"},"taxa":[{"id":"CWE-259","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-798","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"A07:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"ruleId":"D13","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"7978ed4e2f6a8960d3b433084d5644b2f50391ec251c901e01ac8fd4bb2b23a0"},"taxa":[{"id":"CWE-259","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-798","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"A07:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"ruleId":"D13","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"ce48972cd8397c5dd6f542b049bbbdc16bfb64240cbd650949d14de87c9e8587"},"taxa":[{"id":"CWE-259","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-798","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"A07:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"ruleId":"D13","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"89d2fe5b309fc0074fdd762bfea1012cad9bce8955b3340bdb678e3cb04d3fe9"},"taxa":[{"id":"CWE-259","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-798","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"A07:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"ruleId":"D13","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"cb06cc9000310f9e6de85b03ef642ba00ca2b83c730304285427e2d43985acd3"},"taxa":[{"id":"CWE-259","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-798","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"A07:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"ruleId":"D13","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"0c7daf3d7faf3b394dd18a73970a43b9e1947d190807a91e8ee9f284c092b4ca"},"taxa":[{"id":"CWE-259","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-798","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"A07:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"ruleId":"D13","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"ae3622b61a0454dba7761d3f77cd391bb091815553bef95a43657727a0bb4125"},"taxa":[{"id":"CWE-259","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-798","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"A07:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"ruleId":"D13","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"220938f56aa5d223778339aa2ab6decf71b2280039e03f623abeb474cc213ee7"},"taxa":[{"id":"CWE-259","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-798","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"A07:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"ruleId":"D13","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"896e694da613d80646a4750c936dae2d0ab70ce2a5986529bdce237b667b94e8"},"taxa":[{"id":"CWE-259","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-798","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"A07:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"ruleId":"D13","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"4327740fad364367b67b04db37f778e7edbd39231fd4daff862d8852bfa66056"},"taxa":[{"id":"CWE-259","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-798","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"A07:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"ruleId":"D13","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"e3028a47262a4d80959daa25d952040c2edcc181844edc0d1bdcffd98a6ae517"},"taxa":[{"id":"CWE-259","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-798","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"A07:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"ruleId":"D13","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"6cc53af08c7d788c8928174351ccb6441f530f24cf877f86ee650804ee9c199d"},"taxa":[{"id":"CWE-259","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-798","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"A07:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"ruleId":"D13","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"d9f84dbbf6a78718ef9d55bc41e4275d7445848f5a44467a73fc26461d1e34ee"},"taxa":[{"id":"CWE-259","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-798","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"A07:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"ruleId":"D13","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"92a114ccf16cd15b8e3662a64e8e81c4d71ebfd13dd54db61085929f2e0a8442"},"taxa":[{"id":"CWE-259","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-798","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"A07:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: engineering/agent-memory/skills/agent-memory/scripts/validate_examples.py: engineering/agent-memory/skills/agent-memory/scripts/validate_examples.py changed 16 times in last 90 days, and the most complex body those changes touched has cyclomatic complexity 32 in validate_examples.main at line 195. 1 of those changes was a fix/bug commit, and the other 15 changed it for other reasons \u2014 this file is under both repair and feature pressure. Before the next change lands here, make sure the area it touches is under test, then split that area out of the file so the following change is smaller than this one \u2014 a file this often edited pays the complexity back every time. Counted over 2026-05-28..2026-08-26, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-05-28 15:53:02 \u002B02:00\u0027 --until=\u00272026-08-26 15:53:02 \u002B02:00\u0027 --full-history --no-merges -- engineering/agent-memory/skills/agent-memory/scripts/validate_examples.py\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/agent-memory/skills/agent-memory/scripts/validate_examples.py"},"region":{"startLine":195}}}],"partialFingerprints":{"codehealthFindingId/v1":"6911c12f80902573bb79ee1cf01b0bb67e610f3ca03db29200b59bf2f9f9d294"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: scripts/generate-docs.py: scripts/generate-docs.py changed 4 times in last 90 days, and the most complex body those changes touched has cyclomatic complexity 74 in generate-docs.main at line 458. Frequent change and high complexity in one file compound: schedule 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-28..2026-08-26, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-05-28 15:53:02 \u002B02:00\u0027 --until=\u00272026-08-26 15:53:02 \u002B02:00\u0027 --full-history --no-merges -- scripts/generate-docs.py\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"scripts/generate-docs.py"},"region":{"startLine":458}}}],"partialFingerprints":{"codehealthFindingId/v1":"36931c60cddc1dee1be0e212568188b99fcecfc11f2c987c6a486d5738f04ee4"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: scripts/derive_counters.py: scripts/derive_counters.py changed 13 times in last 90 days, and the most complex body those changes touched has cyclomatic complexity 18 in derive_counters.run_check at line 273. 6 of those changes were fix/bug commits, and the other 7 changed it for other reasons \u2014 this file is under both repair and feature pressure. Before the next change lands here, make sure the area it touches is under test, then split that area out of the file so the following change is smaller than this one \u2014 a file this often edited pays the complexity back every time. Counted over 2026-05-28..2026-08-26, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-05-28 15:53:02 \u002B02:00\u0027 --until=\u00272026-08-26 15:53:02 \u002B02:00\u0027 --full-history --no-merges -- scripts/derive_counters.py\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once 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/derive_counters.py"},"region":{"startLine":273}}}],"partialFingerprints":{"codehealthFindingId/v1":"a8fc7cd216387293d76e5b8018b4ec7882af1e4135e6283793cf870fa9dc0829"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: engineering/skillopt-sleep/skillopt_sleep/cycle.py: engineering/skillopt-sleep/skillopt_sleep/cycle.py changed 4 times in last 90 days, and the most complex body those changes touched has cyclomatic complexity 41 in cycle.run_sleep_cycle at line 93. 4 of those changes were fix/bug commits, so the churn is repair rather than feature work. Before the next change lands here, make sure the area it touches is under test, then split that area out of the file so the following change is smaller than this one \u2014 a file this often edited pays the complexity back every time. Counted over 2026-05-28..2026-08-26, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-05-28 15:53:02 \u002B02:00\u0027 --until=\u00272026-08-26 15:53:02 \u002B02:00\u0027 --full-history --no-merges -- engineering/skillopt-sleep/skillopt_sleep/cycle.py\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skillopt-sleep/skillopt_sleep/cycle.py"},"region":{"startLine":93}}}],"partialFingerprints":{"codehealthFindingId/v1":"ae3347837071a9cefcbef8c757630e6abe013fd069a7102b40b78dfb51690b1f"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: engineering/deep-learning-book/skills/deep-learning-book/scripts/model_arithmetic.py: engineering/deep-learning-book/skills/deep-learning-book/scripts/model_arithmetic.py changed 4 times in last 90 days, and the most complex body those changes touched has cyclomatic complexity 38 in model_arithmetic.step at line 98. 4 of those changes were fix/bug commits, so the churn is repair rather than feature work. Before the next change lands here, make sure the area it touches is under test, then split that area out of the file so the following change is smaller than this one \u2014 a file this often edited pays the complexity back every time. Counted over 2026-05-28..2026-08-26, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-05-28 15:53:02 \u002B02:00\u0027 --until=\u00272026-08-26 15:53:02 \u002B02:00\u0027 --full-history --no-merges -- engineering/deep-learning-book/skills/deep-learning-book/scripts/model_arithmetic.py\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/deep-learning-book/skills/deep-learning-book/scripts/model_arithmetic.py"},"region":{"startLine":98}}}],"partialFingerprints":{"codehealthFindingId/v1":"43ccfb928735f256e328669ae6ef7f9b1560f7cc240dca5d1352dcd4642b01cb"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: engineering/human-gate/skills/human-gate/scripts/human_gate.py: engineering/human-gate/skills/human-gate/scripts/human_gate.py changed 7 times in last 90 days, and the most complex body those changes touched has cyclomatic complexity 15 in human_gate.cmd_close at line 431. 7 of those changes were fix/bug commits, so the churn is repair rather than feature work. Before the next change lands here, make sure the area it touches is under test, then split that area out of the file so the following change is smaller than this one \u2014 a file this often edited pays the complexity back every time. Counted over 2026-05-28..2026-08-26, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-05-28 15:53:02 \u002B02:00\u0027 --until=\u00272026-08-26 15:53:02 \u002B02:00\u0027 --full-history --no-merges -- engineering/human-gate/skills/human-gate/scripts/human_gate.py\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/human-gate/skills/human-gate/scripts/human_gate.py"},"region":{"startLine":431}}}],"partialFingerprints":{"codehealthFindingId/v1":"8652e23fa2b391abea9e96b34b3f0a3fe7c485932c477db76f66b1dc28a54249"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: engineering/book-to-skill/skills/book-to-skill/scripts/skill_plugin_emitter.py: engineering/book-to-skill/skills/book-to-skill/scripts/skill_plugin_emitter.py changed 5 times in last 90 days, and the most complex body those changes touched has cyclomatic complexity 18 in skill_plugin_emitter.emit at line 375. 4 of those changes were fix/bug commits, so the churn is repair rather than feature work. Before the next change lands here, make sure the area it touches is under test, then split that area out of the file so the following change is smaller than this one \u2014 a file this often edited pays the complexity back every time. Counted over 2026-05-28..2026-08-26, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-05-28 15:53:02 \u002B02:00\u0027 --until=\u00272026-08-26 15:53:02 \u002B02:00\u0027 --full-history --no-merges -- engineering/book-to-skill/skills/book-to-skill/scripts/skill_plugin_emitter.py\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/book-to-skill/skills/book-to-skill/scripts/skill_plugin_emitter.py"},"region":{"startLine":375}}}],"partialFingerprints":{"codehealthFindingId/v1":"796907190480f64f1d313ba6ad9fcdbbec9e6c17506b836db82879e3414a2f31"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: engineering/human-gate/skills/human-gate/scripts/review_page_builder.py: engineering/human-gate/skills/human-gate/scripts/review_page_builder.py changed 6 times in last 90 days, and the most complex body those changes touched has cyclomatic complexity 15 in review_page_builder.sanitize_attrs at line 292. 6 of those changes were fix/bug commits, so the churn is repair rather than feature work. Before the next change lands here, make sure the area it touches is under test, then split that area out of the file so the following change is smaller than this one \u2014 a file this often edited pays the complexity back every time. Counted over 2026-05-28..2026-08-26, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-05-28 15:53:02 \u002B02:00\u0027 --until=\u00272026-08-26 15:53:02 \u002B02:00\u0027 --full-history --no-merges -- engineering/human-gate/skills/human-gate/scripts/review_page_builder.py\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/human-gate/skills/human-gate/scripts/review_page_builder.py"},"region":{"startLine":292}}}],"partialFingerprints":{"codehealthFindingId/v1":"ab8f7376fb6c301993c24bc529475877e11cabcaad8037ab1b2883ef1d78cbfd"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: engineering-team/skills/incident-response/scripts/incident_triage.py: engineering-team/skills/incident-response/scripts/incident_triage.py changed 3 times in last 90 days, and the most complex body those changes touched has cyclomatic complexity 22 in incident_triage.main at line 600. Frequent change and high complexity in one file compound: schedule 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-28..2026-08-26, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-05-28 15:53:02 \u002B02:00\u0027 --until=\u00272026-08-26 15:53:02 \u002B02:00\u0027 --full-history --no-merges -- engineering-team/skills/incident-response/scripts/incident_triage.py\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/skills/incident-response/scripts/incident_triage.py"},"region":{"startLine":600}}}],"partialFingerprints":{"codehealthFindingId/v1":"055627f045953134ef2e09b96f818e749a43815c99e7cc15c980654f373f5fa4"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: productivity/deep-work/skills/deep-work/scripts/time_block_planner.py: productivity/deep-work/skills/deep-work/scripts/time_block_planner.py changed 2 times in last 90 days, and the most complex body those changes touched has cyclomatic complexity 28 in time_block_planner.plan at line 86. 2 of those changes were fix/bug commits, so the churn is repair rather than feature work. Before the next change lands here, make sure the area it touches is under test, then split that area out of the file so the following change is smaller than this one \u2014 a file this often edited pays the complexity back every time. Counted over 2026-05-28..2026-08-26, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-05-28 15:53:02 \u002B02:00\u0027 --until=\u00272026-08-26 15:53:02 \u002B02:00\u0027 --full-history --no-merges -- productivity/deep-work/skills/deep-work/scripts/time_block_planner.py\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"productivity/deep-work/skills/deep-work/scripts/time_block_planner.py"},"region":{"startLine":86}}}],"partialFingerprints":{"codehealthFindingId/v1":"386c88e20604d48e049437c9dedc679e7fae0ea87a583ade9c3337ac8ae6bb9e"}},{"ruleId":"D15","level":"warning","message":{"text":"Repeated repair: engineering/skillopt-sleep/skillopt_sleep/staging.py: engineering/skillopt-sleep/skillopt_sleep/staging.py changed 6 times in last 90 days and 6 of those changes were fix/bug commits, so repair is the majority of this file\u0027s churn. Its max cyclomatic complexity is 5 (its worst body is staging.redact_secrets at line 56), UNDER the 15 threshold, so this is deliberately not filed as a churn \u00D7 complexity hotspot \u2014 the difficulty here is in the behaviour the file has to get right, not in its control flow, and refactoring it for complexity would be the wrong move. The repairs counted were: \u201Cfix(engineering): require --yes for schedule \u002B close mkdir/chmod race (round-10)\u201D; \u201Cfix(engineering): relabel misleading redaction placeholder (round-5 review)\u201D; \u201Cfix(engineering): close round-4 review findings on vendored skillopt-sleep\u201D; \u201Cfix(engineering): close round-3 review findings on vendored skillopt-sleep\u201D. Each one is a case this code did not handle. Before the next change lands here, check that every one of them is pinned by a test that fails without its fix; where the same area keeps coming back, the durable fix is usually at the interface that keeps being misused rather than at the line that was last corrected. Counted over 2026-05-28..2026-08-26, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-05-28 15:53:02 \u002B02:00\u0027 --until=\u00272026-08-26 15:53:02 \u002B02:00\u0027 --full-history --no-merges -- engineering/skillopt-sleep/skillopt_sleep/staging.py\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skillopt-sleep/skillopt_sleep/staging.py"},"region":{"startLine":56}}}],"partialFingerprints":{"codehealthFindingId/v1":"9b453ad2a6257eb616dd84f86862b746959308184baa7a8fc7dbd29113cf4e18"}},{"ruleId":"D15","level":"warning","message":{"text":"Repeated repair: productivity/meetings/skills/meetings/scripts/action_item_extractor.py: productivity/meetings/skills/meetings/scripts/action_item_extractor.py changed 5 times in last 90 days and 4 of those changes were fix/bug commits, so repair is the majority of this file\u0027s churn. Its max cyclomatic complexity is 13 (its worst body is action_item_extractor.extract at line 105), UNDER the 15 threshold, so this is deliberately not filed as a churn \u00D7 complexity hotspot \u2014 the difficulty here is in the behaviour the file has to get right, not in its control flow, and refactoring it for complexity would be the wrong move. The repairs counted were: \u201Cfix(meetings): stop crediting capitalized non-names in \u0027Name will ...\u0027 prose\u201D; \u201Cfix(meetings): only a leading @mention confers action-item ownership\u201D; \u201Cfix(deep-work): enforce the 10-min buffer before the end-of-day shallow batch\u201D; \u201Cfix(meetings): action_item_extractor no longer reassigns owner to a mid-text @mention\u201D. Each one is a case this code did not handle. Before the next change lands here, check that every one of them is pinned by a test that fails without its fix; where the same area keeps coming back, the durable fix is usually at the interface that keeps being misused rather than at the line that was last corrected. Counted over 2026-05-28..2026-08-26, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-05-28 15:53:02 \u002B02:00\u0027 --until=\u00272026-08-26 15:53:02 \u002B02:00\u0027 --full-history --no-merges -- productivity/meetings/skills/meetings/scripts/action_item_extractor.py\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"productivity/meetings/skills/meetings/scripts/action_item_extractor.py"},"region":{"startLine":105}}}],"partialFingerprints":{"codehealthFindingId/v1":"af97dc8c9644af736256615a24787c9a95dee053363c5e575f43a0e9302fe020"}},{"ruleId":"D15","level":"warning","message":{"text":"Repeated repair: engineering/skillopt-sleep/skillopt_sleep/scheduler.py: engineering/skillopt-sleep/skillopt_sleep/scheduler.py changed 4 times in last 90 days and 4 of those changes were fix/bug commits, so repair is the majority of this file\u0027s churn. Its max cyclomatic complexity is 8 (its worst body is scheduler.unschedule at line 154), UNDER the 15 threshold, so this is deliberately not filed as a churn \u00D7 complexity hotspot \u2014 the difficulty here is in the behaviour the file has to get right, not in its control flow, and refactoring it for complexity would be the wrong move. The repairs counted were: \u201Cfix(engineering): anchor scheduler.py\u0027s project marker match (round-9 bug)\u201D; \u201Cfix(engineering): close CLI-output redaction gap (round-8 HIGH finding)\u201D; \u201Cfix(engineering): address round-2 review findings on vendored skillopt-sleep\u201D; \u201Cfix(engineering): close 3 safety gaps found by PR review in vendored skillopt-sleep\u201D. Each one is a case this code did not handle. Before the next change lands here, check that every one of them is pinned by a test that fails without its fix; where the same area keeps coming back, the durable fix is usually at the interface that keeps being misused rather than at the line that was last corrected. Counted over 2026-05-28..2026-08-26, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-05-28 15:53:02 \u002B02:00\u0027 --until=\u00272026-08-26 15:53:02 \u002B02:00\u0027 --full-history --no-merges -- engineering/skillopt-sleep/skillopt_sleep/scheduler.py\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skillopt-sleep/skillopt_sleep/scheduler.py"},"region":{"startLine":154}}}],"partialFingerprints":{"codehealthFindingId/v1":"4856537bdc4b8d16f35670af16f5270115e96922bdd89d6de60f70cbba2d7e72"}},{"ruleId":"D15","level":"warning","message":{"text":"Repeated repair: engineering/book-to-skill/skills/book-to-skill/scripts/extract_document.py: engineering/book-to-skill/skills/book-to-skill/scripts/extract_document.py changed 3 times in last 90 days and 3 of those changes were fix/bug commits, so repair is the majority of this file\u0027s churn. Its max cyclomatic complexity is 9 (its worst body is extract_document.resolve_workdir at line 99), UNDER the 15 threshold, so this is deliberately not filed as a churn \u00D7 complexity hotspot \u2014 the difficulty here is in the behaviour the file has to get right, not in its control flow, and refactoring it for complexity would be the wrong move. The repairs counted were: \u201Cfix(book-to-skill): close the workdir race with fd pinning\u201D; \u201Cfix(book-to-skill): skill-quality audit \u2014 runnable docs, honest gates\u201D; \u201Cfix(book-to-skill): private per-invocation workdir; share budget constants\u201D. Each one is a case this code did not handle. Before the next change lands here, check that every one of them is pinned by a test that fails without its fix; where the same area keeps coming back, the durable fix is usually at the interface that keeps being misused rather than at the line that was last corrected. Counted over 2026-05-28..2026-08-26, the 90 days ending at the analysed commit. Reproduce with \u0060git log --since=\u00272026-05-28 15:53:02 \u002B02:00\u0027 --until=\u00272026-08-26 15:53:02 \u002B02:00\u0027 --full-history --no-merges -- engineering/book-to-skill/skills/book-to-skill/scripts/extract_document.py\u0060: merges are excluded because a merge re-states changes already counted at their own commits, and history is NOT path-simplified because a change that reached the file through a merged branch is still a change to it. That command counts raw commits and can read HIGHER than this row, which counts a cherry-picked re-land, and a revert together with the commit it undoes, once each \u2014 a difference of several commits on a file whose history was re-landed or reverted inside the window."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/book-to-skill/skills/book-to-skill/scripts/extract_document.py"},"region":{"startLine":99}}}],"partialFingerprints":{"codehealthFindingId/v1":"29dc63b7b07cc800e58d80db64ff5b17c9d892cec478db0413855e8a66f576fd"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: Implement {task.operator} for {task.task_id} \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/skills/senior-data-engineer/scripts/pipeline_orchestrator.py"},"region":{"startLine":303}}}],"partialFingerprints":{"codehealthFindingId/v1":"54060a64d3d7668dd09683e0018e923af35b602df57e6c62554fb3b6e06e9158"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: Set up test data and dependencies \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/skills/tdd-guide/scripts/test_generator.py"},"region":{"startLine":222}}}],"partialFingerprints":{"codehealthFindingId/v1":"8eadd4db2b1ce780486b87bcd02343bfa8b201f9ecf4fd01d3c13a44c11459e4"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: Execute the code under test \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/skills/tdd-guide/scripts/test_generator.py"},"region":{"startLine":225}}}],"partialFingerprints":{"codehealthFindingId/v1":"f4d7a926d061609176cdb89faeb66efc990189fb79e0a1a1d0e59cada55bb2ee"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: Verify expected behavior \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/skills/tdd-guide/scripts/test_generator.py"},"region":{"startLine":228}}}],"partialFingerprints":{"codehealthFindingId/v1":"e4a2de5033b05d5191085ac348b4863c05e730cb10b2a0c0c1d7b2fe6b194776"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: Implement test \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/skills/tdd-guide/scripts/test_generator.py"},"region":{"startLine":293}}}],"partialFingerprints":{"codehealthFindingId/v1":"847a94a50afa550a5556d9646df5db5bad6fd0b94a0b5037d18782240ad85db3"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: Move this to configuration file \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/tech-debt-tracker/assets/sample_codebase/src/user_service.py"},"region":{"startLine":12}}}],"partialFingerprints":{"codehealthFindingId/v1":"b35541f9c3abf48a9527042cefd7e4b2910dc61b967b8b3fd73ddba86b816988"}},{"ruleId":"D17","level":"warning","message":{"text":"FixmeComment: # FIXME: This should be in environment variables \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/tech-debt-tracker/assets/sample_codebase/src/user_service.py"},"region":{"startLine":14}}}],"partialFingerprints":{"codehealthFindingId/v1":"b937eecd03121033da58091d8974d235ff920376ed4401e3290022ac0b402a5f"}},{"ruleId":"D17","level":"warning","message":{"text":"HackComment: # HACK: Using dict for now, should be proper database connection \u2014 a workaround marked in source: record what it is compensating for and what would allow its removal (the upstream fix, the API it is waiting on, the invariant it restores), so the next reader can judge whether it is still needed rather than rediscovering why it is there."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/tech-debt-tracker/assets/sample_codebase/src/user_service.py"},"region":{"startLine":21}}}],"partialFingerprints":{"codehealthFindingId/v1":"005e80136871f8a837b0aef52271933924ae9d1ea3373676df1dc195d6fd3f31"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: Implement proper user ID generation \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/tech-debt-tracker/assets/sample_codebase/src/user_service.py"},"region":{"startLine":88}}}],"partialFingerprints":{"codehealthFindingId/v1":"5630528420b0fcdd0642023863bed5e009320176182676802cee182110e18912"}},{"ruleId":"D17","level":"warning","message":{"text":"XxxComment: # XXX: This is terrible for production \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/tech-debt-tracker/assets/sample_codebase/src/user_service.py"},"region":{"startLine":89}}}],"partialFingerprints":{"codehealthFindingId/v1":"be7e40d991b30fcfbd174bf95a6b3b2901922e408d41311e69b05fe68037ed9c"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: Implement soft delete instead \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/tech-debt-tracker/assets/sample_codebase/src/user_service.py"},"region":{"startLine":196}}}],"partialFingerprints":{"codehealthFindingId/v1":"1b27f752126d0b75fb7a55014f84ea76f356604d0a1a92520862e96aa5a3d243"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: These should come from environment or config \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/tech-debt-tracker/assets/sample_codebase/src/payment_processor.py"},"region":{"startLine":21}}}],"partialFingerprints":{"codehealthFindingId/v1":"7b0d1fe06f1fe40a7c352cb4b6dff2fda196c015de110303bd5eeb71d39599f7"}},{"ruleId":"D17","level":"warning","message":{"text":"FixmeComment: # FIXME: This should query a discount service \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/tech-debt-tracker/assets/sample_codebase/src/payment_processor.py"},"region":{"startLine":74}}}],"partialFingerprints":{"codehealthFindingId/v1":"a4cfd8c2cc70c211c69bb3e130f287f799eb847fe2413834d3cdec3f60310524"}},{"ruleId":"D17","level":"warning","message":{"text":"HackComment: # HACK: Using print instead of actual email service \u2014 a workaround marked in source: record what it is compensating for and what would allow its removal (the upstream fix, the API it is waiting on, the invariant it restores), so the next reader can judge whether it is still needed rather than rediscovering why it is there."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/tech-debt-tracker/assets/sample_codebase/src/payment_processor.py"},"region":{"startLine":226}}}],"partialFingerprints":{"codehealthFindingId/v1":"225d001043b6f530067c2e5d04a603ed19c2b7967ff253201b30d43b12936701"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: Implement actual email sending \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/tech-debt-tracker/assets/sample_codebase/src/payment_processor.py"},"region":{"startLine":231}}}],"partialFingerprints":{"codehealthFindingId/v1":"3b7c375611d62a65fd2c4d3760f4ecf283b730ee6edbad29fba6d1f5e2ddeb91"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: Implement refund for different providers \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/tech-debt-tracker/assets/sample_codebase/src/payment_processor.py"},"region":{"startLine":236}}}],"partialFingerprints":{"codehealthFindingId/v1":"ae29d58b521047208f07e9d546be23928df2b83cca784797b9b2b2dea0300955"}},{"ruleId":"D17","level":"warning","message":{"text":"XxxComment: # XXX: This doesn\u0027t actually process the refund \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/tech-debt-tracker/assets/sample_codebase/src/payment_processor.py"},"region":{"startLine":243}}}],"partialFingerprints":{"codehealthFindingId/v1":"653aff9f461ed6b1fb077abfaaeb24281b9cf6683d2d4c9f6ce8f0ae448e7241"}},{"ruleId":"D17","level":"warning","message":{"text":"FixmeComment: # FIXME: Implement actual transaction lookup \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/tech-debt-tracker/assets/sample_codebase/src/payment_processor.py"},"region":{"startLine":248}}}],"partialFingerprints":{"codehealthFindingId/v1":"5a0b1a5ef494f153948f4add7bfc68f16a34b26201cf26d9399014d11732f16c"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: # TODO: accept channel data via --file \u003Cjson\u003E or stdin so the tool can be \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060# REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"marketing-skill/skills/marketing-demand-acquisition/scripts/calculate_cac.py"},"region":{"startLine":77}}}],"partialFingerprints":{"codehealthFindingId/v1":"cce8797a5b40806fd9a06fc83463d1d916ffd1114b799d79e57b3639d63ae917"}},{"ruleId":"D20","level":"warning","message":{"text":"No context/problem and no consequences/trade-offs sections for living documentation (updates in same PR, remove outdated info), despite informative title: Add a Context section explaining why living docs are needed (code changes outpace documentation) and a Consequences section on risks like stale links or inconsistent examples"},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"standards/documentation/documentation-standards.md"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"f64167396e991699da219af5b06e2a4ec4600c58e48d1a18f6cc032caed72f96"}},{"ruleId":"D28","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"30235c99f3b87c5c541db00c0ae8fa9f90e3fc6f45e87f449002377811925bd8"},"properties":{"commitSha":"87fb428eadfd1186ea34713fa522b62374c09728"}},{"ruleId":"D28","level":"note","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"3cdfd7beb31b791ae18dcb425e21eb157c842e7bbcd522cc330573c1a6538db1"}},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"3d7c4cf26a265375268c0a5f4f1fd4564adc65ce5efa21c595ad52c56d232f74"},"taxa":[{"id":"CWE-78","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"A05:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"cd4f979950b20129c6a02ad2d5c9a698d05f5f41153f85a7f4d327c913f8d9b7"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"A03:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"4b4c9523e63ee4e8ac84124f8ca8c0f97ae7447fcc03c3a31a4e46e02e789b1e"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"A03:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"3b278a52b33abac8221dab2d3900be40136f5f9d85e6cd1f5bb0833348155e57"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-829","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"A03:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"148ee17e0cf2865de738aaef01f9aaa1fddf494704b7ef02f49a5bfee3da00ed"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"A03:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"6519d157bf2bccbc1df44dd6e60f1782f94b29cde10d6a6028d6a49fa5d5435c"},"taxa":[{"id":"CWE-78","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"A05:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"b7600e54d983e3ac007f73bbb115db730799faa65e1a92e4933fff8f89d75142"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"A03:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"61882cbe17a694c2e461787e99cfb9483432db7ddc279eb4a6c065b62b30c21c"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"A03:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"10c56a38858357ca9e1678c77c6b09a50a04b3f7d5c5aa9d458ffd15a74a7c6a"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"A03:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"f59b8a83fe4db5d95cdda29eb7db13adea9f8b2f574e5eddb03417851bb3c67e"},"taxa":[{"id":"CWE-522","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-829","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"A06:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}},{"id":"CICD-SEC-6","toolComponent":{"name":"OWASP Top 10 CI/CD Security Risks","guid":"3c9b2a6e-5d14-4f7b-8e02-6a1d9c4b7f35"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"608798eb5b7e28a28184b2d443368e4743437b2e32e5b85f823900f3d22b464d"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"A03:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"49e9df15abb5f92add0830591936c7eef68c563b22208cadcbe80ba32728ab96"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"A03:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"d2bbf4db0c0e09606afc98b04e17df3bfe887cdfdd807d54822b0c9b8316e441"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"A03:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"0957cc7f47d1931c56662464cd3ce406765637560a7f96e94ab37853c0558962"},"taxa":[{"id":"CWE-522","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-829","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"A06:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}},{"id":"CICD-SEC-6","toolComponent":{"name":"OWASP Top 10 CI/CD Security Risks","guid":"3c9b2a6e-5d14-4f7b-8e02-6a1d9c4b7f35"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"682a8f777efe777d35a447fb6089cbedc8821d7724c9dc3ea5c1608018bdc1ae"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"A03:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"219ae5b4f256c2ee81a57d3bcc68cdf8ba32b02f59a31541d96a4e90a390bb8f"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"A03:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"33a76c57e5660f32643a9bee5b8e5e593216e38fa747abbe50666e90aa7c8801"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"A03:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"c9870655b445a34e889d4d9f69b634be3a75c0bc358e007d923d1213deb1bc02"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"A03:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"7d0f08b1531a6b0bf3ac476003f5e8899532cac82f3783d4a08b775098b6a7ea"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"A03:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"a86995f004a8a9e66beba73fe44216b2c068efca7650662fa46cbbb184119a74"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"A03:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"31e15292ee7781495cff3025f3779e23aded0d07be93120b45c65e1d6518c389"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"A03:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"101907159e3bb7d8afe7fa3e34f7c2a5a9da4668d93ae9cd3e6f1dd4ae43516b"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"A03:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"f1b966c70d2e5f6ab697ac6d268d54938c60e802d8ea58ea6ff9cb7e10a35f70"},"taxa":[{"id":"CWE-78","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"A05:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"866c5c4a184e4a0cbac5b9eb7198041e39a2fa9cbcdb98836fb742adfc864a54"},"taxa":[{"id":"CWE-78","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"A05:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"70d91096fb11e71208b406fa2c0e5a6ec1d352491d9c896955900531130326de"},"taxa":[{"id":"CWE-78","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"A05:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"498064ebdb85199f1022db9c525f4a3de844ad4f5c0a527227b53433b7ed98a3"},"taxa":[{"id":"CWE-78","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"A05:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"3c22e78931771d91c1c9387d01789eb02b29325e662e6d1dce97f23f214c8fef"},"taxa":[{"id":"CWE-78","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"A05:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"1d0e31f8792891767b44f33e2801f625c3409708cfef6fddc0427f50a08099de"},"taxa":[{"id":"CWE-78","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"A05:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"a5d79726ec815a0a21fcabe3790ebcd11618c3929ed9aadfd81637ea344e06ff"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"A03:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"146fae2b852deee08dc401dbe6a1e24dc0c01ad266fb26c5cacacf0f3ff9c6c6"},"taxa":[{"id":"CWE-78","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"A05:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"9fd7e97dc9c5c0238d316cfa471ec1dced23d8c13327adc2e460055eb07bdc43"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"A03:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"6ea138e313e82e7b8c063630f0e621b2c93faf2669dce15dc63f6bd9777f4ef4"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"A03:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"a1db3aa681409bdd89fe17c97c826c83ffc4451ade100c4196ed87f0c610689c"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"A03:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"3c07fff404bb7dd97f109c4e8909fba1742923410a261f4f8a1f80fcab7115e0"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-829","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"A03:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"5f1e19693e3dc07267cd492d3a9abd583d356ff8b5f0ed7c5ee77fdcadd2162d"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"A03:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"9f6bbe269b4fe9a82bc313a684d76c4c066ffea6ef17017cab4bec974f1566a6"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"A03:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"eba19963dd6add935e909cfd53e20a9eca14ac52cd294813a73ed28dbe3256e6"},"taxa":[{"id":"CWE-78","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"A05:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"287d12de971e61701990f83b71540d68831840d38e3c8a3ad70000b0e375e4d6"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"A03:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"ace48e947b9c57df3dac53719982c518af164f1106ef9f4b966bc5815a867309"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"A03:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"894fd7dce4b2c92348eacf5890a84f55a35243a73e155a241caa49808edfb093"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"A03:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"a03cee6c1edc64185680b5d75f76b65640ba0a100ff63b468db1431360f0165e"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"A03:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"3d6c4e3a43c708612ce60e1223c25211001cf1dabb80967c932e7a89c9fd75af"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"A03:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"689996d31f68990248fc34f43b77fdd6aec09fd98887df2d193cfa4c48135c89"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"A03:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"f0a347888d4121995e99b0b1a2aa49a14529935c70e160ec057f3e7720af3fb4"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"A03:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"6553a8633524df5c4e1c518feb6ad18acddb05f1429d73d3c72a125b42dccbcf"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"A03:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"31b61cce527de6002676a2b7dfbfc1ab32f074d6b535cc17f62b19d976507af7"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-829","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"A03:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"74c1fe352726c02937ad0f2252961cd3ce92ee4e1fc91b9d19b143c38a580de2"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"A03:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"dea0758c01ac0c1ee9b88e09a2b2a31b175e5c0537a80e69b980ff7d77c3870a"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"A03:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"413c28dd6d50586936bd2fd2cb0f237f504721ba96f3206c9ba5106cffde1313"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"A03:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"0c5a29847a94499c9caac3df17c014087bb0eeec736bb29bdd557f81a3c599c9"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"A03:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"208d5a807da7ddf3891b5dcf020acc7206c7e2f0248fba32a416261ce0a0c84c"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"A03:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"2d4f8673ca502ed3aad5c98252689997eda29b585cd1e84b78603cc17078359e"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"A03:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"f5bd263b3230d757efe07b92e2c87d2f43279613be1933695a2787453fbafc35"},"taxa":[{"id":"CWE-522","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-829","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"A06:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}},{"id":"CICD-SEC-6","toolComponent":{"name":"OWASP Top 10 CI/CD Security Risks","guid":"3c9b2a6e-5d14-4f7b-8e02-6a1d9c4b7f35"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"bcf7a7f509e292f988d03501912f9162560c69c32a6e8b001e42eb1844c4d25d"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"A03:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"0795a99a048827a19e8bd1904356837ec65624059412eb41fc7a37ff6110d609"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"A03:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"172361d1d417e13b12e45bbb049d94185fb16b6fc94ff44df41e8622dd41d6c5"},"taxa":[{"id":"CWE-522","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-829","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"A06:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}},{"id":"CICD-SEC-6","toolComponent":{"name":"OWASP Top 10 CI/CD Security Risks","guid":"3c9b2a6e-5d14-4f7b-8e02-6a1d9c4b7f35"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"9262dbbd651bebdb5a4fe067e56b7e21abde0254c35089d84cba7bdc857d1ea7"},"taxa":[{"id":"CWE-522","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-829","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"A06:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}},{"id":"CICD-SEC-6","toolComponent":{"name":"OWASP Top 10 CI/CD Security Risks","guid":"3c9b2a6e-5d14-4f7b-8e02-6a1d9c4b7f35"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"67ecb3b27b4ecb267b45f691780bb39d781d1c737297a9ecbb242a3203e8afb4"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"A03:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"256dcc0bea31b5b9f122456272a12e13646b66110b63736aa4dd80213b8fc33f"},"taxa":[{"id":"CWE-676","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"A06:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"c94a489592b9a251c16429119a2922a8917735c498f51406fc32b7b85bf0f8b1"},"taxa":[{"id":"CWE-676","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"A06:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"572034f9fb3746316308a7bbe386ec04b9848b24c423774bb6a717dceb9fc26e"},"taxa":[{"id":"CWE-676","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"A06:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"04ec992daf31098777b96d92ff18bb4e9fb9c0c6e4611a341fcb8cef72fa6145"},"taxa":[{"id":"CWE-676","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"A06:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"50cc3906621487b866142a8f205174e0e9854efc40d22a5191ace8f7de35d721"},"taxa":[{"id":"CWE-676","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"A06:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"b0a10e5a720bea775bf7ef83c19367dea4b1318c9043524658444f7ad9fc22cf"},"taxa":[{"id":"CWE-676","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"A06:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"ruleId":"D29","level":"warning","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"68c0d4ec25c93b4343aa60801355676080f365f1953e0dd7db645d5d677642b4"},"taxa":[{"id":"CWE-1104","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-1352","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"A03:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}},{"id":"CICD-SEC-7","toolComponent":{"name":"OWASP Top 10 CI/CD Security Risks","guid":"3c9b2a6e-5d14-4f7b-8e02-6a1d9c4b7f35"}}]},{"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":"0bd09466570594210574e6b12bf6f82557e21589173450022a4ffd2e5f8c4ae7"},"taxa":[{"id":"CWE-1104","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-1352","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"A03:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}},{"id":"CICD-SEC-7","toolComponent":{"name":"OWASP Top 10 CI/CD Security Risks","guid":"3c9b2a6e-5d14-4f7b-8e02-6a1d9c4b7f35"}}]},{"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":"7ff11eda70483a15c976da034c3aac33c81ad8832cd0e249ecfdab1a226023c4"},"taxa":[{"id":"CWE-276","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"A01:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"ruleId":"D29","level":"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":"f2c6805f67d4e85d77e4b665e38fc52bde110284d9504cc444802d6fb476893b"},"taxa":[{"id":"CWE-276","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"A01:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"ruleId":"D29","level":"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":"0bcf75060a4b834ae6d6a9d38ac299fe4a7f007892a22a441a5333184c3c8f30"},"taxa":[{"id":"CWE-276","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"A01:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"ruleId":"D29","level":"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":"9fa2be4ed3eeec1c5d143e82fc968c88b72c0ed9b3163b189fe1e0734a1ba664"},"taxa":[{"id":"CWE-327","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"A04:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"ruleId":"D29","level":"warning","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"73bf6b2aa720f071a147891b018358db27452952a5f7a2f4ed30a518fb04b46b"},"taxa":[{"id":"CWE-327","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"A04:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"ruleId":"D29","level":"warning","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"d6a13a97a5a725571f158800da518740681a9b66bb7407b90cde4613ff549a0d"},"taxa":[{"id":"CWE-327","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"A04:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"ruleId":"D29","level":"note","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"15b6aebed769823f225f328fd59fad9331586e49c3f7da19b7d07cb0a9ebce37"},"taxa":[{"id":"CWE-79","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"A05:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"ruleId":"D29","level":"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":"e20362db1cfd3bb9c5d2788df8e63f98babb32d222c6b641cdf1a312dda08b6b"},"taxa":[{"id":"CWE-78","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"A05:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"ruleId":"D29","level":"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":"cbb8bef38e21e4ca483b3bc79a0f0f2b64e7223fd247888cfd96bcd0ed278948"},"taxa":[{"id":"CWE-78","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"A05:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"ruleId":"D29","level":"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":"cb331e3ed4b48a88d7de37683d1c86cfe336e60a878335c50259c54e8b3f2e64"},"taxa":[{"id":"CWE-78","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"A05:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"ruleId":"D30","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"e258f96b4c74149eb13fc562b9982577f09891451a2c178e6f19d64782d99dc4"},"properties":{"dependency":{"package":"pillow","version":"9.5.0","advisory":"[GHSA redacted]","aliases":["A-299477569","ASB-A-299477569","BIT-pillow-2023-44271","BIT-pillow-2023-50447","BIT-pillow-2024-28219","BIT-pillow-2026-42308","BIT-pillow-2026-42310","BIT-pillow-2026-54058","BIT-pillow-2026-54059","BIT-pillow-2026-54060","BIT-pillow-2026-55379","BIT-pillow-2026-55380","BIT-pillow-2026-55798","BIT-pillow-2026-59197","BIT-pillow-2026-59198","BIT-pillow-2026-59199","BIT-pillow-2026-59200","BIT-pillow-2026-59204","BIT-pillow-2026-59205","[CVE redacted]","[CVE redacted]","[CVE redacted]","[CVE redacted]","[CVE redacted]","[CVE redacted]","[CVE redacted]","[CVE redacted]","[CVE redacted]","[CVE redacted]","[CVE redacted]","[CVE redacted]","[CVE redacted]","[CVE redacted]","[CVE redacted]","[CVE redacted]","[CVE redacted]","[CVE redacted]","[CVE redacted]","[GHSA redacted]","[GHSA redacted]","[GHSA redacted]","[GHSA redacted]","[GHSA redacted]","[GHSA redacted]","[GHSA redacted]","[GHSA redacted]","[GHSA redacted]","[GHSA redacted]","[GHSA redacted]","[GHSA redacted]","[GHSA redacted]","[GHSA redacted]","[GHSA redacted]","[GHSA redacted]","[GHSA redacted]","PYSEC-2023-175","PYSEC-2023-227","PYSEC-2026-165","PYSEC-2026-1793","PYSEC-2026-1794","PYSEC-2026-2253","PYSEC-2026-2254","PYSEC-2026-2255","PYSEC-2026-2256","PYSEC-2026-2257","PYSEC-2026-2874","PYSEC-2026-3451","PYSEC-2026-3453","PYSEC-2026-3454","PYSEC-2026-3493","PYSEC-2026-3494","PYSEC-2026-3495","PYSEC-2026-3496","PYSEC-2026-457","RUSTSEC-2023-0060","RUSTSEC-2023-0061"],"reachability":{"kind":"unknown"}}}},{"ruleId":"D30","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"dc4e5728a5653e68688371875694caafbe3725b2fc529d575eed172f33ec6b01"},"properties":{"dependency":{"package":"django","version":"4.1.7","advisory":"[GHSA redacted]","aliases":["BIT-django-2023-31047","BIT-django-2023-36053","BIT-django-2023-41164","BIT-django-2023-43665","BIT-django-2023-46695","BIT-django-2024-45231","BIT-django-2025-48432","BIT-django-2025-57833","BIT-django-2025-64458","BIT-django-2025-64459","BIT-django-2026-15307","BIT-django-2026-15830","BIT-django-2026-48587","BIT-django-2026-48588","BIT-django-2026-53877","BIT-django-2026-53878","BIT-django-2026-6873","BIT-django-2026-8404","[CVE redacted]","[CVE redacted]","[CVE redacted]","[CVE redacted]","[CVE redacted]","[CVE redacted]","[CVE redacted]","[CVE redacted]","[CVE redacted]","[CVE redacted]","[CVE redacted]","[CVE redacted]","[CVE redacted]","[CVE redacted]","[CVE redacted]","[CVE redacted]","[CVE redacted]","[CVE redacted]","[GHSA redacted]","[GHSA redacted]","[GHSA redacted]","[GHSA redacted]","[GHSA redacted]","[GHSA redacted]","[GHSA redacted]","[GHSA redacted]","[GHSA redacted]","[GHSA redacted]","[GHSA redacted]","[GHSA redacted]","[GHSA redacted]","[GHSA redacted]","[GHSA redacted]","[GHSA redacted]","[GHSA redacted]","PYSEC-2023-100","PYSEC-2023-222","PYSEC-2023-225","PYSEC-2023-226","PYSEC-2023-61","PYSEC-2025-105","PYSEC-2025-107","PYSEC-2025-108","PYSEC-2025-47","PYSEC-2026-1297","PYSEC-2026-198","PYSEC-2026-199","PYSEC-2026-201","PYSEC-2026-2090","PYSEC-2026-2091","PYSEC-2026-2092","PYSEC-2026-3717","PYSEC-2026-4035"],"reachability":{"kind":"unknown"}}}},{"ruleId":"D30","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"5476f40473a4985251fea0b9d6d99a482d142c87acc135658ea91e3081bde718"},"properties":{"dependency":{"package":"urllib3","version":"1.26.15","advisory":"[GHSA redacted]","aliases":["[CVE redacted]","[CVE redacted]","[CVE redacted]","[CVE redacted]","[CVE redacted]","[CVE redacted]","[CVE redacted]","[CVE redacted]","[CVE redacted]","[CVE redacted]","[GHSA redacted]","[GHSA redacted]","[GHSA redacted]","[GHSA redacted]","[GHSA redacted]","[GHSA redacted]","[GHSA redacted]","[GHSA redacted]","[GHSA redacted]","PYSEC-2023-192","PYSEC-2023-212","PYSEC-2026-141","PYSEC-2026-1994","PYSEC-2026-1995","PYSEC-2026-1996","PYSEC-2026-1998","PYSEC-2026-1999","PYSEC-2026-4175","PYSEC-2026-4177"],"reachability":{"kind":"unknown"}}}},{"ruleId":"D30","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"5acdd6214a5b07323449253a5b5ca29ab4704cdc1b0133e6b787c035a97f8cd3"},"properties":{"dependency":{"package":"cryptography","version":"40.0.1","advisory":"[GHSA redacted]","aliases":["[CVE redacted]","[CVE redacted]","[CVE redacted]","[CVE redacted]","[CVE redacted]","[CVE redacted]","[CVE redacted]","[CVE redacted]","[CVE redacted]","[GHSA redacted]","[GHSA redacted]","[GHSA redacted]","[GHSA redacted]","[GHSA redacted]","[GHSA redacted]","[GHSA redacted]","[GHSA redacted]","[GHSA redacted]","[GHSA redacted]","[GHSA redacted]","[GHSA redacted]","[GHSA redacted]","PYSEC-2023-112","PYSEC-2023-254","PYSEC-2024-225","PYSEC-2026-1283","PYSEC-2026-1285","PYSEC-2026-2141","PYSEC-2026-35","PYSEC-2026-3553","PYSEC-2026-3554"],"reachability":{"kind":"unknown"}}}},{"ruleId":"D30","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"a8660a76fda63062d25bbeab46c80517732d2fc081c2d1272bb3496d159e97f4"},"properties":{"dependency":{"package":"gunicorn","version":"20.1.0","advisory":"[GHSA redacted]","aliases":["[CVE redacted]","[CVE redacted]","[GHSA redacted]","PYSEC-2026-1433","PYSEC-2026-1434"],"reachability":{"kind":"unknown"}}}},{"ruleId":"D30","level":"warning","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"b2b43c0387a1c04f74eeb7aa1179aacde97dca83c9e003cfd25adad6e13080d8"},"properties":{"dependency":{"package":"django-allauth","version":"0.54.0","advisory":"[GHSA redacted]","aliases":["[CVE redacted]","[CVE redacted]","[CVE redacted]","[GHSA redacted]","[GHSA redacted]","PYSEC-2025-110","PYSEC-2025-111","PYSEC-2026-56"],"reachability":{"kind":"unknown"}}}},{"ruleId":"D30","level":"warning","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"6b41ab86abbb8f22d6744df55f4ef574935547020733211caa79aeac4f9fb1b0"},"properties":{"dependency":{"package":"djangorestframework","version":"3.14.0","advisory":"[GHSA redacted]","aliases":["[CVE redacted]","[CVE redacted]","[CVE redacted]","[GHSA redacted]","[GHSA redacted]","PYSEC-2026-1304","PYSEC-2026-3827","PYSEC-2026-3828"],"reachability":{"kind":"unknown"}}}},{"ruleId":"D30","level":"warning","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"06c9ce7c5a21c16d27137af288af4b9b9230c7f9e63e11a10340c5d3ee310998"},"properties":{"dependency":{"package":"pytest","version":"7.3.1","advisory":"[GHSA redacted]","aliases":["[CVE redacted]","PYSEC-2026-1845"],"reachability":{"kind":"unknown"}}}},{"ruleId":"D30","level":"warning","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"3068a88910c0f6d93e4b852773a558248edd27c9c71393fbc89f87124413deca"},"properties":{"dependency":{"package":"requests","version":"2.28.2","advisory":"[GHSA redacted]","aliases":["[CVE redacted]","[CVE redacted]","[CVE redacted]","[CVE redacted]","[GHSA redacted]","[GHSA redacted]","[GHSA redacted]","PYSEC-2023-74","PYSEC-2026-1872","PYSEC-2026-1873","PYSEC-2026-2275"],"reachability":{"kind":"unknown"}}}},{"ruleId":"D30","level":"warning","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"d15ca3d04d9a3b593188c0975ba011427e09a814d92fd659908e05f074cc27be"},"properties":{"dependency":{"package":"black","version":"23.3.0","advisory":"[GHSA redacted]","aliases":["[CVE redacted]","[CVE redacted]","[CVE redacted]","[GHSA redacted]","[GHSA redacted]","PYSEC-2024-48","PYSEC-2026-2120","PYSEC-2026-2121"],"reachability":{"kind":"unknown"}}}},{"ruleId":"D30","level":"warning","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"3ed23a4620df41dfb3b8bf5feb0e0766d310beaff2de99bfed4c063e564fc9c3"},"properties":{"dependency":{"package":"djangorestframework-simplejwt","version":"5.2.2","advisory":"PYSEC-2026-1305","aliases":["[CVE redacted]","[GHSA redacted]"],"reachability":{"kind":"unknown"}}}},{"ruleId":"D30","level":"warning","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"1404a79884fccd9be9c8f21d4086fc7c4709608c9e65bd0aa7ebf30179423db0"},"properties":{"dependency":{"package":"sentry-sdk","version":"1.21.1","advisory":"PYSEC-2026-1917","aliases":["[CVE redacted]","[GHSA redacted]"],"reachability":{"kind":"unknown"}}}},{"ruleId":"D34","level":"error","message":{"text":"Orphaned knowledge: No living knowledge remains for this large file \u2014 its last meaningful change has decayed away; if it breaks, no one currently understands it. Schedule a read-through / add characterisation tests before it bites."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/skills/incident-commander/scripts/pir_generator.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"627a23df7ec70dacf9c65a3e9d7b2ecffd395f42704bed81710c059a1dc06c0a"}},{"ruleId":"D34","level":"error","message":{"text":"Orphaned knowledge: No living knowledge remains for this large file \u2014 its last meaningful change has decayed away; if it breaks, no one currently understands it. Schedule a read-through / add characterisation tests before it bites."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/interview-system-designer/hiring_calibrator.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"088b40761afb682a606ca83fa494a7d6059259eec937bd2de983697a38a5c359"}},{"ruleId":"D34","level":"error","message":{"text":"Orphaned knowledge: No living knowledge remains for this large file \u2014 its last meaningful change has decayed away; if it breaks, no one currently understands it. Schedule a read-through / add characterisation tests before it bites."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/interview-system-designer/question_bank_generator.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"87fdd95237a1bd36a11da718247c0475c99b84a6b2e79a3c09cfc61158f451ea"}},{"ruleId":"D34","level":"error","message":{"text":"Orphaned knowledge: No living knowledge remains for this large file \u2014 its last meaningful change has decayed away; if it breaks, no one currently understands it. Schedule a read-through / add characterisation tests before it bites."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/database-designer/migration_generator.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"545b761a34820a30903b2628aaff69b15c8ac70ac27a44484d9ccd81fa138909"}},{"ruleId":"D34","level":"error","message":{"text":"Orphaned knowledge: No living knowledge remains for this large file \u2014 its last meaningful change has decayed away; if it breaks, no one currently understands it. Schedule a read-through / add characterisation tests before it bites."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/migration-architect/scripts/rollback_generator.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"6886873fc8051e3cc2c6ceadab6444c29fba5154ff717daf91790c6bc2877830"}},{"ruleId":"D34","level":"error","message":{"text":"Orphaned knowledge: No living knowledge remains for this large file \u2014 its last meaningful change has decayed away; if it breaks, no one currently understands it. Schedule a read-through / add characterisation tests before it bites."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/observability-designer/scripts/dashboard_generator.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"b1d859c4ac46d976d65f2d15c4d042dfb3f25b4eb53d39626c191044141ae69d"}},{"ruleId":"D34","level":"error","message":{"text":"Orphaned knowledge: No living knowledge remains for this large file \u2014 its last meaningful change has decayed away; if it breaks, no one currently understands it. Schedule a read-through / add characterisation tests before it bites."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/observability-designer/scripts/alert_optimizer.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"bbfed2745feeaff00599351f4421fe79b26e88fdfe69dfcb30ea74717b74c6e1"}},{"ruleId":"D34","level":"error","message":{"text":"Orphaned knowledge: No living knowledge remains for this large file \u2014 its last meaningful change has decayed away; if it breaks, no one currently understands it. Schedule a read-through / add characterisation tests before it bites."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/interview-system-designer/loop_designer.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"e2263b2c0da424ff902d6015a29b5029680f6636e55cdbdfb19a23cb4c464b97"}},{"ruleId":"D34","level":"error","message":{"text":"Orphaned knowledge: No living knowledge remains for this large file \u2014 its last meaningful change has decayed away; if it breaks, no one currently understands it. Schedule a read-through / add characterisation tests before it bites."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/dependency-auditor/scripts/license_checker.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"dc54fb6e3933a2a24409bc71adfb5cdbbbd34fbba6d6936efb81e443b3463cc0"}},{"ruleId":"D34","level":"error","message":{"text":"Orphaned knowledge: No living knowledge remains for this large file \u2014 its last meaningful change has decayed away; if it breaks, no one currently understands it. Schedule a read-through / add characterisation tests before it bites."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/skills/cloud-security/scripts/cloud_posture_check.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"1aa0a161014aa4e9ec6df930a993ca3e8f1e4cab0625359cfff74c10bda4bf3a"}},{"ruleId":"D34","level":"error","message":{"text":"Orphaned knowledge: No living knowledge remains for this large file \u2014 its last meaningful change has decayed away; if it breaks, no one currently understands it. Schedule a read-through / add characterisation tests before it bites."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/dependency-auditor/scripts/upgrade_planner.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"d91699c6ed36ffdb1d75d7870e39a2be2456e4595f0eb9aeddfadd29651e4000"}},{"ruleId":"D34","level":"error","message":{"text":"Orphaned knowledge: No living knowledge remains for this large file \u2014 its last meaningful change has decayed away; if it breaks, no one currently understands it. Schedule a read-through / add characterisation tests before it bites."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/migration-architect/scripts/compatibility_checker.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"eb3b45969dfa04ddc53daf99cb65fd7205d915ed751bc927ba8ef7e028268d5b"}},{"ruleId":"D34","level":"error","message":{"text":"Orphaned knowledge: No living knowledge remains for this large file \u2014 its last meaningful change has decayed away; if it breaks, no one currently understands it. Schedule a read-through / add characterisation tests before it bites."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/database-designer/schema_analyzer.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"f1c15409a367a6778335730f1be5314564dbc8663dbfb32ce7c802d082e13df9"}},{"ruleId":"D34","level":"error","message":{"text":"Orphaned knowledge: No living knowledge remains for this large file \u2014 its last meaningful change has decayed away; if it breaks, no one currently understands it. Schedule a read-through / add characterisation tests before it bites."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/tech-debt-tracker/scripts/debt_dashboard.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"85454b40a96e5ecacd880071404d1ce1bc5d51fa2dc4849fc3e93d1de2bf22a1"}},{"ruleId":"D34","level":"error","message":{"text":"Orphaned knowledge: No living knowledge remains for this large file \u2014 its last meaningful change has decayed away; if it breaks, no one currently understands it. Schedule a read-through / add characterisation tests before it bites."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/skills/incident-commander/scripts/timeline_reconstructor.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"95f4457cb4b8cf54a43cc3ddf60f9a477eec6b987dddc25a6761a1755fae2b36"}},{"ruleId":"D34","level":"error","message":{"text":"Orphaned knowledge: No living knowledge remains for this large file \u2014 its last meaningful change has decayed away; if it breaks, no one currently understands it. Schedule a read-through / add characterisation tests before it bites."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/database-designer/index_optimizer.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"ef9d76ea99cc8f5261fde43429dc232855d5084d336158afe6ed868e2e57ed5c"}},{"ruleId":"D34","level":"error","message":{"text":"Orphaned knowledge: No living knowledge remains for this large file \u2014 its last meaningful change has decayed away; if it breaks, no one currently understands it. Schedule a read-through / add characterisation tests before it bites."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/agent-designer/agent_planner.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"adb801f006d7a271dde3be9005341ae045072e813ee175615dd989fa7d3827ee"}},{"ruleId":"D34","level":"error","message":{"text":"Orphaned knowledge: No living knowledge remains for this large file \u2014 its last meaningful change has decayed away; if it breaks, no one currently understands it. Schedule a read-through / add characterisation tests before it bites."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/agent-designer/tool_schema_generator.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"8f2c1f4aa61b749853d291ed409ee1fabdedd1a69adb993b560d89f1ea1f939e"}},{"ruleId":"D34","level":"error","message":{"text":"Orphaned knowledge: No living knowledge remains for this large file \u2014 its last meaningful change has decayed away; if it breaks, no one currently understands it. Schedule a read-through / add characterisation tests before it bites."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"project-management/skills/scrum-master/scripts/retrospective_analyzer.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"550cf5631691a750b68fa5a9ee0813531dac9de64fefabced11be7eeee3aab5a"}},{"ruleId":"D34","level":"error","message":{"text":"Orphaned knowledge: No living knowledge remains for this large file \u2014 its last meaningful change has decayed away; if it breaks, no one currently understands it. Schedule a read-through / add characterisation tests before it bites."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/skills/incident-commander/scripts/incident_classifier.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"6d7f980d11b092876b37946bd583888ead3e863a19d7b89eb3465aa0dccf6ef2"}},{"ruleId":"D34","level":"error","message":{"text":"Orphaned knowledge: No living knowledge remains for this large file \u2014 its last meaningful change has decayed away; if it breaks, no one currently understands it. Schedule a read-through / add characterisation tests before it bites."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/tech-debt-tracker/scripts/debt_prioritizer.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"4b231b759e503162e3b656ad52d766c4463bf8545814842ed785d66eafa230e0"}},{"ruleId":"D34","level":"error","message":{"text":"Orphaned knowledge: No living knowledge remains for this large file \u2014 its last meaningful change has decayed away; if it breaks, no one currently understands it. Schedule a read-through / add characterisation tests before it bites."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"project-management/skills/senior-pm/scripts/resource_capacity_planner.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"221bd03c0c9b3ac4e9bcfc420d5c6745a4d57b5372f8e95cf0a3afe6c828e3ef"}},{"ruleId":"D34","level":"error","message":{"text":"Orphaned knowledge: No living knowledge remains for this large file \u2014 its last meaningful change has decayed away; if it breaks, no one currently understands it. Schedule a read-through / add characterisation tests before it bites."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"project-management/skills/senior-pm/scripts/project_health_dashboard.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"5f4ae21bcd3b1a0919ea79cc478d5a18f90ae496dc61f4a525206342cbc719b3"}},{"ruleId":"D34","level":"error","message":{"text":"Orphaned knowledge: No living knowledge remains for this large file \u2014 its last meaningful change has decayed away; if it breaks, no one currently understands it. Schedule a read-through / add characterisation tests before it bites."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/dependency-auditor/scripts/dep_scanner.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"376dc0f6152f8e169f2eb3a585fceddda2fca15f57ec876b7d7474a945855b5b"}},{"ruleId":"D34","level":"error","message":{"text":"Orphaned knowledge: No living knowledge remains for this large file \u2014 its last meaningful change has decayed away, so if it breaks, no one currently understands it. It does carry its own tests, so the behaviour is pinned even though the understanding is gone: schedule a read-through, using those tests as the specification, before the next change lands here."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/skill-tester/scripts/script_tester.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"37394ce64a2108f6a7e7c31b390da97e58619aed92b575a8d51b104947233ee0"}},{"ruleId":"D34","level":"error","message":{"text":"Orphaned knowledge: No living knowledge remains for this large file \u2014 its last meaningful change has decayed away; if it breaks, no one currently understands it. Schedule a read-through / add characterisation tests before it bites."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/rag-architect/chunking_optimizer.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"b7e7c0c4cd465cd8f53ae35f899f17e3cab1f2335d362dd4f71c3c61165d40a9"}},{"ruleId":"D34","level":"error","message":{"text":"Orphaned knowledge: No living knowledge remains for this large file \u2014 its last meaningful change has decayed away; if it breaks, no one currently understands it. Schedule a read-through / add characterisation tests before it bites."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/observability-designer/scripts/slo_designer.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"bfd257fbcf9268c17c16af4d8e4736aa4ba87046c10301ad587f8fdcabe1609c"}},{"ruleId":"D34","level":"error","message":{"text":"Orphaned knowledge: No living knowledge remains for this large file \u2014 its last meaningful change has decayed away; if it breaks, no one currently understands it. Schedule a read-through / add characterisation tests before it bites."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"project-management/skills/scrum-master/scripts/sprint_health_scorer.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"fcfc4e008e2445f707483e63bf90584ece3718e8290cf89617c209bab1c481df"}},{"ruleId":"D34","level":"error","message":{"text":"Orphaned knowledge: No living knowledge remains for this large file \u2014 its last meaningful change has decayed away; if it breaks, no one currently understands it. Schedule a read-through / add characterisation tests before it bites."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/rag-architect/rag_pipeline_designer.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"48737a84bd37602a4f6a7f0c5564f2f3ec4c3b48995109386c3aeb7740b45d68"}},{"ruleId":"D34","level":"error","message":{"text":"Orphaned knowledge: No living knowledge remains for this large file \u2014 its last meaningful change has decayed away; if it breaks, no one currently understands it. Schedule a read-through / add characterisation tests before it bites."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"project-management/skills/senior-pm/scripts/risk_matrix_analyzer.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"253fd09b0194d00ed491468ec36e2af9b4e8fc4baabf6894c9af3b14649f4426"}},{"ruleId":"D34","level":"error","message":{"text":"Orphaned knowledge: No living knowledge remains for this large file \u2014 its last meaningful change has decayed away; if it breaks, no one currently understands it. Schedule a read-through / add characterisation tests before it bites."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/migration-architect/scripts/migration_planner.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"5db308721dd2692328270aa42781da8abebd2e572ab8b6c9f7ef98f295b8ab87"}},{"ruleId":"D34","level":"error","message":{"text":"Orphaned knowledge: No living knowledge remains for this large file \u2014 its last meaningful change has decayed away; if it breaks, no one currently understands it. Schedule a read-through / add characterisation tests before it bites."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/tech-debt-tracker/scripts/debt_scanner.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"fdf6d4e2745c2bb1be56bdb97ac8290dd3522b709f0fe521d5a1c1d62cd23003"}},{"ruleId":"D34","level":"error","message":{"text":"Orphaned knowledge: No living knowledge remains for this large file \u2014 its last meaningful change has decayed away; if it breaks, no one currently understands it. Schedule a read-through / add characterisation tests before it bites."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/skills/threat-detection/scripts/threat_signal_analyzer.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"12ee689d7f6f7229307fa3171381998d04e8bdb2e660d98e709e0ffa0e4d4fe1"}},{"ruleId":"D34","level":"error","message":{"text":"Orphaned knowledge: No living knowledge remains for this large file \u2014 its last meaningful change has decayed away; if it breaks, no one currently understands it. Schedule a read-through / add characterisation tests before it bites."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/rag-architect/retrieval_evaluator.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"e91a1dd803f4ad8a91f1a3709682664801b668feafab40fbbb8bfc53ea3af997"}},{"ruleId":"D34","level":"error","message":{"text":"Orphaned knowledge: No living knowledge remains for this large file \u2014 its last meaningful change has decayed away; if it breaks, no one currently understands it. Schedule a read-through / add characterisation tests before it bites."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/skill-tester/scripts/security_scorer.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"d4209b43ed44f3a93caddc0bea8a1b35e0315f3910a16fff378866d72729a808"}},{"ruleId":"D34","level":"error","message":{"text":"Orphaned knowledge: No living knowledge remains for this large file \u2014 its last meaningful change has decayed away; if it breaks, no one currently understands it. Schedule a read-through / add characterisation tests before it bites."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/changelog-generator/scripts/version_bumper.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"1613ec213231efa9d169a0796561fbc7889821c77d47d2745a479c7f03b30f62"}},{"ruleId":"D34","level":"error","message":{"text":"Orphaned knowledge: No living knowledge remains for this large file \u2014 its last meaningful change has decayed away; if it breaks, no one currently understands it. Schedule a read-through / add characterisation tests before it bites."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"ra-qm-team/skills/regulatory-affairs-head/scripts/regulatory_pathway_analyzer.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"dedb8e4437ef5b1366b8f3aa51bc7a28e4aaa258c25833ffe5f42aa8b1ec4c3c"}},{"ruleId":"D34","level":"error","message":{"text":"Orphaned knowledge: No living knowledge remains for this large file \u2014 its last meaningful change has decayed away; if it breaks, no one currently understands it. Schedule a read-through / add characterisation tests before it bites."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/skills/ai-security/scripts/ai_threat_scanner.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"50889030cbd8cd1db503c2e75e04d41e0a330ece7b24d9f8cc80ec95e19131cd"}},{"ruleId":"D34","level":"error","message":{"text":"Orphaned knowledge: No living knowledge remains for this large file \u2014 its last meaningful change has decayed away; if it breaks, no one currently understands it. Schedule a read-through / add characterisation tests before it bites."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"project-management/skills/scrum-master/scripts/velocity_analyzer.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"39c74625e9bdcb6622596b6c4afa1cf4671bde17bfb062334b4659c92db432bb"}},{"ruleId":"D34","level":"error","message":{"text":"Orphaned knowledge: No living knowledge remains for this large file \u2014 its last meaningful change has decayed away; if it breaks, no one currently understands it. Schedule a read-through / add characterisation tests before it bites."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/helm-chart-builder/skills/helm-chart-builder/scripts/chart_analyzer.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"c92d14ee4c1a4976016a66dfb1f95099b896771817a424b9e81ed0b22392c20a"}},{"ruleId":"D34","level":"error","message":{"text":"Orphaned knowledge: No living knowledge remains for this large file \u2014 its last meaningful change has decayed away; if it breaks, no one currently understands it. Schedule a read-through / add characterisation tests before it bites."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/skills/red-team/scripts/engagement_planner.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"60974bdb3dce9a2bba2365d11e8096c4dc241fd9f330b5953c2338a9ebfd61b2"}},{"ruleId":"D34","level":"note","message":{"text":"Further orphaned files (smaller): 35 smaller file(s) also have no living knowledge \u2014 folded into the freshness score and metrics rather than raised one row each \u2014 most significant first: engineering/terraform-patterns/skills/terraform-patterns/scripts/tf_security_scanner.py, ra-qm-team/skills/capa-officer/scripts/root_cause_analyzer.py, engineering/statistical-analyst/skills/statistical-analyst/scripts/hypothesis_tester.py, ra-qm-team/skills/risk-management-specialist/scripts/fmea_analyzer.py, engineering/helm-chart-builder/skills/helm-chart-builder/scripts/values_validator.py, engineering/skills/tc-tracker/scripts/tc_validator.py, engineering/skills/tc-tracker/scripts/tc_update.py, engineering/terraform-patterns/skills/terraform-patterns/scripts/tf_module_analyzer.py (and 27 more) (76 orphaned of 728 analysed files in total, counted over production source files of roughly 2,400 bytes or more, excluding vendored, generated and example/demo trees and test files identified by path convention, largest first; 728 of the 752 production source files in this repository met that bar). Attach the read to the next change that touches one of them: have a second person review that change, and leave behind a short comment or test recording what the file is for, so the knowledge comes back at the cost of a change you were making anyway."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"ce861fd78f6935114d3a342cb90ad25870f984e1042954fcbbe27c0e23be3658"}},{"ruleId":"D34","level":"note","message":{"text":"Orphaned file: No one still active in this repository holds living knowledge of this file: everyone who made a meaningful change to it has gone quiet, or what the current team did to it (moves, reformatting, log-level or import edits, renames) never needed understanding it. If it breaks, no one currently understands it. Attach the read to the next change that touches it: have a second person review that change, and leave behind a short comment or test recording what the file is for."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/terraform-patterns/skills/terraform-patterns/scripts/tf_security_scanner.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"4a931b4f1f5419fb0d7edd14cac75fe4bbe40b17098bcafb1aef69dc0c8e7dd0"}},{"ruleId":"D34","level":"note","message":{"text":"Orphaned file: No one still active in this repository holds living knowledge of this file: everyone who made a meaningful change to it has gone quiet, or what the current team did to it (moves, reformatting, log-level or import edits, renames) never needed understanding it. If it breaks, no one currently understands it. Attach the read to the next change that touches it: have a second person review that change, and leave behind a short comment or test recording what the file is for."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"ra-qm-team/skills/capa-officer/scripts/root_cause_analyzer.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"21afa537664dfde77a7c4e1673dd4cdec9e2660fee0b58add094122167ba89fb"}},{"ruleId":"D34","level":"note","message":{"text":"Orphaned file: No one still active in this repository holds living knowledge of this file: everyone who made a meaningful change to it has gone quiet, or what the current team did to it (moves, reformatting, log-level or import edits, renames) never needed understanding it. If it breaks, no one currently understands it. Attach the read to the next change that touches it: have a second person review that change, and leave behind a short comment or test recording what the file is for."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/statistical-analyst/skills/statistical-analyst/scripts/hypothesis_tester.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"4c74ae7ea387d1a98f72b810f417bf5966caf30ae1a0ce8e9e187abc83955653"}},{"ruleId":"D34","level":"note","message":{"text":"Orphaned file: No one still active in this repository holds living knowledge of this file: everyone who made a meaningful change to it has gone quiet, or what the current team did to it (moves, reformatting, log-level or import edits, renames) never needed understanding it. If it breaks, no one currently understands it. Attach the read to the next change that touches it: have a second person review that change, and leave behind a short comment or test recording what the file is for."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"ra-qm-team/skills/risk-management-specialist/scripts/fmea_analyzer.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"706dc340576ffb0530c203b5aa7294d5ac2b774b2480c83c321945fd0951cabb"}},{"ruleId":"D34","level":"note","message":{"text":"Orphaned file: No one still active in this repository holds living knowledge of this file: everyone who made a meaningful change to it has gone quiet, or what the current team did to it (moves, reformatting, log-level or import edits, renames) never needed understanding it. If it breaks, no one currently understands it. Attach the read to the next change that touches it: have a second person review that change, and leave behind a short comment or test recording what the file is for."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/helm-chart-builder/skills/helm-chart-builder/scripts/values_validator.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"9e0fe764e1d04dc3ed751dc12872c7604d4e9e549e68ff6a308e7ee13eb6da2e"}},{"ruleId":"D34","level":"note","message":{"text":"Orphaned file: No one still active in this repository holds living knowledge of this file: everyone who made a meaningful change to it has gone quiet, or what the current team did to it (moves, reformatting, log-level or import edits, renames) never needed understanding it. If it breaks, no one currently understands it. Attach the read to the next change that touches it: have a second person review that change, and leave behind a short comment or test recording what the file is for."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/tc-tracker/scripts/tc_validator.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"cda29868cb539d41743f84248e2fc05855826927a52cbfb1f0946c87af62ffab"}},{"ruleId":"D34","level":"note","message":{"text":"Orphaned file: No one still active in this repository holds living knowledge of this file: everyone who made a meaningful change to it has gone quiet, or what the current team did to it (moves, reformatting, log-level or import edits, renames) never needed understanding it. If it breaks, no one currently understands it. Attach the read to the next change that touches it: have a second person review that change, and leave behind a short comment or test recording what the file is for."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/tc-tracker/scripts/tc_update.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"ed060f9d4f42215dd4cc147a5385785dcd46be3f84ad0a0cce2d33d78d3bb28c"}},{"ruleId":"D34","level":"note","message":{"text":"Orphaned file: No one still active in this repository holds living knowledge of this file: everyone who made a meaningful change to it has gone quiet, or what the current team did to it (moves, reformatting, log-level or import edits, renames) never needed understanding it. If it breaks, no one currently understands it. Attach the read to the next change that touches it: have a second person review that change, and leave behind a short comment or test recording what the file is for."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/terraform-patterns/skills/terraform-patterns/scripts/tf_module_analyzer.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"4a345c7f719c4784d7816d63c3366fcd2a1696c89f8cb3c6423ea7c8f2851e8f"}},{"ruleId":"D34","level":"note","message":{"text":"Orphaned file: No one still active in this repository holds living knowledge of this file: everyone who made a meaningful change to it has gone quiet, or what the current team did to it (moves, reformatting, log-level or import edits, renames) never needed understanding it. If it breaks, no one currently understands it. Attach the read to the next change that touches it: have a second person review that change, and leave behind a short comment or test recording what the file is for."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/docker-development/skills/docker-development/scripts/dockerfile_analyzer.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"02809270ae7586a9a4839eae42023fba0719fa86701e8b9b687439fd36be8416"}},{"ruleId":"D34","level":"note","message":{"text":"Orphaned file: No one still active in this repository holds living knowledge of this file: everyone who made a meaningful change to it has gone quiet, or what the current team did to it (moves, reformatting, log-level or import edits, renames) never needed understanding it. If it breaks, no one currently understands it. Attach the read to the next change that touches it: have a second person review that change, and leave behind a short comment or test recording what the file is for."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/skill-tester/assets/sample-skill/scripts/text_processor.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"36754afc43e372790bba0ea4cd0bd4331d7ea6f9a2dcc840e494441fb7df2f5e"}},{"ruleId":"D34","level":"note","message":{"text":"Orphaned file: No one still active in this repository holds living knowledge of this file: everyone who made a meaningful change to it has gone quiet, or what the current team did to it (moves, reformatting, log-level or import edits, renames) never needed understanding it. If it breaks, no one currently understands it. Attach the read to the next change that touches it: have a second person review that change, and leave behind a short comment or test recording what the file is for."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/docker-development/skills/docker-development/scripts/compose_validator.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"f7372918bceaf3480cddfd7666f3d258289c03be00f3d84e042564db2d131e33"}},{"ruleId":"D34","level":"note","message":{"text":"Orphaned file: No one still active in this repository holds living knowledge of this file: everyone who made a meaningful change to it has gone quiet, or what the current team did to it (moves, reformatting, log-level or import edits, renames) never needed understanding it. If it breaks, no one currently understands it. Attach the read to the next change that touches it: have a second person review that change, and leave behind a short comment or test recording what the file is for."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"marketing-skill/skills/x-twitter-growth/scripts/profile_auditor.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"e50c8bd216920789ea65594f8360b8114df0320fb37818943b5cb3c16b5bb175"}},{"ruleId":"D34","level":"note","message":{"text":"Orphaned file: No one still active in this repository holds living knowledge of this file: everyone who made a meaningful change to it has gone quiet, or what the current team did to it (moves, reformatting, log-level or import edits, renames) never needed understanding it. If it breaks, no one currently understands it. Attach the read to the next change that touches it: have a second person review that change, and leave behind a short comment or test recording what the file is for."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"product-team/research-summarizer/skills/research-summarizer/scripts/format_summary.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"a81fa9ca30199cd288831f81a1098d6fbaed9cbe047e714c5daa8a51620c8158"}},{"ruleId":"D34","level":"note","message":{"text":"Orphaned file: No one still active in this repository holds living knowledge of this file: everyone who made a meaningful change to it has gone quiet, or what the current team did to it (moves, reformatting, log-level or import edits, renames) never needed understanding it. If it breaks, no one currently understands it. Attach the read to the next change that touches it: have a second person review that change, and leave behind a short comment or test recording what the file is for."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"marketing-skill/skills/x-twitter-growth/scripts/tweet_composer.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"c2a019f02f7511c0aa89c030cd5eea597e70be0525fb2df01044f6bb9bf0e806"}},{"ruleId":"D34","level":"note","message":{"text":"Orphaned file: No one still active in this repository holds living knowledge of this file: everyone who made a meaningful change to it has gone quiet, or what the current team did to it (moves, reformatting, log-level or import edits, renames) never needed understanding it. If it breaks, no one currently understands it. Attach the read to the next change that touches it: have a second person review that change, and leave behind a short comment or test recording what the file is for."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/tc-tracker/scripts/tc_create.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"ccfd990e737866f52ceb6e8d9b0fc1c42778b9bbc04bc69d1b2e2fa37a061dbb"}},{"ruleId":"D34","level":"note","message":{"text":"Orphaned file: No one still active in this repository holds living knowledge of this file: everyone who made a meaningful change to it has gone quiet, or what the current team did to it (moves, reformatting, log-level or import edits, renames) never needed understanding it. If it breaks, no one currently understands it. Attach the read to the next change that touches it: have a second person review that change, and leave behind a short comment or test recording what the file is for."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"marketing-skill/skills/x-twitter-growth/scripts/growth_tracker.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"4c8175a8299e3d3f8c6f2a43cb57be61333c22af3e255e501876f888fd28e638"}},{"ruleId":"D34","level":"note","message":{"text":"Orphaned file: No one still active in this repository holds living knowledge of this file: everyone who made a meaningful change to it has gone quiet, or what the current team did to it (moves, reformatting, log-level or import edits, renames) never needed understanding it. If it breaks, no one currently understands it. Attach the read to the next change that touches it: have a second person review that change, and leave behind a short comment or test recording what the file is for."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"finance/skills/saas-metrics-coach/scripts/metrics_calculator.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"9ee4cbe7129f17a24e79ea4f1c1f7f03b8acf8ff38ced40727d2386909bae8fd"}},{"ruleId":"D34","level":"note","message":{"text":"Orphaned file: No one still active in this repository holds living knowledge of this file: everyone who made a meaningful change to it has gone quiet, or what the current team did to it (moves, reformatting, log-level or import edits, renames) never needed understanding it. If it breaks, no one currently understands it. Attach the read to the next change that touches it: have a second person review that change, and leave behind a short comment or test recording what the file is for."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"product-team/research-summarizer/skills/research-summarizer/scripts/extract_citations.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"1ba0135aa6a1d94ce0bd7d16170531d73e655ef92a2d8a77154db144f43b2d3b"}},{"ruleId":"D34","level":"note","message":{"text":"Orphaned file: No one still active in this repository holds living knowledge of this file: everyone who made a meaningful change to it has gone quiet, or what the current team did to it (moves, reformatting, log-level or import edits, renames) never needed understanding it. If it breaks, no one currently understands it. Attach the read to the next change that touches it: have a second person review that change, and leave behind a short comment or test recording what the file is for."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/tech-debt-tracker/assets/sample_codebase/src/user_service.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"1a25d96f6ffe6224eb26d4d6fc54e5e9a76dcdfaedc4d29d541a89e9d87b835f"}},{"ruleId":"D34","level":"note","message":{"text":"Orphaned file: No one still active in this repository holds living knowledge of this file: everyone who made a meaningful change to it has gone quiet, or what the current team did to it (moves, reformatting, log-level or import edits, renames) never needed understanding it. If it breaks, no one currently understands it. Attach the read to the next change that touches it: have a second person review that change, and leave behind a short comment or test recording what the file is for."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/data-quality-auditor/skills/data-quality-auditor/scripts/missing_value_analyzer.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"a934745ca16a0b93b6ee6129c82a1872a9f7e95234e631ff9b3929cf6066bc8f"}},{"ruleId":"D34","level":"note","message":{"text":"Orphaned file: No one still active in this repository holds living knowledge of this file: everyone who made a meaningful change to it has gone quiet, or what the current team did to it (moves, reformatting, log-level or import edits, renames) never needed understanding it. If it breaks, no one currently understands it. Attach the read to the next change that touches it: have a second person review that change, and leave behind a short comment or test recording what the file is for."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"marketing-skill/skills/x-twitter-growth/scripts/competitor_analyzer.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"81f361fc1067bda5aaadcba2f0dac5056c93df72b4150991d793de49fe009216"}},{"ruleId":"D34","level":"note","message":{"text":"Orphaned file: No one still active in this repository holds living knowledge of this file: everyone who made a meaningful change to it has gone quiet, or what the current team did to it (moves, reformatting, log-level or import edits, renames) never needed understanding it. If it breaks, no one currently understands it. Attach the read to the next change that touches it: have a second person review that change, and leave behind a short comment or test recording what the file is for."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"marketing-skill/skills/x-twitter-growth/scripts/content_planner.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"0144ed53ca09cc894bb8103e91b28138016420681024afe3dfe6d02b1df36adc"}},{"ruleId":"D34","level":"note","message":{"text":"Orphaned file: No one still active in this repository holds living knowledge of this file: everyone who made a meaningful change to it has gone quiet, or what the current team did to it (moves, reformatting, log-level or import edits, renames) never needed understanding it. If it breaks, no one currently understands it. Attach the read to the next change that touches it: have a second person review that change, and leave behind a short comment or test recording what the file is for."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/tc-tracker/scripts/tc_status.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"b4403214c7fecba7975670de0b3398439ccd94dc6489da8b5097a85e7b621f31"}},{"ruleId":"D34","level":"note","message":{"text":"Orphaned file: No one still active in this repository holds living knowledge of this file: everyone who made a meaningful change to it has gone quiet, or what the current team did to it (moves, reformatting, log-level or import edits, renames) never needed understanding it. If it breaks, no one currently understands it. Attach the read to the next change that touches it: have a second person review that change, and leave behind a short comment or test recording what the file is for."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/statistical-analyst/skills/statistical-analyst/scripts/confidence_interval.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"c8893de7c91eeac325880d0cf33df81fec5517d02ed5470631270b64a2cf9ea5"}},{"ruleId":"D34","level":"note","message":{"text":"Orphaned file: No one still active in this repository holds living knowledge of this file: everyone who made a meaningful change to it has gone quiet, or what the current team did to it (moves, reformatting, log-level or import edits, renames) never needed understanding it. If it breaks, no one currently understands it. Attach the read to the next change that touches it: have a second person review that change, and leave behind a short comment or test recording what the file is for."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/tc-tracker/scripts/tc_init.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"a8c7b64b13512eabb27688f7f7ea262b8e700bb6115a23c535b34250d082561c"}},{"ruleId":"D34","level":"note","message":{"text":"Orphaned file: No one still active in this repository holds living knowledge of this file: everyone who made a meaningful change to it has gone quiet, or what the current team did to it (moves, reformatting, log-level or import edits, renames) never needed understanding it. If it breaks, no one currently understands it. Attach the read to the next change that touches it: have a second person review that change, and leave behind a short comment or test recording what the file is for."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"finance/skills/saas-metrics-coach/scripts/quick_ratio_calculator.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"e40d1b30f3f6496a276e7d7133790311a15f77ff97d6c348c450de32ac6cf472"}},{"ruleId":"D34","level":"note","message":{"text":"Orphaned file: No one still active in this repository holds living knowledge of this file: everyone who made a meaningful change to it has gone quiet, or what the current team did to it (moves, reformatting, log-level or import edits, renames) never needed understanding it. If it breaks, no one currently understands it. Attach the read to the next change that touches it: have a second person review that change, and leave behind a short comment or test recording what the file is for."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/codebase-onboarding/scripts/codebase_analyzer.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"732dd5f73099e4594ace513862798764e9ecd6099ddf061f9c1c74772e265ad0"}},{"ruleId":"D34","level":"note","message":{"text":"Orphaned file: No one still active in this repository holds living knowledge of this file: everyone who made a meaningful change to it has gone quiet, or what the current team did to it (moves, reformatting, log-level or import edits, renames) never needed understanding it. If it breaks, no one currently understands it. Attach the read to the next change that touches it: have a second person review that change, and leave behind a short comment or test recording what the file is for."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/monorepo-navigator/scripts/monorepo_analyzer.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"12613b0bcd8ce1618c80926b3c48dd0db44fd2ab05746f03419b33288e8b0a94"}},{"ruleId":"D34","level":"note","message":{"text":"Orphaned file: No one still active in this repository holds living knowledge of this file: everyone who made a meaningful change to it has gone quiet, or what the current team did to it (moves, reformatting, log-level or import edits, renames) never needed understanding it. If it breaks, no one currently understands it. Attach the read to the next change that touches it: have a second person review that change, and leave behind a short comment or test recording what the file is for."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/interview-system-designer/scripts/interview_planner.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"0a84ed00c11a645f9286d822e1215fd4a523e0f047b247b372174147cbe14643"}},{"ruleId":"D34","level":"note","message":{"text":"Orphaned file: No one still active in this repository holds living knowledge of this file: everyone who made a meaningful change to it has gone quiet, or what the current team did to it (moves, reformatting, log-level or import edits, renames) never needed understanding it. If it breaks, no one currently understands it. Attach the read to the next change that touches it: have a second person review that change, and leave behind a short comment or test recording what the file is for."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/env-secrets-manager/scripts/env_auditor.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"34c986904de5ebccc2cff5c21676259b1791fcf858b54ca217038e09643a5f2b"}},{"ruleId":"D34","level":"note","message":{"text":"Orphaned file: No one still active in this repository holds living knowledge of this file: everyone who made a meaningful change to it has gone quiet, or what the current team did to it (moves, reformatting, log-level or import edits, renames) never needed understanding it. If it breaks, no one currently understands it. Attach the read to the next change that touches it: have a second person review that change, and leave behind a short comment or test recording what the file is for."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"product-team/skills/product-discovery/scripts/assumption_mapper.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"2f2b36c50ace94ea893f04549134b9b2f369c496b94bcec22ad291c87c65a162"}},{"ruleId":"D34","level":"note","message":{"text":"Orphaned file: No one still active in this repository holds living knowledge of this file: everyone who made a meaningful change to it has gone quiet, or what the current team did to it (moves, reformatting, log-level or import edits, renames) never needed understanding it. If it breaks, no one currently understands it. Attach the read to the next change that touches it: have a second person review that change, and leave behind a short comment or test recording what the file is for."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"product-team/apple-hig-expert/skills/apple-hig-expert/scripts/hig_checker.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"5b255b321c9dc072a066dd005955ac6bdadffab4a5a7fab34e62a8c44da51fbc"}},{"ruleId":"D34","level":"note","message":{"text":"Orphaned file: No one still active in this repository holds living knowledge of this file: everyone who made a meaningful change to it has gone quiet, or what the current team did to it (moves, reformatting, log-level or import edits, renames) never needed understanding it. If it breaks, no one currently understands it. Attach the read to the next change that touches it: have a second person review that change, and leave behind a short comment or test recording what the file is for."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/agent-workflow-designer/scripts/workflow_scaffolder.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"f7c9f0cbc522133a4443825b3bf75c1abd080d82c40d00b02fdc57fa99637cc3"}},{"ruleId":"D34","level":"note","message":{"text":"Orphaned file: No one still active in this repository holds living knowledge of this file: everyone who made a meaningful change to it has gone quiet, or what the current team did to it (moves, reformatting, log-level or import edits, renames) never needed understanding it. If it breaks, no one currently understands it. Attach the read to the next change that touches it: have a second person review that change, and leave behind a short comment or test recording what the file is for."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"product-team/skills/experiment-designer/scripts/sample_size_calculator.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"f6910227c05e57810c47fb202876308199e5dc9c3d4fd7e1221b837803fa866d"}},{"ruleId":"D34","level":"note","message":{"text":"Orphaned file: No one still active in this repository holds living knowledge of this file: everyone who made a meaningful change to it has gone quiet, or what the current team did to it (moves, reformatting, log-level or import edits, renames) never needed understanding it. If it breaks, no one currently understands it. Attach the read to the next change that touches it: have a second person review that change, and leave behind a short comment or test recording what the file is for."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/runbook-generator/scripts/runbook_generator.py"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"8fafde9f2f0f3f23d88fca4a115d7c6cc41ff8ed33b8d8b09d213e0ac0bf0e0a"}},{"ruleId":"D36","level":"note","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"1b213f6eedd4b140d0bc37bdf1496f72811a643f34064f12518b32e9e83bcfc7"},"taxa":[{"id":"CICD-SEC-9","toolComponent":{"name":"OWASP Top 10 CI/CD Security Risks","guid":"3c9b2a6e-5d14-4f7b-8e02-6a1d9c4b7f35"}}]},{"ruleId":"D36","level":"note","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"0e17f71490e4d120a48b2b2881ab866c93b272bef2febb673a3e8e42b2c288ab"},"taxa":[{"id":"CICD-SEC-9","toolComponent":{"name":"OWASP Top 10 CI/CD Security Risks","guid":"3c9b2a6e-5d14-4f7b-8e02-6a1d9c4b7f35"}}]},{"ruleId":"D36","level":"note","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"eb00976a698a5d68999b7ee6d27206fd374e916853e7ff1ead5eed42386f043f"},"taxa":[{"id":"CICD-SEC-9","toolComponent":{"name":"OWASP Top 10 CI/CD Security Risks","guid":"3c9b2a6e-5d14-4f7b-8e02-6a1d9c4b7f35"}}]},{"ruleId":"D36","level":"warning","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"90f83b4fa27db32740afe9540c905f3c0499caed87f61049a8a903ecc95b41c3"},"taxa":[{"id":"CICD-SEC-8","toolComponent":{"name":"OWASP Top 10 CI/CD Security Risks","guid":"3c9b2a6e-5d14-4f7b-8e02-6a1d9c4b7f35"}}]},{"ruleId":"D36","level":"warning","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"81691587bb67a4879135c86871abb844d0343283fee2ab0b9592a80022176498"},"taxa":[{"id":"CICD-SEC-6","toolComponent":{"name":"OWASP Top 10 CI/CD Security Risks","guid":"3c9b2a6e-5d14-4f7b-8e02-6a1d9c4b7f35"}}]},{"ruleId":"D36","level":"note","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"ace515990e7ee0f17b5c17e44dd168a5bdecf90804a3a3dd845cf05540978013"},"taxa":[{"id":"CICD-SEC-3","toolComponent":{"name":"OWASP Top 10 CI/CD Security Risks","guid":"3c9b2a6e-5d14-4f7b-8e02-6a1d9c4b7f35"}}]},{"ruleId":"AC1","level":"error","message":{"text":"\u003Cimg\u003E without a text alternative: An image with no alt (and no aria-label/aria-labelledby) is unreadable to assistive tech. Add alt \u2014 alt=\u0022\u0022 if it\u0027s purely decorative."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":".codex/skills/a11y-audit/assets/sample-component.tsx"},"region":{"startLine":7}}}],"partialFingerprints":{"codehealthFindingId/v1":"aaf43be67911539916e69e405757cd11a0c3fb87a51b577cdf192fac88ce5b26"}},{"ruleId":"AC1","level":"error","message":{"text":"\u003Cimg\u003E without a text alternative: An image with no alt (and no aria-label/aria-labelledby) is unreadable to assistive tech. Add alt \u2014 alt=\u0022\u0022 if it\u0027s purely decorative."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":".hermes/skills/claude-skills/engineering-team/a11y-audit/assets/sample-component.tsx"},"region":{"startLine":7}}}],"partialFingerprints":{"codehealthFindingId/v1":"bc62e0e0bd71a63f6db8d77b19788a77e6c837a4c0d2491590bfdf95102d091b"}},{"ruleId":"AC1","level":"error","message":{"text":"\u003Cimg\u003E without a text alternative: An image with no alt (and no aria-label/aria-labelledby) is unreadable to assistive tech. Add alt \u2014 alt=\u0022\u0022 if it\u0027s purely decorative."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":".vibe/skills/claude-skills/engineering-team/a11y-audit/assets/sample-component.tsx"},"region":{"startLine":7}}}],"partialFingerprints":{"codehealthFindingId/v1":"7993a4202d62ebfe3a17387128e987522503a139afc49c4b1e10020fba614f7a"}},{"ruleId":"AC1","level":"error","message":{"text":"\u003Cimg\u003E without a text alternative: An image with no alt (and no aria-label/aria-labelledby) is unreadable to assistive tech. Add alt \u2014 alt=\u0022\u0022 if it\u0027s purely decorative."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/a11y-audit/skills/a11y-audit/assets/sample-component.tsx"},"region":{"startLine":7}}}],"partialFingerprints":{"codehealthFindingId/v1":"d55bdaa33026e8bdc93f9fab02d0fc0316032fc058605b55d59035dc936f7f48"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Cinput\u003E without a programmatic label: This control has only a placeholder \u2014 a placeholder is not a label (it vanishes on input and many AT ignore it). Add a \u003Clabel htmlFor\u003E, a wrapping \u003Clabel\u003E, or aria-label."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":".codex/skills/a11y-audit/assets/sample-component.tsx"},"region":{"startLine":16}}}],"partialFingerprints":{"codehealthFindingId/v1":"8101b0e0e56beeedc68c1c67503f90e73dba170f171e723883b1de2e9cb9c1b7"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Cinput\u003E without a programmatic label: This control has only a placeholder \u2014 a placeholder is not a label (it vanishes on input and many AT ignore it). Add a \u003Clabel htmlFor\u003E, a wrapping \u003Clabel\u003E, or aria-label."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":".codex/skills/a11y-audit/assets/sample-component.tsx"},"region":{"startLine":24}}}],"partialFingerprints":{"codehealthFindingId/v1":"392eed469e7d3a15b9d39ec10ce790da527d3a1366b9462bf68b1aac32bdaebb"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Cinput\u003E without a programmatic label: This control has only a placeholder \u2014 a placeholder is not a label (it vanishes on input and many AT ignore it). Add a \u003Clabel htmlFor\u003E, a wrapping \u003Clabel\u003E, or aria-label."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":".hermes/skills/claude-skills/engineering-team/a11y-audit/assets/sample-component.tsx"},"region":{"startLine":16}}}],"partialFingerprints":{"codehealthFindingId/v1":"a672a1764beda18c260dcb771357832515386d1655312a0c1cab280825835681"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Cinput\u003E without a programmatic label: This control has only a placeholder \u2014 a placeholder is not a label (it vanishes on input and many AT ignore it). Add a \u003Clabel htmlFor\u003E, a wrapping \u003Clabel\u003E, or aria-label."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":".hermes/skills/claude-skills/engineering-team/a11y-audit/assets/sample-component.tsx"},"region":{"startLine":24}}}],"partialFingerprints":{"codehealthFindingId/v1":"30097b0e683c8dcb91f1b4ee7f4c14759b9819ffc60064a2e5ef218a9dd2d723"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Cinput\u003E without a programmatic label: This control has only a placeholder \u2014 a placeholder is not a label (it vanishes on input and many AT ignore it). Add a \u003Clabel htmlFor\u003E, a wrapping \u003Clabel\u003E, or aria-label."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":".vibe/skills/claude-skills/engineering-team/a11y-audit/assets/sample-component.tsx"},"region":{"startLine":16}}}],"partialFingerprints":{"codehealthFindingId/v1":"fb4b4efc6470cf7fba0dfefd24dc082c7bd5e4797a1493721599ce8e80bb0340"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Cinput\u003E without a programmatic label: This control has only a placeholder \u2014 a placeholder is not a label (it vanishes on input and many AT ignore it). Add a \u003Clabel htmlFor\u003E, a wrapping \u003Clabel\u003E, or aria-label."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":".vibe/skills/claude-skills/engineering-team/a11y-audit/assets/sample-component.tsx"},"region":{"startLine":24}}}],"partialFingerprints":{"codehealthFindingId/v1":"bbb8bd9561196ea140e485aaa1fb5b4756c2de33b166f7ad9b2f711a6a8a927d"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Cinput\u003E without a programmatic label: This control has only a placeholder \u2014 a placeholder is not a label (it vanishes on input and many AT ignore it). Add a \u003Clabel htmlFor\u003E, a wrapping \u003Clabel\u003E, or aria-label."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/a11y-audit/skills/a11y-audit/assets/sample-component.tsx"},"region":{"startLine":16}}}],"partialFingerprints":{"codehealthFindingId/v1":"c85e806dd6eefd742471bd71cce38aa32c693a7f72f05bee7d8eb0a92f04b495"}},{"ruleId":"AC2","level":"error","message":{"text":"\u003Cinput\u003E without a programmatic label: This control has only a placeholder \u2014 a placeholder is not a label (it vanishes on input and many AT ignore it). Add a \u003Clabel htmlFor\u003E, a wrapping \u003Clabel\u003E, or aria-label."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/a11y-audit/skills/a11y-audit/assets/sample-component.tsx"},"region":{"startLine":24}}}],"partialFingerprints":{"codehealthFindingId/v1":"d27b9647bb04ea03cba46203c3958de740c24f73bc623c10443578f3259c9905"}},{"ruleId":"AC3","level":"warning","message":{"text":"Data table has no header cells: A \u003Ctable\u003E with data cells but no \u003Cth\u003E gives assistive technology no way to associate cells with their headers. Mark the header row/column cells as \u003Cth\u003E (with a scope)."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":".codex/skills/a11y-audit/assets/sample-component.tsx"},"region":{"startLine":34}}}],"partialFingerprints":{"codehealthFindingId/v1":"1893f596f39ba7152f212c68fe30245866b9ef304f337545ffd351b4ce2b8a70"}},{"ruleId":"AC3","level":"warning","message":{"text":"Page without a main landmark: No \u003Cmain\u003E (or role=\u0022main\u0022) means no \u0022skip to content\u0022 target and a weaker landmark map. Wrap the primary content in \u003Cmain\u003E."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":".codex/skills/md-review/assets/md_review_template.html"},"region":{"startLine":11}}}],"partialFingerprints":{"codehealthFindingId/v1":"885268d5a78bdba30ff69f7947b8d1b8a02a6f1ea0d097b1a360e1f5375fc51d"}},{"ruleId":"AC3","level":"warning","message":{"text":"Page without a main landmark: No \u003Cmain\u003E (or role=\u0022main\u0022) means no \u0022skip to content\u0022 target and a weaker landmark map. Wrap the primary content in \u003Cmain\u003E."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":".codex/skills/md-slides/assets/md_slides_template.html"},"region":{"startLine":11}}}],"partialFingerprints":{"codehealthFindingId/v1":"59e6237469daff7711fa64df60db3139926d734cdc4dd7b722e6bc2468ed523f"}},{"ruleId":"AC3","level":"warning","message":{"text":"Heading level jumps from h1 to h3: Skipping heading levels breaks the document outline assistive tech relies on. Don\u0027t jump levels \u2014 increase by at most one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":".codex/skills/md-slides/assets/md_slides_template.html"},"region":{"startLine":72}}}],"partialFingerprints":{"codehealthFindingId/v1":"c171513e9119c69f67e4c82e4c54d1ead90205822dc1f97e2c167ea8098b6c22"}},{"ruleId":"AC3","level":"warning","message":{"text":"Data table has no header cells: A \u003Ctable\u003E with data cells but no \u003Cth\u003E gives assistive technology no way to associate cells with their headers. Mark the header row/column cells as \u003Cth\u003E (with a scope)."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":".hermes/skills/claude-skills/engineering-team/a11y-audit/assets/sample-component.tsx"},"region":{"startLine":34}}}],"partialFingerprints":{"codehealthFindingId/v1":"de5c38feeb88502c5447179253b39d47c1a0bfefcc8e9a27734ea6e5b65472eb"}},{"ruleId":"AC3","level":"warning","message":{"text":"Page without a main landmark: No \u003Cmain\u003E (or role=\u0022main\u0022) means no \u0022skip to content\u0022 target and a weaker landmark map. Wrap the primary content in \u003Cmain\u003E."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":".hermes/skills/claude-skills/markdown-html/md-review/assets/md_review_template.html"},"region":{"startLine":11}}}],"partialFingerprints":{"codehealthFindingId/v1":"49e44c6a39951d01d1aa59f55d4a5bd7a5abe00aa430b7c46ebb6a471d7d7343"}},{"ruleId":"AC3","level":"warning","message":{"text":"Page without a main landmark: No \u003Cmain\u003E (or role=\u0022main\u0022) means no \u0022skip to content\u0022 target and a weaker landmark map. Wrap the primary content in \u003Cmain\u003E."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":".hermes/skills/claude-skills/markdown-html/md-slides/assets/md_slides_template.html"},"region":{"startLine":11}}}],"partialFingerprints":{"codehealthFindingId/v1":"912a79cba10e8b5afe94147323c664e00276ac516da83847733cf879813c115d"}},{"ruleId":"AC3","level":"warning","message":{"text":"Heading level jumps from h1 to h3: Skipping heading levels breaks the document outline assistive tech relies on. Don\u0027t jump levels \u2014 increase by at most one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":".hermes/skills/claude-skills/markdown-html/md-slides/assets/md_slides_template.html"},"region":{"startLine":72}}}],"partialFingerprints":{"codehealthFindingId/v1":"a20c177cedb19f047289809eee6008df46975d59ca4bc7583599363b1f04f69a"}},{"ruleId":"AC3","level":"warning","message":{"text":"Data table has no header cells: A \u003Ctable\u003E with data cells but no \u003Cth\u003E gives assistive technology no way to associate cells with their headers. Mark the header row/column cells as \u003Cth\u003E (with a scope)."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":".vibe/skills/claude-skills/engineering-team/a11y-audit/assets/sample-component.tsx"},"region":{"startLine":34}}}],"partialFingerprints":{"codehealthFindingId/v1":"fc6a935b5adceb5669376c8fed30171e40f53edeba1efe7cc2d217ee7baaee3a"}},{"ruleId":"AC3","level":"warning","message":{"text":"Page without a main landmark: No \u003Cmain\u003E (or role=\u0022main\u0022) means no \u0022skip to content\u0022 target and a weaker landmark map. Wrap the primary content in \u003Cmain\u003E."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":".vibe/skills/claude-skills/markdown-html/md-review/assets/md_review_template.html"},"region":{"startLine":11}}}],"partialFingerprints":{"codehealthFindingId/v1":"9fb4ab61ce1e9e3a57307b35bd11f3301d1fdfa403110ebea259f7bbbd373898"}},{"ruleId":"AC3","level":"warning","message":{"text":"Page without a main landmark: No \u003Cmain\u003E (or role=\u0022main\u0022) means no \u0022skip to content\u0022 target and a weaker landmark map. Wrap the primary content in \u003Cmain\u003E."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":".vibe/skills/claude-skills/markdown-html/md-slides/assets/md_slides_template.html"},"region":{"startLine":11}}}],"partialFingerprints":{"codehealthFindingId/v1":"570ec38304825375a437804267775699a59fce669d9eb0644462df9e183ae8ed"}},{"ruleId":"AC3","level":"warning","message":{"text":"Heading level jumps from h1 to h3: Skipping heading levels breaks the document outline assistive tech relies on. Don\u0027t jump levels \u2014 increase by at most one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":".vibe/skills/claude-skills/markdown-html/md-slides/assets/md_slides_template.html"},"region":{"startLine":72}}}],"partialFingerprints":{"codehealthFindingId/v1":"e5c179bb4bbdc8c8873ff4a9543cc02faf516742441067cab154c99b04226314"}},{"ruleId":"AC3","level":"warning","message":{"text":"Data table has no header cells: A \u003Ctable\u003E with data cells but no \u003Cth\u003E gives assistive technology no way to associate cells with their headers. Mark the header row/column cells as \u003Cth\u003E (with a scope)."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/a11y-audit/skills/a11y-audit/assets/sample-component.tsx"},"region":{"startLine":34}}}],"partialFingerprints":{"codehealthFindingId/v1":"57373cb719d58c2541358ff7c91dcccf7dd27cf83ad043b361713b3f3101de38"}},{"ruleId":"AC3","level":"warning","message":{"text":"Page without a main landmark: No \u003Cmain\u003E (or role=\u0022main\u0022) means no \u0022skip to content\u0022 target and a weaker landmark map. Wrap the primary content in \u003Cmain\u003E."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"markdown-html/skills/md-review/assets/md_review_template.html"},"region":{"startLine":11}}}],"partialFingerprints":{"codehealthFindingId/v1":"4b2a007070ccc35fbf7f86a2de4cc9f4dc233fdf9e3b035f6535d96320a8f660"}},{"ruleId":"AC3","level":"warning","message":{"text":"Page without a main landmark: No \u003Cmain\u003E (or role=\u0022main\u0022) means no \u0022skip to content\u0022 target and a weaker landmark map. Wrap the primary content in \u003Cmain\u003E."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"markdown-html/skills/md-slides/assets/md_slides_template.html"},"region":{"startLine":11}}}],"partialFingerprints":{"codehealthFindingId/v1":"eab3f212dd5a5ca3726e5b2b0d1650e5511ca86504c9b9c5d6f612a43a2bed6c"}},{"ruleId":"AC3","level":"warning","message":{"text":"Heading level jumps from h1 to h3: Skipping heading levels breaks the document outline assistive tech relies on. Don\u0027t jump levels \u2014 increase by at most one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"markdown-html/skills/md-slides/assets/md_slides_template.html"},"region":{"startLine":72}}}],"partialFingerprints":{"codehealthFindingId/v1":"749438d2261b233f92417ffbd868242226d675f6f3e1a4af1dadc16e7a708146"}},{"ruleId":"AC4","level":"error","message":{"text":"Click handler on a non-interactive \u003Cdiv\u003E: A click handler on a plain element isn\u0027t keyboard-operable. Use a \u003Cbutton\u003E, or add role \u002B tabIndex={0} \u002B a key handler."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":".codex/skills/a11y-audit/assets/sample-component.tsx"},"region":{"startLine":6}}}],"partialFingerprints":{"codehealthFindingId/v1":"0f0fa8bae734c8edc0c419a9550dfa703f9186f7a8ef2b9c8144116268d48a45"}},{"ruleId":"AC4","level":"error","message":{"text":"Click handler on a non-interactive \u003Cdiv\u003E: A click handler on a plain element isn\u0027t keyboard-operable. Use a \u003Cbutton\u003E, or add role \u002B tabIndex={0} \u002B a key handler."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":".codex/skills/a11y-audit/assets/sample-component.tsx"},"region":{"startLine":11}}}],"partialFingerprints":{"codehealthFindingId/v1":"4aaf7d414171b4f7b61f3f4ba25b14f958bebfe1fafa4ee5a41968823bc81672"}},{"ruleId":"AC4","level":"warning","message":{"text":"Positive tabindex (5): A positive tabindex forces a manual tab order that fights the DOM and is fragile. Use tabindex=\u00220\u0022 (or restructure the DOM)."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":".codex/skills/a11y-audit/assets/sample-component.tsx"},"region":{"startLine":25}}}],"partialFingerprints":{"codehealthFindingId/v1":"f16a26dd754c1f86b5c43492300dc7702b9205c6fc33c9c8d363d61bc58b469b"}},{"ruleId":"AC4","level":"warning","message":{"text":"Link used as a button (placeholder href): An \u003Ca href=\u0022#\u0022\u003E (or javascript:) with a click handler is a button dressed as a link \u2014 it announces the wrong role and stops working without JS. Use a \u003Cbutton\u003E for an action."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":".codex/skills/md-slides/assets/md_slides_template.html"},"region":{"startLine":84}}}],"partialFingerprints":{"codehealthFindingId/v1":"500ccadb42dd44ea4b9330627bbfa8d768c4b5c4f3b0a46428f38cd3aaeeb93a"}},{"ruleId":"AC4","level":"error","message":{"text":"Click handler on a non-interactive \u003Cdiv\u003E: A click handler on a plain element isn\u0027t keyboard-operable. Use a \u003Cbutton\u003E, or add role \u002B tabIndex={0} \u002B a key handler."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":".hermes/skills/claude-skills/engineering-team/a11y-audit/assets/sample-component.tsx"},"region":{"startLine":6}}}],"partialFingerprints":{"codehealthFindingId/v1":"96a4a2dfe61a7bfd941896acc99ab267232fe7bfd5e1f9d02539b4ce65f2d1b7"}},{"ruleId":"AC4","level":"error","message":{"text":"Click handler on a non-interactive \u003Cdiv\u003E: A click handler on a plain element isn\u0027t keyboard-operable. Use a \u003Cbutton\u003E, or add role \u002B tabIndex={0} \u002B a key handler."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":".hermes/skills/claude-skills/engineering-team/a11y-audit/assets/sample-component.tsx"},"region":{"startLine":11}}}],"partialFingerprints":{"codehealthFindingId/v1":"18a461c10380dcebf0017bb4b8b06062f18ebe343614409e72835bbbfec814e2"}},{"ruleId":"AC4","level":"warning","message":{"text":"Positive tabindex (5): A positive tabindex forces a manual tab order that fights the DOM and is fragile. Use tabindex=\u00220\u0022 (or restructure the DOM)."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":".hermes/skills/claude-skills/engineering-team/a11y-audit/assets/sample-component.tsx"},"region":{"startLine":25}}}],"partialFingerprints":{"codehealthFindingId/v1":"689ca1052721f3579f08b4b2a2ccafb10da31f0abe15f35b6abbdca5228ddd1a"}},{"ruleId":"AC4","level":"warning","message":{"text":"Link used as a button (placeholder href): An \u003Ca href=\u0022#\u0022\u003E (or javascript:) with a click handler is a button dressed as a link \u2014 it announces the wrong role and stops working without JS. Use a \u003Cbutton\u003E for an action."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":".hermes/skills/claude-skills/markdown-html/md-slides/assets/md_slides_template.html"},"region":{"startLine":84}}}],"partialFingerprints":{"codehealthFindingId/v1":"33872ac6d45d471b47f22d57c066f6536b72c96e30cf722bc418ec5c1c432c9b"}},{"ruleId":"AC4","level":"error","message":{"text":"Click handler on a non-interactive \u003Cdiv\u003E: A click handler on a plain element isn\u0027t keyboard-operable. Use a \u003Cbutton\u003E, or add role \u002B tabIndex={0} \u002B a key handler."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":".vibe/skills/claude-skills/engineering-team/a11y-audit/assets/sample-component.tsx"},"region":{"startLine":6}}}],"partialFingerprints":{"codehealthFindingId/v1":"aec480ff302b7a41489f459e55449f0f792ad775560f1860597d6f937b680c47"}},{"ruleId":"AC4","level":"error","message":{"text":"Click handler on a non-interactive \u003Cdiv\u003E: A click handler on a plain element isn\u0027t keyboard-operable. Use a \u003Cbutton\u003E, or add role \u002B tabIndex={0} \u002B a key handler."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":".vibe/skills/claude-skills/engineering-team/a11y-audit/assets/sample-component.tsx"},"region":{"startLine":11}}}],"partialFingerprints":{"codehealthFindingId/v1":"8871eda7344d2f0c58cfdbb8f2071033d7a8ab153661e36e2c8f71f6798e3b52"}},{"ruleId":"AC4","level":"warning","message":{"text":"Positive tabindex (5): A positive tabindex forces a manual tab order that fights the DOM and is fragile. Use tabindex=\u00220\u0022 (or restructure the DOM)."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":".vibe/skills/claude-skills/engineering-team/a11y-audit/assets/sample-component.tsx"},"region":{"startLine":25}}}],"partialFingerprints":{"codehealthFindingId/v1":"0cf5430f1a61b71ed67bf53753440ce5d3e625e3bcbecf9b250e20454e0ab5c0"}},{"ruleId":"AC4","level":"warning","message":{"text":"Link used as a button (placeholder href): An \u003Ca href=\u0022#\u0022\u003E (or javascript:) with a click handler is a button dressed as a link \u2014 it announces the wrong role and stops working without JS. Use a \u003Cbutton\u003E for an action."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":".vibe/skills/claude-skills/markdown-html/md-slides/assets/md_slides_template.html"},"region":{"startLine":84}}}],"partialFingerprints":{"codehealthFindingId/v1":"b9cd04e9d61d441b760c38175fe7d6da8526466e881f4d56514aa7c200149f67"}},{"ruleId":"AC4","level":"error","message":{"text":"Click handler on a non-interactive \u003Cdiv\u003E: A click handler on a plain element isn\u0027t keyboard-operable. Use a \u003Cbutton\u003E, or add role \u002B tabIndex={0} \u002B a key handler."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/a11y-audit/skills/a11y-audit/assets/sample-component.tsx"},"region":{"startLine":6}}}],"partialFingerprints":{"codehealthFindingId/v1":"f1ad201b91163c0830794a41012a2c35290771f69e5f632f212d2f0edafa7f90"}},{"ruleId":"AC4","level":"error","message":{"text":"Click handler on a non-interactive \u003Cdiv\u003E: A click handler on a plain element isn\u0027t keyboard-operable. Use a \u003Cbutton\u003E, or add role \u002B tabIndex={0} \u002B a key handler."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/a11y-audit/skills/a11y-audit/assets/sample-component.tsx"},"region":{"startLine":11}}}],"partialFingerprints":{"codehealthFindingId/v1":"0c400758f2316562f0e379eae8a5fc09020651322f1fcb073b9a90d94de58866"}},{"ruleId":"AC4","level":"warning","message":{"text":"Positive tabindex (5): A positive tabindex forces a manual tab order that fights the DOM and is fragile. Use tabindex=\u00220\u0022 (or restructure the DOM)."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/a11y-audit/skills/a11y-audit/assets/sample-component.tsx"},"region":{"startLine":25}}}],"partialFingerprints":{"codehealthFindingId/v1":"9bcd150e32ffc0e5c08d5815a00f6470fb43c712feda7c443ff47414f5de44a2"}},{"ruleId":"AC4","level":"warning","message":{"text":"Link used as a button (placeholder href): An \u003Ca href=\u0022#\u0022\u003E (or javascript:) with a click handler is a button dressed as a link \u2014 it announces the wrong role and stops working without JS. Use a \u003Cbutton\u003E for an action."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"markdown-html/skills/md-slides/assets/md_slides_template.html"},"region":{"startLine":84}}}],"partialFingerprints":{"codehealthFindingId/v1":"c9db9d7a0ff79c05103770f4c27a9616fc16bee6ec596bd9b81ba492d515d18b"}},{"ruleId":"AC6","level":"warning","message":{"text":"Animation without a prefers-reduced-motion guard: \u0060.md-typeset .md-button--primary\u0060 moves (\u0060transition: transform 0.12s ease, box-shadow 0.18s ease, filter 0.18s ease\u0060) and nothing reads prefers-reduced-motion for it \u2014 no @media (prefers-reduced-motion) rule for this element, no reset this project loads \u2014 so a motion-sensitive user cannot turn it off (WCAG 2.3.3). Declare it under @media (prefers-reduced-motion: no-preference), or neutralise it under reduce."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/stylesheets/extra.css"},"region":{"startLine":216}}}],"partialFingerprints":{"codehealthFindingId/v1":"7ff6e32b7c651a86042b1c62cb68786abf1f15364c134b5c80ef1183ed83558a"}},{"ruleId":"AC6","level":"warning","message":{"text":"Animation without a prefers-reduced-motion guard: \u0060.md-typeset .md-button:not(.md-button--primary)\u0060 moves (\u0060transition: background-color 0.15s ease, border-color 0.15s ease, transform 0.12s ease\u0060) and nothing reads prefers-reduced-motion for it \u2014 no @media (prefers-reduced-motion) rule for this element, no reset this project loads \u2014 so a motion-sensitive user cannot turn it off (WCAG 2.3.3). Declare it under @media (prefers-reduced-motion: no-preference), or neutralise it under reduce."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/stylesheets/extra.css"},"region":{"startLine":245}}}],"partialFingerprints":{"codehealthFindingId/v1":"332eeaee938477cdfedebe3012849b4a1ba9dfba376af13a6579a39bab1a043f"}},{"ruleId":"AC7","level":"warning","message":{"text":"Accessibility enforcement below the top rung: No accessibility enforcement found \u2014 no automated accessibility check runs over the HTML your app renders. Assert the accessibility invariants over that HTML in the test suite you already have (parse the output and assert, or drive a browser), and gate that test in CI so a regression blocks the merge. What was searched, so you can tell an absence from a miss: the 21 markup file(s) this pass actually assessed, the linter configuration checked in beside them, and this repository\u0027s test and CI files \u2014 matched by name against the accessibility checkers this dimension carries. An audit run outside the repository, a hosted scanner, or a check whose name is not one of those, is not seen here."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"d46019b86eff5ddad9db289e6802ac158899e980df54c34f67722442787ead62"}},{"ruleId":"IC1","level":"warning","message":{"text":"Fake-async \u2014 async method never awaits: \u0060HandleClick\u0060 is declared \u0060async\u0060 but never awaits anything, so it runs synchronously while pretending to be asynchronous. Drop \u0060async\u0060 or do the real async work."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/skills/code-reviewer/assets/sample_csharp_smells.cs"},"region":{"startLine":25}}}],"partialFingerprints":{"codehealthFindingId/v1":"320458b57fa8715212e0d80e96c870caabe0b24dcbb5f1c0a093d3ef83b7d1af"}},{"ruleId":"M2","level":"note","message":{"text":"ADRs not easily discoverable: 35 ADR-shaped document(s) detected by content \u2014 \u0060.codex/skills/cdo-review/SKILL.md\u0060, \u0060.codex/skills/chief-ai-officer-advisor/references/ai_cost_economics.md\u0060, \u0060.codex/skills/chief-ai-officer-advisor/references/ai_risk_governance.md\u0060, \u0060.codex/skills/chief-ai-officer-advisor/references/ai_team_org_evolution.md\u0060, \u0060.codex/skills/chief-ai-officer-advisor/references/model_buildvsbuy_strategy.md\u0060, \u0060.codex/skills/chief-customer-officer-advisor/references/cs_coverage_model.md\u0060, \u0060.codex/skills/chief-customer-officer-advisor/references/cs_team_org_evolution.md\u0060, \u0060.codex/skills/chief-customer-officer-advisor/references/customer_segmentation_strategy.md\u0060, \u0060.codex/skills/chief-customer-officer-advisor/references/retention_decomposition.md\u0060, \u0060.codex/skills/chief-data-officer-advisor/references/ai_training_data_rights.md\u0060, \u0060.codex/skills/chief-data-officer-advisor/references/customer_data_as_asset.md\u0060, \u0060.codex/skills/chief-data-officer-advisor/references/data_product_strategy.md\u0060, \u0060.codex/skills/chief-data-officer-advisor/references/data_team_org_evolution.md\u0060, \u0060.codex/skills/chief-of-staff/SKILL.md\u0060, \u0060.codex/skills/collab-proof/references/session-documentation-patterns.md\u0060, \u0060.codex/skills/confluence-expert/references/templates.md\u0060, \u0060.codex/skills/cto-advisor/references/architecture_decision_records.md\u0060, \u0060.codex/skills/decide/SKILL.md\u0060, \u0060.codex/skills/freeze/SKILL.md\u0060, \u0060.codex/skills/tech-debt-tracker/references/stakeholder-communication-templates.md\u0060, \u0060.codex/skills/vpe-advisor/references/delivery_throughput.md\u0060, \u0060.codex/skills/vpe-advisor/references/eng_team_structure.md\u0060, \u0060.codex/skills/vpe-advisor/references/engineering_hiring_funnel.md\u0060, \u0060.codex/skills/vpe-advisor/references/production_discipline.md\u0060, \u0060compliance-os/agents/cs-fda-qsr-auditor.md\u0060, \u0060docs/agents/cs-fda-qsr-auditor.md\u0060, \u0060docs/agents/cs-handoff-author.md\u0060, \u0060docs/agents/hub-coordinator.md\u0060, \u0060docs/skills/c-level-advisor/c-level-agents-cdo-review.md\u0060, \u0060docs/skills/c-level-advisor/c-level-agents-decide.md\u0060, \u0060docs/skills/c-level-advisor/c-level-agents-freeze.md\u0060, \u0060docs/skills/c-level-advisor/chief-of-staff.md\u0060, \u0060engineering/agenthub/agents/hub-coordinator.md\u0060, \u0060engineering/handoff/agents/cs-handoff-author.md\u0060, \u0060standards/documentation/documentation-standards.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":"M4","level":"note","message":{"text":"README/code drift: INSTALLATION.md names \u0060.github/skills/\u0060, but no file or folder \u0060.github/skills\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"INSTALLATION.md"},"region":{"startLine":193}}}],"partialFingerprints":{"codehealthFindingId/v1":"ca6b928600a1beb56768992ba5b4beeae5f2a6385ebfcfafb6ddbe09386a8966"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: README.md links to \u0060Hermes\u0060, but \u0060Hermes\u0060 does not exist. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"README.md"},"region":{"startLine":9}}}],"partialFingerprints":{"codehealthFindingId/v1":"7a3e7c3f932c8a2faeacccc07f6d2f699e405f2bd11577b2dc665f9c2824fba1"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: README.md links to \u0060Mistral\u0060, but \u0060Mistral\u0060 does not exist. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"README.md"},"region":{"startLine":10}}}],"partialFingerprints":{"codehealthFindingId/v1":"4cc1af29360f046244f0c6e286a2e0ec723e8a08bb11ce3ac7c1762acfdfc505"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: README.md names \u0060engineering/git-worktree-manager\u0060, but no file or folder \u0060engineering/git-worktree-manager\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"README.md"},"region":{"startLine":280}}}],"partialFingerprints":{"codehealthFindingId/v1":"1205afb8134b84629c77a62408999a976b8b1d54d14fd8ba3be9e804d6cceb03"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: README.md names \u0060engineering/mcp-server-builder\u0060, but no file or folder \u0060engineering/mcp-server-builder\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"README.md"},"region":{"startLine":281}}}],"partialFingerprints":{"codehealthFindingId/v1":"316c99daf6d1a88c605fe9483e307e972cadc415ce0ebb1e0e95abd044819df4"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: README.md names \u0060engineering/changelog-generator\u0060, but no file or folder \u0060engineering/changelog-generator\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"README.md"},"region":{"startLine":282}}}],"partialFingerprints":{"codehealthFindingId/v1":"c063e96dfbf23deff6a5c539b69681ddadf27954cea06f99dbf747605c6aa968"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: README.md names \u0060engineering/ci-cd-pipeline-builder\u0060, but no file or folder \u0060engineering/ci-cd-pipeline-builder\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"README.md"},"region":{"startLine":283}}}],"partialFingerprints":{"codehealthFindingId/v1":"9aca915c861a7e9c4cb50272bf99bb264a3cbc85f89639398520c0df4afd6495"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: README.md names \u0060marketing-skill/prompt-engineer-toolkit\u0060, but no file or folder \u0060marketing-skill/prompt-engineer-toolkit\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"README.md"},"region":{"startLine":284}}}],"partialFingerprints":{"codehealthFindingId/v1":"f59df7ad87ba4d2b7facc99950afd5cdbe895cfaa2afa8fac6196b0620e02967"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: business-operations/README.md names \u0060c-level-advisor/coo-advisor\u0060, but no file or folder \u0060c-level-advisor/coo-advisor\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"business-operations/README.md"},"region":{"startLine":32}}}],"partialFingerprints":{"codehealthFindingId/v1":"04b6772e39d3b0ec5ac30f00815916a036f10b41f8620522596f56e2227031d6"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: business-operations/README.md names \u0060engineering-team/runbook-generator\u0060, but no file or folder \u0060engineering-team/runbook-generator\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"business-operations/README.md"},"region":{"startLine":36}}}],"partialFingerprints":{"codehealthFindingId/v1":"fe825f1ce0723334110ddc62db4269d0cb24c732b3f9a3888783dd6e7c8d6621"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: commercial/README.md names \u0060business-growth/sales-engineer\u0060, but no file or folder \u0060business-growth/sales-engineer\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"commercial/README.md"},"region":{"startLine":32}}}],"partialFingerprints":{"codehealthFindingId/v1":"4c191871f6a1ebd28377081a07e2a7449cdab84084ab50cea4e9e775364ce275"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: commercial/README.md names \u0060business-growth/revenue-operations\u0060, but no file or folder \u0060business-growth/revenue-operations\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"commercial/README.md"},"region":{"startLine":33}}}],"partialFingerprints":{"codehealthFindingId/v1":"0a477d1a732fc5d0742ccf7e910f940b3dff1711a16714a2c02b5f8a2acbddb9"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: commercial/README.md names \u0060business-growth/contract-and-proposal-writer\u0060, but no file or folder \u0060business-growth/contract-and-proposal-writer\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"commercial/README.md"},"region":{"startLine":34}}}],"partialFingerprints":{"codehealthFindingId/v1":"580815592cbecaed89c520443dfdb7395e266b77dbd5c9ad217fbf1ba3059fda"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: commercial/README.md names \u0060c-level-advisor/cro-advisor\u0060, but no file or folder \u0060c-level-advisor/cro-advisor\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"commercial/README.md"},"region":{"startLine":35}}}],"partialFingerprints":{"codehealthFindingId/v1":"d604ecd7b64f341815d9d0759ab9d8510ac1c3875dc2a09ef6dc09d74dbe8fa9"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: commercial/README.md names \u0060c-level-advisor/cfo-advisor\u0060, but no file or folder \u0060c-level-advisor/cfo-advisor\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"commercial/README.md"},"region":{"startLine":36}}}],"partialFingerprints":{"codehealthFindingId/v1":"ba333eccd6e92e2492aa7be7e21c32f0370ce05644e31b2dd58a9e09eb250169"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: commercial/README.md names \u0060finance/financial-analysis\u0060, but no file or folder \u0060finance/financial-analysis\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"commercial/README.md"},"region":{"startLine":37}}}],"partialFingerprints":{"codehealthFindingId/v1":"589ec6fa528934acc801d98b3d3e97638a38842117f4844cc9a017bde27e7fc3"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/integrations.md documents the environment variable \u0060OPENCODE_DISABLE_CLAUDE_CODE_SKILLS\u0060, but no code, script or configuration file names it. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/integrations.md"},"region":{"startLine":434}}}],"partialFingerprints":{"codehealthFindingId/v1":"6227c37632e46e75e100ee7742ed7874c4331eba548ebb0faec48b20a989bfe3"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/integrations.md documents the environment variable \u0060NOUS_API_KEY\u0060, but no code, script or configuration file names it. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/integrations.md"},"region":{"startLine":595}}}],"partialFingerprints":{"codehealthFindingId/v1":"9436ef6ebb7487ac293b7ed9332896f7687ba7517d7627397c7c22c91f312966"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/integrations.md documents the environment variable \u0060MISTRAL_API_KEY\u0060, but no code, script or configuration file names it. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/integrations.md"},"region":{"startLine":799}}}],"partialFingerprints":{"codehealthFindingId/v1":"5d1912b4f04ab759a6126f8a4997ab3129b70170cb41cd150d7e3bac365f4c1c"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: engineering-team/README.md names \u0060code_review_checklist.md\u0060, but no file or folder \u0060code_review_checklist.md\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/README.md"},"region":{"startLine":310}}}],"partialFingerprints":{"codehealthFindingId/v1":"ebb143a7c7e864dcea92e5fdd87cf9f1cef4c8920fd59537e42c1ceca918050a"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: engineering-team/README.md names \u0060coding_standards.md\u0060, but no file or folder \u0060coding_standards.md\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/README.md"},"region":{"startLine":311}}}],"partialFingerprints":{"codehealthFindingId/v1":"c8302fce6d0a6302b10a25f15b6fed1f4cb0d380241c3928eae1259348e81d1a"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: engineering-team/README.md names \u0060common_antipatterns.md\u0060, but no file or folder \u0060common_antipatterns.md\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/README.md"},"region":{"startLine":312}}}],"partialFingerprints":{"codehealthFindingId/v1":"0f31b4acd0a7b2df3bfcb3639bfbb54041df2fce59a397db2d1195e2b2554591"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: engineering-team/README.md names \u0060security_auditor.py\u0060, but no file or folder \u0060security_auditor.py\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/README.md"},"region":{"startLine":336}}}],"partialFingerprints":{"codehealthFindingId/v1":"d875aa836e9e6c5cbf67fda287927db3774eab18531cf759060181d1b69f9ceb"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: engineering-team/README.md names \u0060pentest_automator.py\u0060, but no file or folder \u0060pentest_automator.py\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/README.md"},"region":{"startLine":337}}}],"partialFingerprints":{"codehealthFindingId/v1":"bccc96896c131459fe1c29eabfb8e6e10cd6ecc2ef93f1af4a7a8c217651f59d"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: engineering-team/README.md names \u0060security_architecture_patterns.md\u0060, but no file or folder \u0060security_architecture_patterns.md\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/README.md"},"region":{"startLine":340}}}],"partialFingerprints":{"codehealthFindingId/v1":"19003842507045a66d5f0014cf271ad47186089a7092e3f90ce1814eb59c9730"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: engineering-team/README.md names \u0060penetration_testing_guide.md\u0060, but no file or folder \u0060penetration_testing_guide.md\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/README.md"},"region":{"startLine":341}}}],"partialFingerprints":{"codehealthFindingId/v1":"dda2db24a32e47dd7d88d61c04b2f8e17186a8d17c0308a94def08fcb067128f"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: engineering-team/README.md names \u0060cryptography_implementation.md\u0060, but no file or folder \u0060cryptography_implementation.md\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/README.md"},"region":{"startLine":342}}}],"partialFingerprints":{"codehealthFindingId/v1":"64db3ca827bbb926fa85f27e22fb9d6f29333772de9bf07494c114dadaf06625"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: engineering-team/README.md names Node.js 20, but the repository declares engines \u0060\u003E=16.0.0\u0060. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/README.md"},"region":{"startLine":472}}}],"partialFingerprints":{"codehealthFindingId/v1":"31eaa97c0c7c4142ae923741673eceee1341eab82406a2f7837786d41d53cfa5"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: loop-library/README.md names \u0060skills/loop-library/\u0060, but no file or folder \u0060skills/loop-library\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"loop-library/README.md"},"region":{"startLine":5}}}],"partialFingerprints":{"codehealthFindingId/v1":"5e85ca1528ec74c9299ee8464b123175b76f47dbfad74516f78e1e87521440e4"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: marketing-skill/README.md links to \u0060content-creator/SKILL.md\u0060, but \u0060marketing-skill/content-creator/SKILL.md\u0060 does not exist. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"marketing-skill/README.md"},"region":{"startLine":130}}}],"partialFingerprints":{"codehealthFindingId/v1":"aeb7af4682394a2d0c92e9902d6a0937441f5e13d80a408850d58cc61b6f261a"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: marketing-skill/README.md links to \u0060marketing-demand-acquisition/SKILL.md\u0060, but \u0060marketing-skill/marketing-demand-acquisition/SKILL.md\u0060 does not exist. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"marketing-skill/README.md"},"region":{"startLine":183}}}],"partialFingerprints":{"codehealthFindingId/v1":"b9fb93fd07312b4bfe3b01003c3078eafcae0bbcee85f2befd7a337033a8a0a9"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: marketing-skill/README.md links to \u0060marketing-strategy-pmm/SKILL.md\u0060, but \u0060marketing-skill/marketing-strategy-pmm/SKILL.md\u0060 does not exist. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"marketing-skill/README.md"},"region":{"startLine":230}}}],"partialFingerprints":{"codehealthFindingId/v1":"930bcaf4f62f0aed196a470af09f76edf0e76b6495d4370ee2c272fc56ff9c4e"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: project-management/README.md links to \u0060scrum-master/SKILL.md\u0060, but \u0060project-management/scrum-master/SKILL.md\u0060 does not exist. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"project-management/README.md"},"region":{"startLine":134}}}],"partialFingerprints":{"codehealthFindingId/v1":"3edd66a7b54f7498033010f61577acbf72d8342d4cafdc1f524e338587825b0f"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: ra-qm-team/README.md names \u0060submission_timeline_tracker.py\u0060, but no file or folder \u0060submission_timeline_tracker.py\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"ra-qm-team/README.md"},"region":{"startLine":132}}}],"partialFingerprints":{"codehealthFindingId/v1":"7d5becb8bb87e9e002a5384317285fddaaeea16eece4c96fa24dadc5ea220dc4"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: ra-qm-team/README.md names \u0060regulatory_intelligence_monitor.py\u0060, but no file or folder \u0060regulatory_intelligence_monitor.py\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"ra-qm-team/README.md"},"region":{"startLine":133}}}],"partialFingerprints":{"codehealthFindingId/v1":"7a8e0425d6f7df0aaebe403649ed79084f74e5092abee17b323b1b1482074907"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: ra-qm-team/README.md names \u0060qms_effectiveness_monitor.py\u0060, but no file or folder \u0060qms_effectiveness_monitor.py\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"ra-qm-team/README.md"},"region":{"startLine":160}}}],"partialFingerprints":{"codehealthFindingId/v1":"00216167fc1de2fa4095a127012a2e32112bc930864d5372b1543a98c8d4011f"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: ra-qm-team/README.md names \u0060management_review_analyzer.py\u0060, but no file or folder \u0060management_review_analyzer.py\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"ra-qm-team/README.md"},"region":{"startLine":162}}}],"partialFingerprints":{"codehealthFindingId/v1":"6b1eb6f3fec1511f3b3ba1a3884e713ca9ec47cc378198c65622f1d6994583bc"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: ra-qm-team/README.md names \u0060qmr-responsibilities.md\u0060, but no file or folder \u0060qmr-responsibilities.md\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"ra-qm-team/README.md"},"region":{"startLine":165}}}],"partialFingerprints":{"codehealthFindingId/v1":"65a09718c064d3194a274c76b40c5ca38cd025d804a25f3940800bca61ce9a96"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: ra-qm-team/README.md names \u0060quality-leadership-framework.md\u0060, but no file or folder \u0060quality-leadership-framework.md\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"ra-qm-team/README.md"},"region":{"startLine":166}}}],"partialFingerprints":{"codehealthFindingId/v1":"4837380eb9feb7cc2245e6201b295d38ad885f6fdf39484d0c4e966d402af417"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: ra-qm-team/README.md names \u0060qms_compliance_checker.py\u0060, but no file or folder \u0060qms_compliance_checker.py\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"ra-qm-team/README.md"},"region":{"startLine":189}}}],"partialFingerprints":{"codehealthFindingId/v1":"174a3f5faad3dc903703bd08bb976b877acd857aa17976be6d118dd79a3ba0d4"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: ra-qm-team/README.md names \u0060design_control_tracker.py\u0060, but no file or folder \u0060design_control_tracker.py\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"ra-qm-team/README.md"},"region":{"startLine":190}}}],"partialFingerprints":{"codehealthFindingId/v1":"82983bac4580d74d37e775c0f65a629e459a2b5ec5b9da85ba5835d3fcb0b86a"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: ra-qm-team/README.md names \u0060document_control_system.py\u0060, but no file or folder \u0060document_control_system.py\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"ra-qm-team/README.md"},"region":{"startLine":191}}}],"partialFingerprints":{"codehealthFindingId/v1":"1d04e3eb4ce5e199562bac0ebe6601f76c951f32687260f453f80b895b971ff3"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: ra-qm-team/README.md names \u0060iso-13485-implementation.md\u0060, but no file or folder \u0060iso-13485-implementation.md\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"ra-qm-team/README.md"},"region":{"startLine":194}}}],"partialFingerprints":{"codehealthFindingId/v1":"d93e99ea4367fbd75088691a87cad697697d6930422593347b0130636226b48f"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: ra-qm-team/README.md names \u0060design-controls-handbook.md\u0060, but no file or folder \u0060design-controls-handbook.md\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"ra-qm-team/README.md"},"region":{"startLine":195}}}],"partialFingerprints":{"codehealthFindingId/v1":"0160c6ed56b538607375b63a102f923bd27b95da1174f1e33dbc26d079c4d379"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: ra-qm-team/README.md names \u0060internal-audit-program.md\u0060, but no file or folder \u0060internal-audit-program.md\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"ra-qm-team/README.md"},"region":{"startLine":196}}}],"partialFingerprints":{"codehealthFindingId/v1":"4d04ac9dd96995f0e909a7145397a298bbce5c86bb10589d723f184b9d332b23"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: ra-qm-team/README.md names \u0060trend_analysis_tool.py\u0060, but no file or folder \u0060trend_analysis_tool.py\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"ra-qm-team/README.md"},"region":{"startLine":220}}}],"partialFingerprints":{"codehealthFindingId/v1":"55f71f8678b011b0c5ec402da0472dde251f316bafd70e1c05587915caf64be5"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: ra-qm-team/README.md names \u0060capa-process-guide.md\u0060, but no file or folder \u0060capa-process-guide.md\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"ra-qm-team/README.md"},"region":{"startLine":223}}}],"partialFingerprints":{"codehealthFindingId/v1":"283c518617dcf4dc882362b9bc2cc301ef177ae4615dbfb6fe17add007520115"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: ra-qm-team/README.md names \u0060root-cause-analysis-methods.md\u0060, but no file or folder \u0060root-cause-analysis-methods.md\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"ra-qm-team/README.md"},"region":{"startLine":224}}}],"partialFingerprints":{"codehealthFindingId/v1":"c30525ac831bd3185b55d9eeca8e01a710347d0060a2d992a3f1ad9a1bd465b3"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: ra-qm-team/README.md names \u0060effectiveness-verification.md\u0060, but no file or folder \u0060effectiveness-verification.md\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"ra-qm-team/README.md"},"region":{"startLine":225}}}],"partialFingerprints":{"codehealthFindingId/v1":"b4a2427667d22c46fcced128c50cecbf13e8715fbc1a00ab658674d71c160565"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: ra-qm-team/README.md names \u0060technical_file_builder.py\u0060, but no file or folder \u0060technical_file_builder.py\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"ra-qm-team/README.md"},"region":{"startLine":248}}}],"partialFingerprints":{"codehealthFindingId/v1":"9bd5f91bbe846de2290d7842eb8f22ae4eaf9067a03b5cf0e483ad9236c671e1"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: ra-qm-team/README.md names \u0060document_compliance_checker.py\u0060, but no file or folder \u0060document_compliance_checker.py\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"ra-qm-team/README.md"},"region":{"startLine":249}}}],"partialFingerprints":{"codehealthFindingId/v1":"101f1d931ef710c50c37296231eae182d1fed32b6f6697b84aad08c220794d82"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: ra-qm-team/README.md names \u0060technical-file-requirements.md\u0060, but no file or folder \u0060technical-file-requirements.md\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"ra-qm-team/README.md"},"region":{"startLine":253}}}],"partialFingerprints":{"codehealthFindingId/v1":"21c64884eacdb57fb1ee6e378f4089393eda1bf67317cba6b1955a99084bcc7c"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: ra-qm-team/README.md names \u0060change-control-process.md\u0060, but no file or folder \u0060change-control-process.md\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"ra-qm-team/README.md"},"region":{"startLine":254}}}],"partialFingerprints":{"codehealthFindingId/v1":"e57abd048fd1666d85d756f12f4afdf34f83925c09faeec0050ef9438d92106e"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: ra-qm-team/README.md names \u0060risk_register_manager.py\u0060, but no file or folder \u0060risk_register_manager.py\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"ra-qm-team/README.md"},"region":{"startLine":276}}}],"partialFingerprints":{"codehealthFindingId/v1":"a90c56842c39512703f8283ae605caa11728fd7d5491d07e6055330891f3b706"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: ra-qm-team/README.md names \u0060fmea_calculator.py\u0060, but no file or folder \u0060fmea_calculator.py\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"ra-qm-team/README.md"},"region":{"startLine":277}}}],"partialFingerprints":{"codehealthFindingId/v1":"e57f07d353a027733d584def1c2e88a8c685b17d0371a2393c22ecd0ae7664c1"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: ra-qm-team/README.md names \u0060risk_control_tracker.py\u0060, but no file or folder \u0060risk_control_tracker.py\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"ra-qm-team/README.md"},"region":{"startLine":278}}}],"partialFingerprints":{"codehealthFindingId/v1":"36c7691d03eb8d913998592cea05b5fbebc7762f40c750fc3d70aa4181a0f835"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: ra-qm-team/README.md names \u0060iso-14971-implementation.md\u0060, but no file or folder \u0060iso-14971-implementation.md\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"ra-qm-team/README.md"},"region":{"startLine":281}}}],"partialFingerprints":{"codehealthFindingId/v1":"7d12c3398e2dcf69cdb73363f094464c3a21513a3f6a54f76a4181ebb40a0506"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: ra-qm-team/README.md names \u0060post-production-monitoring.md\u0060, but no file or folder \u0060post-production-monitoring.md\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"ra-qm-team/README.md"},"region":{"startLine":283}}}],"partialFingerprints":{"codehealthFindingId/v1":"9718384214b675d888341c2c0daa10396e2b54f66215cc69ceffd932e0f50f04"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/agents/cs-agent-deployer.md names \u0060NEXT-DIRECTIONS.md\u0060, but no file or folder \u0060NEXT-DIRECTIONS.md\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/agents/cs-agent-deployer.md"},"region":{"startLine":34}}}],"partialFingerprints":{"codehealthFindingId/v1":"4524e8b50988b234b257e4c4bb20da8e05484a6ffcd48e993b17677448f75873"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/agents/cs-backend-engineer.md names \u0060engineering-team/senior-backend\u0060, but no file or folder \u0060engineering-team/senior-backend\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/agents/cs-backend-engineer.md"},"region":{"startLine":136}}}],"partialFingerprints":{"codehealthFindingId/v1":"4e1aefdc5df5255f834b5b83d63744f3c58f1e725c519c114cb093943e398808"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/agents/cs-book-to-skill.md documents the environment variable \u0060BOOK_TYPE\u0060, but no code, script or configuration file names it. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/agents/cs-book-to-skill.md"},"region":{"startLine":34}}}],"partialFingerprints":{"codehealthFindingId/v1":"fe00ec5203a97df0f345a6abbd0969e7e271b057d2139113745e580d0258d788"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/agents/cs-chief-of-staff.md names \u0060routing_logic.md\u0060, but no file or folder \u0060routing_logic.md\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/agents/cs-chief-of-staff.md"},"region":{"startLine":52}}}],"partialFingerprints":{"codehealthFindingId/v1":"255fdd3c206e4648900d5f2a5fccdd5748a45683e22a88f7ebe6105628dd49d0"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/agents/cs-chro-advisor.md names \u0060comp_philosophy.md\u0060, but no file or folder \u0060comp_philosophy.md\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/agents/cs-chro-advisor.md"},"region":{"startLine":69}}}],"partialFingerprints":{"codehealthFindingId/v1":"e19e0b2bed0a954f02205ba5eaa3729d50e385e367f5dbb1a83ee14673a2db9d"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/agents/cs-chro-advisor.md names \u0060leveling_ladders.md\u0060, but no file or folder \u0060leveling_ladders.md\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/agents/cs-chro-advisor.md"},"region":{"startLine":77}}}],"partialFingerprints":{"codehealthFindingId/v1":"eb90e8d969e7a09f63558c908df5d57b38c85f85a02b281fa042edff42af8a75"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/agents/cs-ciso-advisor.md names \u0060threat_modeling.md\u0060, but no file or folder \u0060threat_modeling.md\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/agents/cs-ciso-advisor.md"},"region":{"startLine":59}}}],"partialFingerprints":{"codehealthFindingId/v1":"f3273b619107af8e92aa9225d18778a820c8a37d99bdef57ff0b4872c247ae9f"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/agents/cs-cmo-advisor.md names \u0060growth_playbooks.md\u0060, but no file or folder \u0060growth_playbooks.md\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/agents/cs-cmo-advisor.md"},"region":{"startLine":70}}}],"partialFingerprints":{"codehealthFindingId/v1":"6d7d75ba496aa04bd893316dca7d797b6cc9b6efb148ae34db33e9d827e79be6"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/agents/cs-coo-advisor.md names \u0060operating_cadence.md\u0060, but no file or folder \u0060operating_cadence.md\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/agents/cs-coo-advisor.md"},"region":{"startLine":61}}}],"partialFingerprints":{"codehealthFindingId/v1":"cb6b04be11b089b075547fab21f9853bdac6167a104f70952d8620d0d5bdd05d"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/agents/cs-coo-advisor.md names \u0060okr_execution.md\u0060, but no file or folder \u0060okr_execution.md\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/agents/cs-coo-advisor.md"},"region":{"startLine":70}}}],"partialFingerprints":{"codehealthFindingId/v1":"2b3464f961841fb67e6e7046ac36729dbed1f3ad2ae382ab67c0b0ad1d0229b7"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/agents/cs-coo-advisor.md names \u0060scaling_playbooks.md\u0060, but no file or folder \u0060scaling_playbooks.md\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/agents/cs-coo-advisor.md"},"region":{"startLine":83}}}],"partialFingerprints":{"codehealthFindingId/v1":"63630c9b8d8164dbc266d57fc5cef0b3d65ba2b24d2879852dd174302857b439"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/agents/cs-cpo-advisor.md names \u0060pmf_framework.md\u0060, but no file or folder \u0060pmf_framework.md\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/agents/cs-cpo-advisor.md"},"region":{"startLine":60}}}],"partialFingerprints":{"codehealthFindingId/v1":"751c7dd47450b81bfc97995b9f70e474ea44b9910c8b22b59eb8441027b74f09"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/agents/cs-cpo-advisor.md names \u0060product_vision.md\u0060, but no file or folder \u0060product_vision.md\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/agents/cs-cpo-advisor.md"},"region":{"startLine":81}}}],"partialFingerprints":{"codehealthFindingId/v1":"43efe58addcac02672e3fb3c4e5680b7fb2edcbdf93a898554e50e807a49e114"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/agents/cs-cro-advisor.md names \u0060retention_expansion.md\u0060, but no file or folder \u0060retention_expansion.md\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/agents/cs-cro-advisor.md"},"region":{"startLine":69}}}],"partialFingerprints":{"codehealthFindingId/v1":"4c068d799e4494a23d8eb823c86bef319b507375430b7d4a8460980367ac78ce"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/agents/cs-cro-advisor.md names \u0060sales_motion.md\u0060, but no file or folder \u0060sales_motion.md\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/agents/cs-cro-advisor.md"},"region":{"startLine":78}}}],"partialFingerprints":{"codehealthFindingId/v1":"dcf8c7d8d65ededbd32abcaf2bbff77b9130870e5b1f3c7c1b5fb5595d432d37"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/agents/cs-deep-research.md names \u0060plan.md\u0060, but no file or folder \u0060plan.md\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/agents/cs-deep-research.md"},"region":{"startLine":28}}}],"partialFingerprints":{"codehealthFindingId/v1":"bcf796fbe13018c0d2cd7621762808343c75105c97637cfd164a38f2d6b9b1a9"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/agents/cs-deep-research.md names \u0060refresh_targets.md\u0060, but no file or folder \u0060refresh_targets.md\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/agents/cs-deep-research.md"},"region":{"startLine":33}}}],"partialFingerprints":{"codehealthFindingId/v1":"ccb65dc1054beaea2e99ffbfc7efbde20100262855ae76862f46901e39883ce1"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/agents/cs-engineering-lead.md names \u0060engineering-team/senior-frontend\u0060, but no file or folder \u0060engineering-team/senior-frontend\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/agents/cs-engineering-lead.md"},"region":{"startLine":22}}}],"partialFingerprints":{"codehealthFindingId/v1":"422c36bd8551bf52afda4406344ad2323921ed49ea2389ed58f6652a5fc24aae"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/agents/cs-engineering-lead.md names \u0060engineering-team/senior-backend\u0060, but no file or folder \u0060engineering-team/senior-backend\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/agents/cs-engineering-lead.md"},"region":{"startLine":23}}}],"partialFingerprints":{"codehealthFindingId/v1":"5a08cd18b12443cdd7b66ed1b39d11b28f72630b687e6340856e8696e5f19a30"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/agents/cs-engineering-lead.md names \u0060engineering-team/senior-fullstack\u0060, but no file or folder \u0060engineering-team/senior-fullstack\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/agents/cs-engineering-lead.md"},"region":{"startLine":24}}}],"partialFingerprints":{"codehealthFindingId/v1":"93d7bcb4dec25ba3fa1174158a1e970ae141557c5854af3458e47d76220b375c"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/agents/cs-engineering-lead.md names \u0060engineering-team/senior-qa\u0060, but no file or folder \u0060engineering-team/senior-qa\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/agents/cs-engineering-lead.md"},"region":{"startLine":27}}}],"partialFingerprints":{"codehealthFindingId/v1":"5d55390be8305c9a4305dcdd6b766c89b01cb532975fba3919296fb2d1b88a14"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/agents/cs-engineering-lead.md names \u0060engineering-team/tdd-guide\u0060, but no file or folder \u0060engineering-team/tdd-guide\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/agents/cs-engineering-lead.md"},"region":{"startLine":29}}}],"partialFingerprints":{"codehealthFindingId/v1":"7d5d1d29b31f9378f9799724976cc1c3e5c5fb8c46ce48fffdf9553e2fab0913"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/agents/cs-engineering-lead.md names \u0060engineering-team/senior-security\u0060, but no file or folder \u0060engineering-team/senior-security\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/agents/cs-engineering-lead.md"},"region":{"startLine":30}}}],"partialFingerprints":{"codehealthFindingId/v1":"97f12bd9f9f707506883d9546c237dc62d4af87c9a3c829a54ffa2a61e3a029e"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/agents/cs-engineering-lead.md names \u0060engineering-team/senior-secops\u0060, but no file or folder \u0060engineering-team/senior-secops\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/agents/cs-engineering-lead.md"},"region":{"startLine":31}}}],"partialFingerprints":{"codehealthFindingId/v1":"c80b58915b50b9aed0075140a1e5dc01b0bd933a523582dddfd36a2cb7820647"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/agents/cs-engineering-lead.md names \u0060engineering-team/senior-data-engineer\u0060, but no file or folder \u0060engineering-team/senior-data-engineer\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/agents/cs-engineering-lead.md"},"region":{"startLine":34}}}],"partialFingerprints":{"codehealthFindingId/v1":"44763b72b9b47a65081257d29a1b7473b094da607056455e82ed2d4f078c3933"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/agents/cs-engineering-lead.md names \u0060engineering-team/senior-data-scientist\u0060, but no file or folder \u0060engineering-team/senior-data-scientist\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/agents/cs-engineering-lead.md"},"region":{"startLine":35}}}],"partialFingerprints":{"codehealthFindingId/v1":"6f91d43dd21d2f8474abee2ce21ac621001b2544809af2d0e59563d8ace9822d"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/agents/cs-engineering-lead.md names \u0060engineering-team/senior-ml-engineer\u0060, but no file or folder \u0060engineering-team/senior-ml-engineer\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/agents/cs-engineering-lead.md"},"region":{"startLine":36}}}],"partialFingerprints":{"codehealthFindingId/v1":"e765fdd68ddb717385d9c52ef853132e2929c02ec4fe12319af67607d1930e1c"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/agents/cs-engineering-lead.md names \u0060engineering-team/senior-devops\u0060, but no file or folder \u0060engineering-team/senior-devops\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/agents/cs-engineering-lead.md"},"region":{"startLine":39}}}],"partialFingerprints":{"codehealthFindingId/v1":"85e74701ebceb8e47569571004f32e94c05ca3796cabcf97f32e260bdd0fc516"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/agents/cs-engineering-lead.md names \u0060engineering-team/incident-commander\u0060, but no file or folder \u0060engineering-team/incident-commander\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/agents/cs-engineering-lead.md"},"region":{"startLine":40}}}],"partialFingerprints":{"codehealthFindingId/v1":"f5c3359401ea9b9c32587fa3279e0f0e19f8d929719cc0aed918b7c546a09427"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/agents/cs-engineering-lead.md names \u0060engineering-team/aws-solution-architect\u0060, but no file or folder \u0060engineering-team/aws-solution-architect\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/agents/cs-engineering-lead.md"},"region":{"startLine":41}}}],"partialFingerprints":{"codehealthFindingId/v1":"20e40e594ecb36068c76e40012e54384856583daefa2bc9004eb76652b86e2de"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/agents/cs-engineering-lead.md names \u0060engineering-team/tech-stack-evaluator\u0060, but no file or folder \u0060engineering-team/tech-stack-evaluator\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/agents/cs-engineering-lead.md"},"region":{"startLine":42}}}],"partialFingerprints":{"codehealthFindingId/v1":"98bccb7e11d8873af39e8afac0d5041044976b41f12f0f7279e29f45c7d59d87"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/agents/cs-frontend-engineer.md names \u0060engineering-team/senior-frontend\u0060, but no file or folder \u0060engineering-team/senior-frontend\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/agents/cs-frontend-engineer.md"},"region":{"startLine":136}}}],"partialFingerprints":{"codehealthFindingId/v1":"133c5af45b237b1b7f4b35d2d89c5a7c41123929d5b6f3e38005052d473c57e4"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/agents/cs-fullstack-engineer.md names \u0060engineering-team/senior-fullstack\u0060, but no file or folder \u0060engineering-team/senior-fullstack\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/agents/cs-fullstack-engineer.md"},"region":{"startLine":177}}}],"partialFingerprints":{"codehealthFindingId/v1":"1d07b0caa1bd4d4c7986b3be887cc799c503c1778c91db7c61b5683e0d631650"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/agents/cs-grill-with-docs.md names \u0060CONTEXT.md\u0060, but no file or folder \u0060CONTEXT.md\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/agents/cs-grill-with-docs.md"},"region":{"startLine":36}}}],"partialFingerprints":{"codehealthFindingId/v1":"14854b01b709ba553029bc3bd5ab48a5237cf1233a5fd8c32304f7837d08b403"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/agents/cs-grill-with-docs.md names \u0060NNNN-slug.md\u0060, but no file or folder \u0060NNNN-slug.md\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/agents/cs-grill-with-docs.md"},"region":{"startLine":69}}}],"partialFingerprints":{"codehealthFindingId/v1":"0e755285d8c4ac7fc862af1efd9279469e7934e43c64678b2f5367205596f290"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/agents/cs-growth-strategist.md names \u0060business-growth/revenue-operations\u0060, but no file or folder \u0060business-growth/revenue-operations\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/agents/cs-growth-strategist.md"},"region":{"startLine":21}}}],"partialFingerprints":{"codehealthFindingId/v1":"91f491d808bc8840b37361f80eef9dacb8a811e21e156aba5363ef693e1a6ec8"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/agents/cs-growth-strategist.md names \u0060business-growth/sales-engineer\u0060, but no file or folder \u0060business-growth/sales-engineer\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/agents/cs-growth-strategist.md"},"region":{"startLine":22}}}],"partialFingerprints":{"codehealthFindingId/v1":"ac9a51523d1aa3f8cd9c38698b62d7018213c1636c5a7ece52662254a9c7b4a8"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/agents/cs-growth-strategist.md names \u0060business-growth/customer-success-manager\u0060, but no file or folder \u0060business-growth/customer-success-manager\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/agents/cs-growth-strategist.md"},"region":{"startLine":23}}}],"partialFingerprints":{"codehealthFindingId/v1":"911e19573a3a5873951e23635bc50e1ebae316dce8a6a1053af53a7cf1037641"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/agents/cs-growth-strategist.md names \u0060business-growth/contract-and-proposal-writer\u0060, but no file or folder \u0060business-growth/contract-and-proposal-writer\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/agents/cs-growth-strategist.md"},"region":{"startLine":24}}}],"partialFingerprints":{"codehealthFindingId/v1":"6304b52617fb2ec846e42d8b9177bf0f7aed64808d5185de6c2993c77b777b0b"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/agents/cs-human-gate.md names \u0060marketing-skill/content-humanizer\u0060, but no file or folder \u0060marketing-skill/content-humanizer\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/agents/cs-human-gate.md"},"region":{"startLine":102}}}],"partialFingerprints":{"codehealthFindingId/v1":"a1091f13ce888bd2a213d05989ecec672708f68c7c639bfbd4a40009c9007f97"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/agents/cs-human-gate.md names \u0060markdown-html/md-review\u0060, but no file or folder \u0060markdown-html/md-review\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/agents/cs-human-gate.md"},"region":{"startLine":103}}}],"partialFingerprints":{"codehealthFindingId/v1":"b870c9d8c17586e8813df3a4b561a37fed934764fca60804babf5b12da0fb57c"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/agents/cs-inbox-triage.md names \u0060email-taxonomy.md\u0060, but no file or folder \u0060email-taxonomy.md\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/agents/cs-inbox-triage.md"},"region":{"startLine":24}}}],"partialFingerprints":{"codehealthFindingId/v1":"e600f1b0299c2be2597bb8b00b2567181cdfc963323cb062295c48f4d12d7b77"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/agents/cs-inbox-triage.md names \u0060email-patterns.md\u0060, but no file or folder \u0060email-patterns.md\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/agents/cs-inbox-triage.md"},"region":{"startLine":24}}}],"partialFingerprints":{"codehealthFindingId/v1":"743074398d682c2d82ee9011b3393ce6a5d6870d1d6bad673e0cab5247bc76bd"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/agents/cs-meeting-discipline.md names \u0060business-operations/internal-comms\u0060, but no file or folder \u0060business-operations/internal-comms\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/agents/cs-meeting-discipline.md"},"region":{"startLine":83}}}],"partialFingerprints":{"codehealthFindingId/v1":"964316eea846797ca710aba594ad1b87399e1ed6781af6ac97bb709d34f1af3b"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/agents/cs-product-orchestrator.md names \u0060discovery_log.json\u0060, but no file or folder \u0060discovery_log.json\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/agents/cs-product-orchestrator.md"},"region":{"startLine":56}}}],"partialFingerprints":{"codehealthFindingId/v1":"a41d38449db7cd24122b0c7e19ebccfbeafaa08ed4b765eea2edefaf515c1e91"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/agents/cs-quality-regulatory.md names \u0060ra-qm-team/quality-manager-qms-iso13485\u0060, but no file or folder \u0060ra-qm-team/quality-manager-qms-iso13485\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/agents/cs-quality-regulatory.md"},"region":{"startLine":22}}}],"partialFingerprints":{"codehealthFindingId/v1":"27b6c3157b56fe103d3bffc18f4e40d22dcb5a49d5827e94e4a4485f87025563"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/agents/cs-quality-regulatory.md names \u0060ra-qm-team/quality-manager-qmr\u0060, but no file or folder \u0060ra-qm-team/quality-manager-qmr\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/agents/cs-quality-regulatory.md"},"region":{"startLine":23}}}],"partialFingerprints":{"codehealthFindingId/v1":"3af8b2e0483554dafc65cf5868a98a52aab61e85059f6bc8a6066669936b04d0"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/agents/cs-quality-regulatory.md names \u0060ra-qm-team/quality-documentation-manager\u0060, but no file or folder \u0060ra-qm-team/quality-documentation-manager\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/agents/cs-quality-regulatory.md"},"region":{"startLine":24}}}],"partialFingerprints":{"codehealthFindingId/v1":"bcff10bcfe9e2fb10f2d7e5c5f7b3c6b215fc76039813115749eb75de2da8808"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/agents/cs-quality-regulatory.md names \u0060ra-qm-team/qms-audit-expert\u0060, but no file or folder \u0060ra-qm-team/qms-audit-expert\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/agents/cs-quality-regulatory.md"},"region":{"startLine":25}}}],"partialFingerprints":{"codehealthFindingId/v1":"7fd6962c1db93064be72e4f5f584c044fc973d18d94efe738955d597d9ad5316"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/agents/cs-quality-regulatory.md names \u0060ra-qm-team/capa-officer\u0060, but no file or folder \u0060ra-qm-team/capa-officer\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/agents/cs-quality-regulatory.md"},"region":{"startLine":26}}}],"partialFingerprints":{"codehealthFindingId/v1":"380febf32d0eafe10cec1da90b03fc18e4cbd05516c54b80ffc46fb437066b35"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/agents/cs-quality-regulatory.md names \u0060ra-qm-team/regulatory-affairs-head\u0060, but no file or folder \u0060ra-qm-team/regulatory-affairs-head\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/agents/cs-quality-regulatory.md"},"region":{"startLine":29}}}],"partialFingerprints":{"codehealthFindingId/v1":"6fcae6402f19362104f6edf458dbe9fdac8914994d12ded4da852527bc94bba7"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/agents/cs-quality-regulatory.md names \u0060ra-qm-team/mdr-745-specialist\u0060, but no file or folder \u0060ra-qm-team/mdr-745-specialist\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/agents/cs-quality-regulatory.md"},"region":{"startLine":30}}}],"partialFingerprints":{"codehealthFindingId/v1":"546f83f543f423e721f915769b5c12f2ff1bcdc903696ee53a47ad0cd76af04a"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/agents/cs-quality-regulatory.md names \u0060ra-qm-team/fda-consultant-specialist\u0060, but no file or folder \u0060ra-qm-team/fda-consultant-specialist\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/agents/cs-quality-regulatory.md"},"region":{"startLine":31}}}],"partialFingerprints":{"codehealthFindingId/v1":"e60adddb65910c48cb7fe0396788e2b5318d2d103fafafa7988898e049414db2"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/agents/cs-quality-regulatory.md names \u0060ra-qm-team/risk-management-specialist\u0060, but no file or folder \u0060ra-qm-team/risk-management-specialist\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/agents/cs-quality-regulatory.md"},"region":{"startLine":32}}}],"partialFingerprints":{"codehealthFindingId/v1":"6a74fb38ca6b10993c7c47ca47e14c9aada92086512c41bef13521eb4a25d6f5"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/agents/cs-quality-regulatory.md names \u0060ra-qm-team/information-security-manager-iso27001\u0060, but no file or folder \u0060ra-qm-team/information-security-manager-iso27001\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/agents/cs-quality-regulatory.md"},"region":{"startLine":35}}}],"partialFingerprints":{"codehealthFindingId/v1":"ae023e9d5fd1caa20916b92a884cdfd03bdf09f916f39d1690a3ce7e47677c20"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/agents/cs-quality-regulatory.md names \u0060ra-qm-team/isms-audit-expert\u0060, but no file or folder \u0060ra-qm-team/isms-audit-expert\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/agents/cs-quality-regulatory.md"},"region":{"startLine":36}}}],"partialFingerprints":{"codehealthFindingId/v1":"43c1027ef0633dc74e49e1204b87cd6577927070866396d8bc5806b9fffc96c4"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/agents/cs-quality-regulatory.md names \u0060ra-qm-team/gdpr-dsgvo-expert\u0060, but no file or folder \u0060ra-qm-team/gdpr-dsgvo-expert\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/agents/cs-quality-regulatory.md"},"region":{"startLine":37}}}],"partialFingerprints":{"codehealthFindingId/v1":"3075d6b4a11dcd0fa9d89b54fdeb850d041ec1f0c965332eb01eda6018a7ddce"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/agents/cs-research-ops-orchestrator.md names \u0060program-budget.json\u0060, but no file or folder \u0060program-budget.json\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/agents/cs-research-ops-orchestrator.md"},"region":{"startLine":43}}}],"partialFingerprints":{"codehealthFindingId/v1":"f5fe1f1fbb7139a82d3c675a7214c9cb39522c9f181a55c48863eb1bbf33e3ae"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/agents/cs-research-ops-orchestrator.md names \u0060tam-model.json\u0060, but no file or folder \u0060tam-model.json\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/agents/cs-research-ops-orchestrator.md"},"region":{"startLine":43}}}],"partialFingerprints":{"codehealthFindingId/v1":"9df204314b5f991eeb3adcf0adf58259a1ab7603a15e488cd9e051bc218c18ff"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/agents/cs-research-ops-orchestrator.md names \u0060finance/financial-analysis\u0060, but no file or folder \u0060finance/financial-analysis\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/agents/cs-research-ops-orchestrator.md"},"region":{"startLine":85}}}],"partialFingerprints":{"codehealthFindingId/v1":"be2140c45028b02248c8a617d2b939ef992442109f5cff18c2e8f4737d6e29de"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/agents/cs-research-ops-orchestrator.md names \u0060product-team/experiment-designer\u0060, but no file or folder \u0060product-team/experiment-designer\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/agents/cs-research-ops-orchestrator.md"},"region":{"startLine":86}}}],"partialFingerprints":{"codehealthFindingId/v1":"3694d6dd2c00d638e513b5f5d2c283536c1480c827ffd317d71f776f0eeeae96"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/agents/cs-research-ops-orchestrator.md names \u0060product-team/ux-researcher-designer\u0060, but no file or folder \u0060product-team/ux-researcher-designer\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/agents/cs-research-ops-orchestrator.md"},"region":{"startLine":87}}}],"partialFingerprints":{"codehealthFindingId/v1":"a3b8e3711c1460ff26a6af1a5e5a22488708f87a4db02d7d5b03e5dc02c4cd11"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/agents/cs-roast-judge.md names \u0060company-context.md\u0060, but no file or folder \u0060company-context.md\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/agents/cs-roast-judge.md"},"region":{"startLine":76}}}],"partialFingerprints":{"codehealthFindingId/v1":"fea6820a5ab81db5c50e8f96990ed13f5d86afcdcf48eba8bd445617fa8286a3"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/agents/cs-scraping-architect.md names \u0060project-context.md\u0060, but no file or folder \u0060project-context.md\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/agents/cs-scraping-architect.md"},"region":{"startLine":19}}}],"partialFingerprints":{"codehealthFindingId/v1":"1b5098ba5f6d6113300f342f7f61b498145a34d5252c98d311b32ac846a7b5b6"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/agents/cs-senior-engineer.md names \u0060engineering/database-designer\u0060, but no file or folder \u0060engineering/database-designer\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/agents/cs-senior-engineer.md"},"region":{"startLine":22}}}],"partialFingerprints":{"codehealthFindingId/v1":"7f88bd3ec03b766b4ab6193edb5872268b5c058982a41f5a0fb5a066fa50863a"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/agents/cs-senior-engineer.md names \u0060engineering/api-design-reviewer\u0060, but no file or folder \u0060engineering/api-design-reviewer\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/agents/cs-senior-engineer.md"},"region":{"startLine":23}}}],"partialFingerprints":{"codehealthFindingId/v1":"1280a967349d3b4f08580f2b106e1c367932d74c68f5dd4c82a56e219c029486"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/agents/cs-senior-engineer.md names \u0060engineering/migration-architect\u0060, but no file or folder \u0060engineering/migration-architect\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/agents/cs-senior-engineer.md"},"region":{"startLine":24}}}],"partialFingerprints":{"codehealthFindingId/v1":"f78a29ce847a6dee52d75c9356b6b3d9a98f506d9e5e3af8c8d18dabb5974cb2"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/agents/cs-senior-engineer.md names \u0060engineering-team/senior-architect\u0060, but no file or folder \u0060engineering-team/senior-architect\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/agents/cs-senior-engineer.md"},"region":{"startLine":25}}}],"partialFingerprints":{"codehealthFindingId/v1":"d975ec3fb4c0fcaf8600c7860db970278a1b4c0275d5f314ccb2524fb3d55c94"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/agents/cs-senior-engineer.md names \u0060engineering-team/senior-backend\u0060, but no file or folder \u0060engineering-team/senior-backend\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/agents/cs-senior-engineer.md"},"region":{"startLine":26}}}],"partialFingerprints":{"codehealthFindingId/v1":"6d1738a0ae4b6ebe57250450542b56dc045ca038285ebcc906976211c9dabb03"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/agents/cs-senior-engineer.md names \u0060engineering/pr-review-expert\u0060, but no file or folder \u0060engineering/pr-review-expert\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/agents/cs-senior-engineer.md"},"region":{"startLine":29}}}],"partialFingerprints":{"codehealthFindingId/v1":"3265239094eaede9f487bc77cefa0bf0c4ee8092147acf89a9246b1eb7def690"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/agents/cs-senior-engineer.md names \u0060engineering/focused-fix\u0060, but no file or folder \u0060engineering/focused-fix\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/agents/cs-senior-engineer.md"},"region":{"startLine":30}}}],"partialFingerprints":{"codehealthFindingId/v1":"bd645521c952017c631e937930ec3f98bbb4c7c22c8c6a4f718eba699d59edcb"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/agents/cs-senior-engineer.md names \u0060engineering-team/code-reviewer\u0060, but no file or folder \u0060engineering-team/code-reviewer\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/agents/cs-senior-engineer.md"},"region":{"startLine":31}}}],"partialFingerprints":{"codehealthFindingId/v1":"33de772d94bdc2def8129c272675e0f6df09c307d2be4c4b16c2179f1a7be884"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/agents/cs-senior-engineer.md names \u0060engineering-team/tdd-guide\u0060, but no file or folder \u0060engineering-team/tdd-guide\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/agents/cs-senior-engineer.md"},"region":{"startLine":32}}}],"partialFingerprints":{"codehealthFindingId/v1":"cb80d5da4f37aa27ac29eb6eb75126c1387bed8b95fb626d198536cd62664f25"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/agents/cs-senior-engineer.md names \u0060engineering-team/senior-qa\u0060, but no file or folder \u0060engineering-team/senior-qa\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/agents/cs-senior-engineer.md"},"region":{"startLine":33}}}],"partialFingerprints":{"codehealthFindingId/v1":"b30b36d0f2aa158a4afdaf48e48035aa8da3f8a74c52990ac598b966973666ee"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/agents/cs-senior-engineer.md names \u0060engineering/ci-cd-pipeline-builder\u0060, but no file or folder \u0060engineering/ci-cd-pipeline-builder\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/agents/cs-senior-engineer.md"},"region":{"startLine":36}}}],"partialFingerprints":{"codehealthFindingId/v1":"64f5cc48979a3ab5946e39018675e82e1476545e219413c3fcd8d0b797c30ccb"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/agents/cs-senior-engineer.md names \u0060engineering-team/senior-devops\u0060, but no file or folder \u0060engineering-team/senior-devops\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/agents/cs-senior-engineer.md"},"region":{"startLine":38}}}],"partialFingerprints":{"codehealthFindingId/v1":"c44330a1f398dd640f1b9a1165925220453b3538337d2ceee7d3fb0909a14f64"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/agents/cs-senior-engineer.md names \u0060engineering/observability-designer\u0060, but no file or folder \u0060engineering/observability-designer\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/agents/cs-senior-engineer.md"},"region":{"startLine":39}}}],"partialFingerprints":{"codehealthFindingId/v1":"ab12aca5785af2c605a9a1e4a2d6e68204404b28c592a3f59a67c1e9ccbca13f"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/agents/cs-senior-engineer.md names \u0060engineering-team/senior-security\u0060, but no file or folder \u0060engineering-team/senior-security\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/agents/cs-senior-engineer.md"},"region":{"startLine":42}}}],"partialFingerprints":{"codehealthFindingId/v1":"f3495cea09409d90ec7f386f2476922851c925d09cf4993cecb5f54ad252c096"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/agents/cs-senior-engineer.md names \u0060engineering-team/senior-secops\u0060, but no file or folder \u0060engineering-team/senior-secops\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/agents/cs-senior-engineer.md"},"region":{"startLine":43}}}],"partialFingerprints":{"codehealthFindingId/v1":"f51c5914833d375f9df9c41e3b45db93754d17ca918bc4a4f7387e2baca280dc"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/agents/cs-senior-engineer.md names \u0060engineering/dependency-auditor\u0060, but no file or folder \u0060engineering/dependency-auditor\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/agents/cs-senior-engineer.md"},"region":{"startLine":44}}}],"partialFingerprints":{"codehealthFindingId/v1":"acf2a6ee00f957dd8db4a094a19b59007877fd1ed744de9edb80e301fdccfb3d"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/agents/memory-analyst.md names \u0060MEMORY.md\u0060, but no file or folder \u0060MEMORY.md\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/agents/memory-analyst.md"},"region":{"startLine":29}}}],"partialFingerprints":{"codehealthFindingId/v1":"35cf2ab8109dca443b5bf51c17f6327298153de16422a3184172e2198f4aeb7c"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/agents/memory-analyst.md names \u0060debugging.md\u0060, but no file or folder \u0060debugging.md\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/agents/memory-analyst.md"},"region":{"startLine":30}}}],"partialFingerprints":{"codehealthFindingId/v1":"b0d680f88f2b38e12fa123de6100432ca32ca770ade0e76f4f21c3fd0b877bef"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/commands/chaos-experiment.md names \u0060.chaos-plan.json\u0060, but no file or folder \u0060.chaos-plan.json\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/commands/chaos-experiment.md"},"region":{"startLine":72}}}],"partialFingerprints":{"codehealthFindingId/v1":"d24af32d8c413eb2150a85080e46106d45eefd9052d62c278eabb65bf81589cd"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/commands/code-to-prd.md names \u0060prd/pages/\u0060, but no file or folder \u0060prd/pages\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/commands/code-to-prd.md"},"region":{"startLine":56}}}],"partialFingerprints":{"codehealthFindingId/v1":"4be5808f33a94c873f86299532b9f21e0097ae9a43c42283ff186b825562bc54"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/commands/code-to-prd.md names \u0060prd/appendix/enum-dictionary.md\u0060, but no file or folder \u0060prd/appendix/enum-dictionary.md\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/commands/code-to-prd.md"},"region":{"startLine":63}}}],"partialFingerprints":{"codehealthFindingId/v1":"e83b19a4bee0709ced6d856bb0914063226faffb056de8dbe83fc476703c389c"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/commands/code-to-prd.md names \u0060prd/appendix/api-inventory.md\u0060, but no file or folder \u0060prd/appendix/api-inventory.md\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/commands/code-to-prd.md"},"region":{"startLine":64}}}],"partialFingerprints":{"codehealthFindingId/v1":"98d63a9acbd87dc0ac8b76d6b18e8c484929887eb5e8f0f4827747957e8d63fd"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/commands/code-to-prd.md names \u0060prd/appendix/page-relationships.md\u0060, but no file or folder \u0060prd/appendix/page-relationships.md\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/commands/code-to-prd.md"},"region":{"startLine":65}}}],"partialFingerprints":{"codehealthFindingId/v1":"ab2cb373d0f2e2f69191745966ac701eb834531c7ce13010d754d6f4a50015f9"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/commands/cs-capacity-plan.md names \u0060c-level-advisor/chro-advisor\u0060, but no file or folder \u0060c-level-advisor/chro-advisor\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/commands/cs-capacity-plan.md"},"region":{"startLine":33}}}],"partialFingerprints":{"codehealthFindingId/v1":"e666089eb38fffdef89208ce87b388504c6ed9968a0597f5d3d99668f849d9f4"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/commands/cs-channel-econ.md names \u0060business-growth/revenue-operations\u0060, but no file or folder \u0060business-growth/revenue-operations\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/commands/cs-channel-econ.md"},"region":{"startLine":33}}}],"partialFingerprints":{"codehealthFindingId/v1":"8d652b24fba070b6bb23a57f374c1751aaa61ef6d643ef31ea1cfc37d72418b8"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/commands/cs-channel-econ.md names \u0060c-level-advisor/cro-advisor\u0060, but no file or folder \u0060c-level-advisor/cro-advisor\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/commands/cs-channel-econ.md"},"region":{"startLine":34}}}],"partialFingerprints":{"codehealthFindingId/v1":"d3226e53b6203af6e77e57532ed69fcb8c02e21143f26b45cdb7db6aef6b3a56"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/commands/cs-channel-econ.md names \u0060finance/financial-analysis\u0060, but no file or folder \u0060finance/financial-analysis\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/commands/cs-channel-econ.md"},"region":{"startLine":35}}}],"partialFingerprints":{"codehealthFindingId/v1":"4156a273e5e6223eb6cf21860124af447fb094523cc584f2b943a3dc65776779"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/commands/cs-clinical-research.md names \u0060product-team/experiment-designer\u0060, but no file or folder \u0060product-team/experiment-designer\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/commands/cs-clinical-research.md"},"region":{"startLine":46}}}],"partialFingerprints":{"codehealthFindingId/v1":"d3e13004ab274d6f242d52387a6d5df31a2c8392997480dd3fe5a0a56036174a"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/commands/cs-commercial-forecast.md names \u0060finance/financial-analysis\u0060, but no file or folder \u0060finance/financial-analysis\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/commands/cs-commercial-forecast.md"},"region":{"startLine":32}}}],"partialFingerprints":{"codehealthFindingId/v1":"7eee8eb8a0a377fdaa16566956bedc0e126fcd00d7dfedc52f5120995f641c05"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/commands/cs-commercial-forecast.md names \u0060c-level-advisor/cfo-advisor\u0060, but no file or folder \u0060c-level-advisor/cfo-advisor\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/commands/cs-commercial-forecast.md"},"region":{"startLine":33}}}],"partialFingerprints":{"codehealthFindingId/v1":"70627234f49e694f0187f840a862a3a934cf1225b2442822f4d800e09b6c1ba9"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/commands/cs-commercial-forecast.md names \u0060c-level-advisor/cro-advisor\u0060, but no file or folder \u0060c-level-advisor/cro-advisor\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/commands/cs-commercial-forecast.md"},"region":{"startLine":34}}}],"partialFingerprints":{"codehealthFindingId/v1":"96401eaa4a17235772f9383139fb41da3fed7dda060db2049cda46236c79e926"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/commands/cs-commercial-policy.md names \u0060c-level-advisor/cro-advisor\u0060, but no file or folder \u0060c-level-advisor/cro-advisor\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/commands/cs-commercial-policy.md"},"region":{"startLine":34}}}],"partialFingerprints":{"codehealthFindingId/v1":"a058749ece7a3a1a93689e57675984fd34a1d15e9a34a8ce53efe0084a9b6a67"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/commands/cs-commercial-policy.md names \u0060c-level-advisor/cfo-advisor\u0060, but no file or folder \u0060c-level-advisor/cfo-advisor\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/commands/cs-commercial-policy.md"},"region":{"startLine":35}}}],"partialFingerprints":{"codehealthFindingId/v1":"15d693d5bf8efa4bab2c8090181b938976aa596ffef27d1337a63ccc55882aac"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/commands/cs-deal-review.md names \u0060business-growth/contract-and-proposal-writer\u0060, but no file or folder \u0060business-growth/contract-and-proposal-writer\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/commands/cs-deal-review.md"},"region":{"startLine":40}}}],"partialFingerprints":{"codehealthFindingId/v1":"435fb4046d69c6d26430ca09c75b8f0af7d631d570e2043b178acea8f882f287"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/commands/cs-deep-research.md names \u0060plan.md\u0060, but no file or folder \u0060plan.md\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/commands/cs-deep-research.md"},"region":{"startLine":34}}}],"partialFingerprints":{"codehealthFindingId/v1":"59d9dac3b813b0543eec64f6151eec275e1d779394ac259e68d98058e651fff3"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/commands/cs-deep-research.md names \u0060sources.csv\u0060, but no file or folder \u0060sources.csv\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/commands/cs-deep-research.md"},"region":{"startLine":37}}}],"partialFingerprints":{"codehealthFindingId/v1":"2df6c86f817be648bd4f8fd689439b4cf4f6b5aa8d791ce6829641c30ff0a48b"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/commands/cs-deep-research.md names \u0060refresh_targets.md\u0060, but no file or folder \u0060refresh_targets.md\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/commands/cs-deep-research.md"},"region":{"startLine":37}}}],"partialFingerprints":{"codehealthFindingId/v1":"36d642b0ede48ea579918b3c407e9884695f346342db007d2ad71c08c7685f9d"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/commands/cs-grill-with-docs.md names \u0060CONTEXT.md\u0060, but no file or folder \u0060CONTEXT.md\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/commands/cs-grill-with-docs.md"},"region":{"startLine":16}}}],"partialFingerprints":{"codehealthFindingId/v1":"2d0624a95039c04f43ad6331312f176937c6a287c425a0d4afdd3d1cf001fd4f"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/commands/cs-inbox-setup.md names \u0060email-taxonomy.md\u0060, but no file or folder \u0060email-taxonomy.md\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/commands/cs-inbox-setup.md"},"region":{"startLine":42}}}],"partialFingerprints":{"codehealthFindingId/v1":"11a286a458f4db4d6971bc6b38e6ee933c3c686265263246845d50d2ab54d42d"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/commands/cs-inbox-setup.md names \u0060email-patterns.md\u0060, but no file or folder \u0060email-patterns.md\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/commands/cs-inbox-setup.md"},"region":{"startLine":43}}}],"partialFingerprints":{"codehealthFindingId/v1":"dbfcd2e27b61a456ae050d6447668744a68d4fafeae095dad8b4cfba72a12dbc"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/commands/cs-inbox-setup.md names \u0060evaluation-framework.md\u0060, but no file or folder \u0060evaluation-framework.md\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/commands/cs-inbox-setup.md"},"region":{"startLine":44}}}],"partialFingerprints":{"codehealthFindingId/v1":"00c2488e5b8b47bb135ac2cf0c01729790ef389517f873dce28a7d8029f6d826"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/commands/cs-inbox-setup.md names \u0060rate-card.md\u0060, but no file or folder \u0060rate-card.md\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/commands/cs-inbox-setup.md"},"region":{"startLine":45}}}],"partialFingerprints":{"codehealthFindingId/v1":"8bc8897c9ddcc5c9c60a649a83d28b5c83148c158624f1935379f5343993dab9"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/commands/cs-inbox-setup.md names \u0060blocklist.md\u0060, but no file or folder \u0060blocklist.md\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/commands/cs-inbox-setup.md"},"region":{"startLine":46}}}],"partialFingerprints":{"codehealthFindingId/v1":"2b5f55bd1473978bf6cef67059f51d0d37338266a80dbdb8a890fa6f6a30c12f"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/commands/cs-inbox-setup.md names \u0060tracker.md\u0060, but no file or folder \u0060tracker.md\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/commands/cs-inbox-setup.md"},"region":{"startLine":47}}}],"partialFingerprints":{"codehealthFindingId/v1":"4ad22146ce25564441fe76b315b9ccb9d9b0a241cd14639077b41fde638231d2"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/commands/cs-inbox-triage.md names \u0060email-patterns.md\u0060, but no file or folder \u0060email-patterns.md\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/commands/cs-inbox-triage.md"},"region":{"startLine":52}}}],"partialFingerprints":{"codehealthFindingId/v1":"17a9da0fa273330eddea90a5676b07ab22e2e39cc446d28fd63a7b206440f780"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/commands/cs-inbox-triage.md names \u0060email-taxonomy.md\u0060, but no file or folder \u0060email-taxonomy.md\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/commands/cs-inbox-triage.md"},"region":{"startLine":53}}}],"partialFingerprints":{"codehealthFindingId/v1":"48b2df6b6d7b2956d49faa8d960b9e91d729242d739e66edffc43c9963cf2300"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/commands/cs-inbox-triage.md names \u0060blocklist.md\u0060, but no file or folder \u0060blocklist.md\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/commands/cs-inbox-triage.md"},"region":{"startLine":54}}}],"partialFingerprints":{"codehealthFindingId/v1":"4328d9c25c836c5d22814484cdc2c2de4b34794a18021d296d6e950c152a8968"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/commands/cs-inbox-triage.md names \u0060tracker.md\u0060, but no file or folder \u0060tracker.md\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/commands/cs-inbox-triage.md"},"region":{"startLine":54}}}],"partialFingerprints":{"codehealthFindingId/v1":"9346f3a987c5ccb95f932ff1c8dd79b3ce016b86c03b44b2cab6f0ecf60e2604"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/commands/cs-inbox-triage.md names \u0060evaluation-framework.md\u0060, but no file or folder \u0060evaluation-framework.md\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/commands/cs-inbox-triage.md"},"region":{"startLine":109}}}],"partialFingerprints":{"codehealthFindingId/v1":"87d0c681755e8cda5ed5bfa091960b3d40cb9fea529901376acb68494259f2b5"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/commands/cs-internal-comms.md names \u0060c-level-advisor/internal-narrative\u0060, but no file or folder \u0060c-level-advisor/internal-narrative\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/commands/cs-internal-comms.md"},"region":{"startLine":35}}}],"partialFingerprints":{"codehealthFindingId/v1":"d71e0ec6d18528afee3e207a0d44480d70edd8562ce9a227d7ee1cf9b5f0b6b9"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/commands/cs-internal-comms.md names \u0060c-level-advisor/change-management\u0060, but no file or folder \u0060c-level-advisor/change-management\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/commands/cs-internal-comms.md"},"region":{"startLine":36}}}],"partialFingerprints":{"codehealthFindingId/v1":"f51c60c43df005f24e4e0dac81e043046a9c21087aa9a27d39164528f3e22c00"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/commands/cs-knowledge-ops.md names \u0060engineering-team/runbook-generator\u0060, but no file or folder \u0060engineering-team/runbook-generator\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/commands/cs-knowledge-ops.md"},"region":{"startLine":29}}}],"partialFingerprints":{"codehealthFindingId/v1":"1fa54c8cb97687de4f29b3310ad03c23fa1cc7f08bd761e1ce0b668a23c1b54e"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/commands/cs-markdown-html.md names \u0060report.md\u0060, but no file or folder \u0060report.md\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/commands/cs-markdown-html.md"},"region":{"startLine":28}}}],"partialFingerprints":{"codehealthFindingId/v1":"42f80660aa45cbb5bffa8e4a78a1e244cc2ddb5caa27f93e54485e66ee0a350a"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/commands/cs-markdown-html.md names \u0060review.md\u0060, but no file or folder \u0060review.md\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/commands/cs-markdown-html.md"},"region":{"startLine":29}}}],"partialFingerprints":{"codehealthFindingId/v1":"5223e99bdf02d1db2028123ec4a7de4a56e8090350e1e2a527731e1c6c2529fa"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/commands/cs-market-research.md names \u0060marketing-skill/marketing-strategy-pmm\u0060, but no file or folder \u0060marketing-skill/marketing-strategy-pmm\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/commands/cs-market-research.md"},"region":{"startLine":45}}}],"partialFingerprints":{"codehealthFindingId/v1":"a224e0c5a6ddacb6a33722057513f6d64e490b72d980a5a74ad88ef3510dc186"}},{"ruleId":"M4","level":"note","message":{"text":"README/code drift: docs/commands/cs-market-research.md names \u0060commercial/pricing-strategist\u0060, but no file or folder \u0060commercial/pricing-strategist\u0060 exists. Checked without a model against the repository: its files and folders, the scripts and dependencies of every package.json, the projects, namespaces, package references and target frameworks of the .NET build, the SDK and Node pins, and the identifiers of every file that is not a document; the documents\u0027 own text never counts. A footprint generated at build time, read only by a platform, or living outside this repository is not seen, and this row is then wrong."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/commands/cs-market-research.md"},"region":{"startLine":46}}}],"partialFingerprints":{"codehealthFindingId/v1":"edb4858d7f06b9bf40b88182bfa7412cfa15288f5c4c247f2b0d84f191b3c01a"}},{"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 72277 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":"R1","level":"warning","message":{"text":"Type Safety: 7 typed \u00B7 11 plain JS \u2014 the untyped files are engineering-team/skills/epic-design/scripts/validate-layers.js, engineering/hivemind/scripts/oc-aggregate.mjs, engineering/hivemind/scripts/oc-status.mjs, engineering/hivemind/scripts/oc-worker.mjs, engineering/skills/full-page-screenshot/scripts/full-page-screenshot.mjs, engineering/skills/tech-debt-tracker/assets/sample_codebase/src/frontend.js (\u002B5 more)."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"d00ee7953f55325a823d27e5db9657c80ca9b9861c0c0abf8fe487cd3fa586d3"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplication concentrated across 2 sibling directories (5 clone groups): 5 duplicated blocks under engineering-team/playwright-pro/integrations/ have copies in at least two of the sibling directories browserstack-mcp, testrail-mcp \u2014 3 of them are reported below, and 2 are counted here but not reported individually: those copies match on shape but no longer clear R10\u0027s bar for an individually reported row \u2014 either they kept neither their own names nor their values, or what was copied is too small to stand on its own (it reports near-exact duplication only, and only of substantial extent). What this row states is the concentration, which the detector measured over all 5 and which does not depend on how exactly each block\u0027s copies still match. That concentration is one structural fact, not 5 local ones: the siblings replicate behaviour none of them owns, which is the shape of a missing shared module \u2014 a common library every sibling imports \u2014 rather than 5 separate extractions. Check first whether the siblings are deliberately standalone deliverables (scaffold templates, demo apps that must stay copy-pasteable); where they are, the duplication is the design and the per-block rows are the ones to act on."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/playwright-pro/integrations/browserstack-mcp/src/index.ts"},"region":{"startLine":147}}}],"partialFingerprints":{"codehealthFindingId/v1":"1ab260c333fa1712506bae39ebe085516189ef656830d7444ee68fbd6a65dfd2"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (34 lines \u00D7 2 locations): engineering/workflow-builder/skills/workflow-builder/assets/templates/pipeline.js:3 \u00B7 engineering/workflow-builder/skills/workflow-builder/expected_outputs/scaffold_pipeline.js:3 \u2014 the 2 copies are spread across 2 files, and the CITED SPAN is a run of DECLARATIONS inside a construct \u2014 the members of a type, or the entries of an object or array literal \u2014 with no statement anywhere in it. Do not read this as an extract-a-helper row: nothing here executes, so there is no call site, and a call expression cannot stand where a member declaration or a literal\u0027s entry was. What repeats is a SHAPE, and which shape decides the move. Where the copies declare the same members, the repetition is a missing common ancestor: give it a base type, an interface both extend, a generic instantiated twice, or \u2014 where the copies are a literal\u0027s entries rather than a type\u0027s members \u2014 one shared constant each site spreads or refers to, so the set is written once. Where they declare DIFFERENT members and only the form is shared \u2014 a decorator and its options, an annotation, a registration table\u0027s keys \u2014 the form is prescribed by a framework or a schema rather than copied, and the only collapse available is to generate the declarations from that schema; where you do not own the generator, this is the cost of the framework and there is nothing to extract. Check which of the two it is before acting: these copies still drift apart the first time only one of them is edited, which is why the repetition is reported, but the sentence to act on is not the same in both cases."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/workflow-builder/skills/workflow-builder/assets/templates/pipeline.js"},"region":{"startLine":3}}}],"partialFingerprints":{"codehealthFindingId/v1":"141dfe6ba3feacaff49b2f1aba41d0a87102a70a1489f70f2f0b61d3e9606691"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block with local edits (31 matched lines \u00D7 2 locations): engineering-team/playwright-pro/integrations/browserstack-mcp/src/index.ts:147 \u00B7 engineering-team/playwright-pro/integrations/testrail-mcp/src/index.ts:182 \u2014 the two spans are one implementation copied and then locally edited \u2014 325 tokens are still identical, in the same order in both files, with only local edits between them. The copies have already begun to drift, which is this row\u0027s finding: an edit made to one and not the other changes behaviour silently. Diff the two spans first to learn what genuinely differs, then extract the shared core into one module both sites use, passing the differences in as parameters \u2014 or, if one copy exists only because the other could not be imported from its context, make one of them the single source the other is generated or re-exported from. If one copy is no longer reachable, delete it rather than letting it shadow the live one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/playwright-pro/integrations/browserstack-mcp/src/index.ts"},"region":{"startLine":147}}}],"partialFingerprints":{"codehealthFindingId/v1":"f9f3a428142c469f47148631af703b4eaac81398d276bf3c69f903774074f088"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (25 lines \u00D7 2 locations): engineering-team/playwright-pro/integrations/browserstack-mcp/src/client.ts:22 \u00B7 engineering-team/playwright-pro/integrations/testrail-mcp/src/client.ts:26 \u2014 the 2 copies are spread across 2 directories, so the shared home is a decision rather than an obvious spot: check first whether one of them already owns this behaviour, and otherwise put the extracted module somewhere all of the sites already reach rather than making one of them depend on another."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/playwright-pro/integrations/browserstack-mcp/src/client.ts"},"region":{"startLine":22}}}],"partialFingerprints":{"codehealthFindingId/v1":"e578c6ded16f72abd4efacbe61a2bb3387a4b0f365252893e95db5dce121a2e6"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block with local edits (18 matched lines \u00D7 2 locations): engineering/skills/full-page-screenshot/scripts/full-page-screenshot.mjs:439 \u00B7 engineering/skills/full-page-screenshot/scripts/full-page-screenshot.mjs:830 \u2014 the two spans are one implementation copied and then locally edited \u2014 142 tokens are still identical, in the same order in both spans, with only local edits between them. The copies have already begun to drift, which is this row\u0027s finding: an edit made to one and not the other changes behaviour silently. Diff the two spans first to learn what genuinely differs, then extract the shared core into one module both sites use, passing the differences in as parameters \u2014 or, if one copy exists only because the other could not be imported from its context, make one of them the single source the other is generated or re-exported from. If one copy is no longer reachable, delete it rather than letting it shadow the live one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/full-page-screenshot/scripts/full-page-screenshot.mjs"},"region":{"startLine":439}}}],"partialFingerprints":{"codehealthFindingId/v1":"9f55e39856663cecedd5d48c9607da5fd603a2f145da06a9ea9c45fc7936cf0f"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (13 lines \u00D7 2 locations): engineering/skills/tech-debt-tracker/assets/sample_codebase/src/frontend.js:59 \u00B7 engineering/skills/tech-debt-tracker/assets/sample_codebase/src/frontend.js:189 \u2014 all 2 copies are in the same file, and the CITED SPAN is not a self-contained block \u2014 it runs from inside one construct into the next (the tail of a branch plus the head of the following one, a run of switch arms, the end of a declaration plus the list that follows it) rather than covering a whole unit. So do not lift these lines literally: no call can be substituted for a half-open construct. Extract the enclosing repeated UNIT instead \u2014 the whole function, component or branch these lines sit in \u2014 and where the repetition IS the construct (a run of switch arms, a stack of near-identical declarations) replace it with one table or registry looked up by key rather than a helper each arm calls. The copies still drift apart the first time only one of them is edited, which is why this is reported."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/tech-debt-tracker/assets/sample_codebase/src/frontend.js"},"region":{"startLine":59}}}],"partialFingerprints":{"codehealthFindingId/v1":"88b07c241fa90a05009f45fb4a9d65558ebc0b82dbd5f5763412dd0c5a0dcbfd"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (11 lines \u00D7 2 locations): engineering/skills/tech-debt-tracker/assets/sample_codebase/src/frontend.js:250 \u00B7 engineering/skills/tech-debt-tracker/assets/sample_codebase/src/frontend.js:267 \u2014 both copies are in the same file, so extract the block 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":"engineering/skills/tech-debt-tracker/assets/sample_codebase/src/frontend.js"},"region":{"startLine":250}}}],"partialFingerprints":{"codehealthFindingId/v1":"b02fea4391b069a1034b12f6520649c4349131cfaf723571cfb26bd4ca5f56a8"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 2 locations): engineering-team/playwright-pro/integrations/browserstack-mcp/src/index.ts:136 \u00B7 engineering-team/playwright-pro/integrations/browserstack-mcp/src/index.ts:144 \u2014 all 2 copies are in the same file, and the CITED SPAN is not a self-contained block \u2014 it runs from inside one construct into the next (the tail of a branch plus the head of the following one, a run of switch arms, the end of a declaration plus the list that follows it) rather than covering a whole unit. So do not lift these lines literally: no call can be substituted for a half-open construct. Extract the enclosing repeated UNIT instead \u2014 the whole function, component or branch these lines sit in \u2014 and where the repetition IS the construct (a run of switch arms, a stack of near-identical declarations) replace it with one table or registry looked up by key rather than a helper each arm calls. The copies still drift apart the first time only one of them is edited, which is why this is reported."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/playwright-pro/integrations/browserstack-mcp/src/index.ts"},"region":{"startLine":136}}}],"partialFingerprints":{"codehealthFindingId/v1":"ebfb0249cf3d127e862e756a29a4e8b7a2699cfa2d710434336da5948beb235b"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 3 locations): research/syllabus/skills/syllabus/scripts/generate_reading_list.js:270 \u00B7 research/syllabus/skills/syllabus/scripts/generate_reading_list.js:277 \u00B7 research/syllabus/skills/syllabus/scripts/generate_reading_list.js:284 \u2014 all 3 copies are in the same file, and the CITED SPAN is a run of DECLARATIONS inside a construct \u2014 the members of a type, or the entries of an object or array literal \u2014 with no statement anywhere in it. Do not read this as an extract-a-helper row: nothing here executes, so there is no call site, and a call expression cannot stand where a member declaration or a literal\u0027s entry was. What repeats is a SHAPE, and which shape decides the move. Where the copies declare the same members, the repetition is a missing common ancestor: give it a base type, an interface both extend, a generic instantiated twice, or \u2014 where the copies are a literal\u0027s entries rather than a type\u0027s members \u2014 one shared constant each site spreads or refers to, so the set is written once. Where they declare DIFFERENT members and only the form is shared \u2014 a decorator and its options, an annotation, a registration table\u0027s keys \u2014 the form is prescribed by a framework or a schema rather than copied, and the only collapse available is to generate the declarations from that schema; where you do not own the generator, this is the cost of the framework and there is nothing to extract. Check which of the two it is before acting: these copies still drift apart the first time only one of them is edited, which is why the repetition is reported, but the sentence to act on is not the same in both cases."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"research/syllabus/skills/syllabus/scripts/generate_reading_list.js"},"region":{"startLine":270}}}],"partialFingerprints":{"codehealthFindingId/v1":"dea53877f3bb31670dde337500af39f77e52f81f6882ce236228f1c4aa4370ff"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2 locations): engineering-team/playwright-pro/integrations/testrail-mcp/src/index.ts:203 \u00B7 engineering-team/playwright-pro/integrations/testrail-mcp/src/index.ts:226 \u2014 all 2 copies are in the same file, and the CITED SPAN is not a self-contained block \u2014 it runs from inside one construct into the next (the tail of a branch plus the head of the following one, a run of switch arms, the end of a declaration plus the list that follows it) rather than covering a whole unit. So do not lift these lines literally: no call can be substituted for a half-open construct. Extract the enclosing repeated UNIT instead \u2014 the whole function, component or branch these lines sit in \u2014 and where the repetition IS the construct (a run of switch arms, a stack of near-identical declarations) replace it with one table or registry looked up by key rather than a helper each arm calls. The copies still drift apart the first time only one of them is edited, which is why this is reported."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/playwright-pro/integrations/testrail-mcp/src/index.ts"},"region":{"startLine":203}}}],"partialFingerprints":{"codehealthFindingId/v1":"1227cb9e2dc463f90cb24b67f63d14170efddf72e135cfa3cb710be88e6007d5"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2 locations): engineering/skills/full-page-screenshot/scripts/full-page-screenshot.mjs:397 \u00B7 engineering/skills/full-page-screenshot/scripts/full-page-screenshot.mjs:418 \u2014 all 2 copies are in the same file, and the CITED SPAN is not a self-contained block \u2014 it runs from inside one construct into the next (the tail of a branch plus the head of the following one, a run of switch arms, the end of a declaration plus the list that follows it) rather than covering a whole unit. So do not lift these lines literally: no call can be substituted for a half-open construct. Extract the enclosing repeated UNIT instead \u2014 the whole function, component or branch these lines sit in \u2014 and where the repetition IS the construct (a run of switch arms, a stack of near-identical declarations) replace it with one table or registry looked up by key rather than a helper each arm calls. The copies still drift apart the first time only one of them is edited, which is why this is reported."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/full-page-screenshot/scripts/full-page-screenshot.mjs"},"region":{"startLine":397}}}],"partialFingerprints":{"codehealthFindingId/v1":"8b1fa2206f71d7245f9d251529c6c3f76d235ab5205eb779c4def9ddc30a39e5"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 4 locations): engineering-team/playwright-pro/integrations/browserstack-mcp/src/index.ts:160 \u00B7 engineering-team/playwright-pro/integrations/testrail-mcp/src/index.ts:205 \u00B7 engineering-team/playwright-pro/integrations/testrail-mcp/src/index.ts:216 \u00B7 engineering-team/playwright-pro/integrations/testrail-mcp/src/index.ts:228 \u2014 the 4 copies are spread across 2 files, and the CITED SPAN is not a self-contained block \u2014 it runs from inside one construct into the next (the tail of a branch plus the head of the following one, a run of switch arms, the end of a declaration plus the list that follows it) rather than covering a whole unit. So do not lift these lines literally: no call can be substituted for a half-open construct. Extract the enclosing repeated UNIT instead \u2014 the whole function, component or branch these lines sit in \u2014 and where the repetition IS the construct (a run of switch arms, a stack of near-identical declarations) replace it with one table or registry looked up by key rather than a helper each arm calls. The copies still drift apart the first time only one of them is edited, which is why this is reported."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/playwright-pro/integrations/browserstack-mcp/src/index.ts"},"region":{"startLine":160}}}],"partialFingerprints":{"codehealthFindingId/v1":"42ba9fe114ea9782be101b406dd83af1a6d78b0db16b4255789d26ff30d4f36e"}},{"ruleId":"R2","level":"warning","message":{"text":"Complex function main (cyclomatic 19, cognitive 19): main has cyclomatic complexity 19 and cognitive complexity 19; this row is raised above a cyclomatic bar of 10. The two numbers answer different questions and the gap between them is what decides whether to act: cyclomatic counts the independent arms through the body, cognitive counts what it costs to hold them in your head, so nesting and mixed boolean chains raise it while a flat run of independent arms does not. Cognitive is at or above cyclomatic here, so the branching is nested or entangled rather than laid out side by side \u2014 extracting each decision into its own named function is the change that pays. Measured by this repository\u0027s own parse of the file, so a body assembled at runtime, or generated, is counted as written rather than as it executes."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/hivemind/scripts/oc-worker.mjs"},"region":{"startLine":109}}}],"partialFingerprints":{"codehealthFindingId/v1":"585fc0f3c131b6e9a53d5f994f11b18c1bb14032eaae8eb38ccdfce4b47cfc4f"}},{"ruleId":"R2","level":"warning","message":{"text":"Complex function captureFullPage (cyclomatic 18, cognitive 31): captureFullPage has cyclomatic complexity 18 and cognitive complexity 31; this row is raised above a cyclomatic bar of 10. The two numbers answer different questions and the gap between them is what decides whether to act: cyclomatic counts the independent arms through the body, cognitive counts what it costs to hold them in your head, so nesting and mixed boolean chains raise it while a flat run of independent arms does not. Cognitive is at or above cyclomatic here, so the branching is nested or entangled rather than laid out side by side \u2014 extracting each decision into its own named function is the change that pays. Measured by this repository\u0027s own parse of the file, so a body assembled at runtime, or generated, is counted as written rather than as it executes."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/full-page-screenshot/scripts/full-page-screenshot.mjs"},"region":{"startLine":221}}}],"partialFingerprints":{"codehealthFindingId/v1":"b7f842482a07d6a5b782befbeba54b0378e63113d74f1e97213d971e59185d64"}},{"ruleId":"R2","level":"warning","message":{"text":"Complex function renderUserDashboard (cyclomatic 18, cognitive 27): renderUserDashboard has cyclomatic complexity 18 and cognitive complexity 27; this row is raised above a cyclomatic bar of 10. The two numbers answer different questions and the gap between them is what decides whether to act: cyclomatic counts the independent arms through the body, cognitive counts what it costs to hold them in your head, so nesting and mixed boolean chains raise it while a flat run of independent arms does not. Cognitive is at or above cyclomatic here, so the branching is nested or entangled rather than laid out side by side \u2014 extracting each decision into its own named function is the change that pays. Measured by this repository\u0027s own parse of the file, so a body assembled at runtime, or generated, is counted as written rather than as it executes."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/tech-debt-tracker/assets/sample_codebase/src/frontend.js"},"region":{"startLine":59}}}],"partialFingerprints":{"codehealthFindingId/v1":"a9ef0f96e718343670b83a949fa4dec04ee5d9694204bce6a5260fdd8a7f68a3"}},{"ruleId":"R2","level":"warning","message":{"text":"Complex function modeUrl (cyclomatic 17, cognitive 30): modeUrl has cyclomatic complexity 17 and cognitive complexity 30; this row is raised above a cyclomatic bar of 10. The two numbers answer different questions and the gap between them is what decides whether to act: cyclomatic counts the independent arms through the body, cognitive counts what it costs to hold them in your head, so nesting and mixed boolean chains raise it while a flat run of independent arms does not. Cognitive is at or above cyclomatic here, so the branching is nested or entangled rather than laid out side by side \u2014 extracting each decision into its own named function is the change that pays. Measured by this repository\u0027s own parse of the file, so a body assembled at runtime, or generated, is counted as written rather than as it executes."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/full-page-screenshot/scripts/full-page-screenshot.mjs"},"region":{"startLine":524}}}],"partialFingerprints":{"codehealthFindingId/v1":"f61e4c7965368f332eb4ce572320a433f648f9e8c6c707ba5b10d697f278404b"}},{"ruleId":"R2","level":"warning","message":{"text":"Complex function parseNdjson (cyclomatic 16, cognitive 22): parseNdjson has cyclomatic complexity 16 and cognitive complexity 22; this row is raised above a cyclomatic bar of 10. The two numbers answer different questions and the gap between them is what decides whether to act: cyclomatic counts the independent arms through the body, cognitive counts what it costs to hold them in your head, so nesting and mixed boolean chains raise it while a flat run of independent arms does not. Cognitive is at or above cyclomatic here, so the branching is nested or entangled rather than laid out side by side \u2014 extracting each decision into its own named function is the change that pays. Measured by this repository\u0027s own parse of the file, so a body assembled at runtime, or generated, is counted as written rather than as it executes."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/hivemind/scripts/oc-worker.mjs"},"region":{"startLine":168}}}],"partialFingerprints":{"codehealthFindingId/v1":"c0afa1b912953c59945257d413537c504a485a721f0c3fa9c900cfac0b8b225b"}},{"ruleId":"R2","level":"warning","message":{"text":"Complex function buildAuditLogSection (cyclomatic 16, cognitive 15): buildAuditLogSection has cyclomatic complexity 16 and cognitive complexity 15; this row is raised above a cyclomatic bar of 10. The two numbers answer different questions and the gap between them is what decides whether to act: cyclomatic counts the independent arms through the body, cognitive counts what it costs to hold them in your head, so nesting and mixed boolean chains raise it while a flat run of independent arms does not. Cognitive sits below cyclomatic here, so much of the count is breadth \u2014 arms side by side rather than stacked \u2014 and splitting per arm would leave a function per arm; group the work between the checks into named steps instead. Measured by this repository\u0027s own parse of the file, so a body assembled at runtime, or generated, is counted as written rather than as it executes."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"research/syllabus/skills/syllabus/scripts/generate_reading_list.js"},"region":{"startLine":263}}}],"partialFingerprints":{"codehealthFindingId/v1":"fe1c0c2c846e678876984e73492606374b3e3c1a741213692099628e70f181c7"}},{"ruleId":"R2","level":"warning","message":{"text":"Complex function modeTarget (cyclomatic 15, cognitive 26): modeTarget has cyclomatic complexity 15 and cognitive complexity 26; this row is raised above a cyclomatic bar of 10. The two numbers answer different questions and the gap between them is what decides whether to act: cyclomatic counts the independent arms through the body, cognitive counts what it costs to hold them in your head, so nesting and mixed boolean chains raise it while a flat run of independent arms does not. Cognitive is at or above cyclomatic here, so the branching is nested or entangled rather than laid out side by side \u2014 extracting each decision into its own named function is the change that pays. Measured by this repository\u0027s own parse of the file, so a body assembled at runtime, or generated, is counted as written rather than as it executes."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/full-page-screenshot/scripts/full-page-screenshot.mjs"},"region":{"startLine":871}}}],"partialFingerprints":{"codehealthFindingId/v1":"65fec8eb705ff6ba3b067372498f9dc18cd32ef209a40e5f01d28c4001811e11"}},{"ruleId":"R2","level":"warning","message":{"text":"Complex function (anonymous) (cyclomatic 15, cognitive 13): (anonymous) has cyclomatic complexity 15 and cognitive complexity 13; this row is raised above a cyclomatic bar of 10. The two numbers answer different questions and the gap between them is what decides whether to act: cyclomatic counts the independent arms through the body, cognitive counts what it costs to hold them in your head, so nesting and mixed boolean chains raise it while a flat run of independent arms does not. Cognitive sits below cyclomatic here, so much of the count is breadth \u2014 arms side by side rather than stacked \u2014 and splitting per arm would leave a function per arm; group the work between the checks into named steps instead. Measured by this repository\u0027s own parse of the file, so a body assembled at runtime, or generated, is counted as written rather than as it executes."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/playwright-pro/integrations/browserstack-mcp/src/index.ts"},"region":{"startLine":112}}}],"partialFingerprints":{"codehealthFindingId/v1":"38516410449d893b3d63d0d255960c98110874c0059ed6078fcd9e74b3054880"}},{"ruleId":"R2","level":"warning","message":{"text":"Complex function (anonymous) (cyclomatic 15, cognitive 11): (anonymous) has cyclomatic complexity 15 and cognitive complexity 11; this row is raised above a cyclomatic bar of 10. The two numbers answer different questions and the gap between them is what decides whether to act: cyclomatic counts the independent arms through the body, cognitive counts what it costs to hold them in your head, so nesting and mixed boolean chains raise it while a flat run of independent arms does not. Cognitive sits below cyclomatic here, so much of the count is breadth \u2014 arms side by side rather than stacked \u2014 and splitting per arm would leave a function per arm; group the work between the checks into named steps instead. Measured by this repository\u0027s own parse of the file, so a body assembled at runtime, or generated, is counted as written rather than as it executes."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/playwright-pro/integrations/testrail-mcp/src/index.ts"},"region":{"startLine":170}}}],"partialFingerprints":{"codehealthFindingId/v1":"6a2f8c51955762b6ed577b637f93841caaf79e0cf1dfe280e9f28c862e128c55"}},{"ruleId":"R2","level":"warning","message":{"text":"Complex function captureViaProxy (cyclomatic 14, cognitive 26): captureViaProxy has cyclomatic complexity 14 and cognitive complexity 26; this row is raised above a cyclomatic bar of 10. The two numbers answer different questions and the gap between them is what decides whether to act: cyclomatic counts the independent arms through the body, cognitive counts what it costs to hold them in your head, so nesting and mixed boolean chains raise it while a flat run of independent arms does not. Cognitive is at or above cyclomatic here, so the branching is nested or entangled rather than laid out side by side \u2014 extracting each decision into its own named function is the change that pays. Measured by this repository\u0027s own parse of the file, so a body assembled at runtime, or generated, is counted as written rather than as it executes."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/full-page-screenshot/scripts/full-page-screenshot.mjs"},"region":{"startLine":646}}}],"partialFingerprints":{"codehealthFindingId/v1":"89c267ce806b033b09fb8a3fdfe4467195f029ec316af964f030c2a3fb11b109"}},{"ruleId":"R2","level":"warning","message":{"text":"Complex function parseArgs (cyclomatic 14, cognitive 15): parseArgs has cyclomatic complexity 14 and cognitive complexity 15; this row is raised above a cyclomatic bar of 10. The two numbers answer different questions and the gap between them is what decides whether to act: cyclomatic counts the independent arms through the body, cognitive counts what it costs to hold them in your head, so nesting and mixed boolean chains raise it while a flat run of independent arms does not. Cognitive is at or above cyclomatic here, so the branching is nested or entangled rather than laid out side by side \u2014 extracting each decision into its own named function is the change that pays. Measured by this repository\u0027s own parse of the file, so a body assembled at runtime, or generated, is counted as written rather than as it executes."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/hivemind/scripts/oc-worker.mjs"},"region":{"startLine":39}}}],"partialFingerprints":{"codehealthFindingId/v1":"fc6d997b0e3b120e5c893f146a0be5b4eae141e9c9150c3343c0de75acf8ce37"}},{"ruleId":"R2","level":"warning","message":{"text":"Complex function main (cyclomatic 13, cognitive 16): main has cyclomatic complexity 13 and cognitive complexity 16; this row is raised above a cyclomatic bar of 10. The two numbers answer different questions and the gap between them is what decides whether to act: cyclomatic counts the independent arms through the body, cognitive counts what it costs to hold them in your head, so nesting and mixed boolean chains raise it while a flat run of independent arms does not. Cognitive is at or above cyclomatic here, so the branching is nested or entangled rather than laid out side by side \u2014 extracting each decision into its own named function is the change that pays. Measured by this repository\u0027s own parse of the file, so a body assembled at runtime, or generated, is counted as written rather than as it executes."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/hivemind/scripts/oc-aggregate.mjs"},"region":{"startLine":30}}}],"partialFingerprints":{"codehealthFindingId/v1":"df291eba3546e97dceba077c73bc6e827cae3f00754317262326d90ede7d9b75"}},{"ruleId":"R2","level":"warning","message":{"text":"Complex function loadRun (cyclomatic 13, cognitive 16): loadRun has cyclomatic complexity 13 and cognitive complexity 16; this row is raised above a cyclomatic bar of 10. The two numbers answer different questions and the gap between them is what decides whether to act: cyclomatic counts the independent arms through the body, cognitive counts what it costs to hold them in your head, so nesting and mixed boolean chains raise it while a flat run of independent arms does not. Cognitive is at or above cyclomatic here, so the branching is nested or entangled rather than laid out side by side \u2014 extracting each decision into its own named function is the change that pays. Measured by this repository\u0027s own parse of the file, so a body assembled at runtime, or generated, is counted as written rather than as it executes."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/hivemind/scripts/oc-status.mjs"},"region":{"startLine":7}}}],"partialFingerprints":{"codehealthFindingId/v1":"3394112cdf7e3c4a0ed49b3063953a3cf33817db0ef5c724a0c81cff97a408f4"}},{"ruleId":"R2","level":"warning","message":{"text":"Complex function waitForLoad (cyclomatic 11, cognitive 21): waitForLoad has cyclomatic complexity 11 and cognitive complexity 21; this row is raised above a cyclomatic bar of 10. The two numbers answer different questions and the gap between them is what decides whether to act: cyclomatic counts the independent arms through the body, cognitive counts what it costs to hold them in your head, so nesting and mixed boolean chains raise it while a flat run of independent arms does not. Cognitive is at or above cyclomatic here, so the branching is nested or entangled rather than laid out side by side \u2014 extracting each decision into its own named function is the change that pays. Measured by this repository\u0027s own parse of the file, so a body assembled at runtime, or generated, is counted as written rather than as it executes."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/full-page-screenshot/scripts/full-page-screenshot.mjs"},"region":{"startLine":168}}}],"partialFingerprints":{"codehealthFindingId/v1":"69534a244695a1338c3e83e3d234670a3721021b4a42237cd8f82a7e6a2a307d"}},{"ruleId":"R2","level":"warning","message":{"text":"Complex function validateInput (cyclomatic 11, cognitive 15): validateInput has cyclomatic complexity 11 and cognitive complexity 15; this row is raised above a cyclomatic bar of 10. The two numbers answer different questions and the gap between them is what decides whether to act: cyclomatic counts the independent arms through the body, cognitive counts what it costs to hold them in your head, so nesting and mixed boolean chains raise it while a flat run of independent arms does not. Cognitive is at or above cyclomatic here, so the branching is nested or entangled rather than laid out side by side \u2014 extracting each decision into its own named function is the change that pays. Measured by this repository\u0027s own parse of the file, so a body assembled at runtime, or generated, is counted as written rather than as it executes."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"research/syllabus/skills/syllabus/scripts/generate_reading_list.js"},"region":{"startLine":85}}}],"partialFingerprints":{"codehealthFindingId/v1":"b6bb3f260e7bb79b19b3bd4023cdea4e24ddae37193d0512c6742e9289f5e6b5"}},{"ruleId":"R7","level":"warning","message":{"text":"Dead file (~197 LoC): no import path from any entry point (10 application, 5 tooling, 0 test roots considered), and no other file in the scanned tree imports it \u2014 nothing in-repo names this module at all, which is the strongest form of this claim the import graph can make"},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/hivemind/scripts/oc-worker.mjs"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"69ea9a6b2b421f94256a5c6c0523de86628528636569bcd3e7023e5949764ae1"}},{"ruleId":"R7","level":"warning","message":{"text":"Dead file (~79 LoC): no import path from any entry point (10 application, 5 tooling, 0 test roots considered), and no other file in the scanned tree imports it \u2014 nothing in-repo names this module at all, which is the strongest form of this claim the import graph can make"},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/hivemind/scripts/oc-aggregate.mjs"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"9752ed8535a02caa3478cfa0d44db8c0c407376ea61c67be3b2601ff98102a0d"}},{"ruleId":"R7","level":"warning","message":{"text":"Dead file (~46 LoC): no import path from any entry point (10 application, 5 tooling, 0 test roots considered), and no other file in the scanned tree imports it \u2014 nothing in-repo names this module at all, which is the strongest form of this claim the import graph can make"},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/hivemind/scripts/oc-status.mjs"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"2498b2d479df7760ae5085c772d362874d7e93f13b84abb1bfb4d4901e753377"}},{"ruleId":"R7","level":"warning","message":{"text":"Dead file (~45 LoC): no import path from any entry point (10 application, 5 tooling, 0 test roots considered), and no other file in the scanned tree imports it \u2014 nothing in-repo names this module at all, which is the strongest form of this claim the import graph can make"},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/workflow-builder/skills/workflow-builder/expected_outputs/scaffold_pipeline.js"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"99bafe5f09ab53d19aa402a796125ddcea37668d490c86b87017f55d53f6b52b"}},{"ruleId":"R7","level":"note","message":{"text":"Unused export \u0027TestRailSection\u0027: Nothing imports this binding \u2014 it is safe to review for removal."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/playwright-pro/integrations/testrail-mcp/src/types.ts"},"region":{"startLine":24}}}],"partialFingerprints":{"codehealthFindingId/v1":"bd4b5590a4d6a0a764d934074bac5a2cecda58509b20a1f26d05618761cf3773"}},{"ruleId":"R7","level":"note","message":{"text":"Unused module-local declaration \u0027proxyScroll\u0027: This top-level declaration is not exported and its name occurs nowhere else in its module \u2014 not called, read, typed against, re-exported or named by a string. Nothing outside the module can reach a non-exported binding, so this is the whole search: remove it, or use it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/full-page-screenshot/scripts/full-page-screenshot.mjs"},"region":{"startLine":639}}}],"partialFingerprints":{"codehealthFindingId/v1":"19d72cb5a7c4d5e8cadb5fa55b6c173a28223b1c3b23f7d0d4e770bf35bde447"}},{"ruleId":"R8","level":"error","message":{"text":"Unlisted import \u0027react\u0027: Imported but not declared in any reachable package.json \u2014 installs work only by hoisting accident."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/a11y-audit/skills/a11y-audit/assets/sample-component.tsx"},"region":{"startLine":2}}}],"partialFingerprints":{"codehealthFindingId/v1":"5a3b5113e061c9a5f6c3291e358f469b694e8ac9efcf91a804414083801ac085"}},{"ruleId":"S1","level":"warning","message":{"text":"Third-party script without Subresource Integrity: \u0060https://cdn.jsdelivr.net/npm/prismjs@1.29.0/components/prism-core.min.js\u0060 is executed by this page with no Subresource Integrity. Whoever can answer that request \u2014 the CDN, anyone who compromises it, anyone on the network path \u2014 runs arbitrary script in this page\u0027s origin, with its session. 8 such include(s) across the repository\u0027s markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":".codex/skills/md-document/assets/md_document_template.html"},"region":{"startLine":97}}}],"partialFingerprints":{"codehealthFindingId/v1":"89a91b8c7c7b820552372f115abc93eeffa4eac5b5e498e001cef9fb89d18d96"}},{"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"}},{"ruleId":"X1","level":"warning","message":{"text":"async void method: HandleClick: \u0060async void\u0060 can\u0027t be awaited and its exceptions crash the process instead of propagating. Return \u0060Task\u0060 \u2014 or, where the delegate contract requires void (timer/event/callback registrations), make this a thin void shim that awaits a Task-returning inner method inside try/catch so exceptions are contained."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/skills/code-reviewer/assets/sample_csharp_smells.cs"},"region":{"startLine":25}}}],"partialFingerprints":{"codehealthFindingId/v1":"8682a0ad4453f526d526eaac355b777eba4967df0174c8b2bffeabaacb1d3726"}},{"ruleId":"X1","level":"warning","message":{"text":"Sync-over-async (deadlock risk) through \u0060.Result\u0060: Reading \u0060.Result\u0060 of a task that has not completed blocks this thread until it does \u2014 the same block as \u0060.Wait()\u0060: under a synchronization context (Blazor, a UI thread, classic ASP.NET) it deadlocks, and on the thread pool it parks a thread for as long as the work runs. \u0060await\u0060 the task instead (make the caller \u0060async\u0060); where a synchronous entry point must stay, keep the block in ONE documented bridge with a timeout."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/skills/code-reviewer/assets/sample_csharp_smells.cs"},"region":{"startLine":28}}}],"partialFingerprints":{"codehealthFindingId/v1":"299b12bc50b338d4aa6887da3973d6eb66b1451141dad88b2128e697fc6aa05b"}},{"ruleId":"X10","level":"note","message":{"text":"Duplicated predicate: \u0060\u0022--interactive\u0022 in sys.argv or \u0022-i\u0022 in sys.argv\u0060 appears character-identically in 2 files \u2014 c-level-advisor/skills/org-health-diagnostic/scripts/health_scorer.py, c-level-advisor/skills/scenario-war-room/scripts/scenario_modeler.py. It is one line, so the duplication detector\u0027s token window never sees it; the copies drift when only one is corrected. Give the condition a name and one home."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"c-level-advisor/skills/org-health-diagnostic/scripts/health_scorer.py"},"region":{"startLine":554}}}],"partialFingerprints":{"codehealthFindingId/v1":"ff225835f76e815609f065f7eb4f9ee49d6c5a25cd23296dcf9d9026bccbc96c"}},{"ruleId":"X10","level":"note","message":{"text":"Duplicated predicate: \u0060\u0022:\u0022 in line and not line.lstrip().startswith(\u0022#\u0022)\u0060 appears character-identically in 2 files \u2014 engineering/llm-wiki/skills/llm-wiki/scripts/lint_wiki.py, engineering/llm-wiki/skills/llm-wiki/scripts/update_index.py. It is one line, so the duplication detector\u0027s token window never sees it; the copies drift when only one is corrected. Give the condition a name and one home."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/llm-wiki/skills/llm-wiki/scripts/lint_wiki.py"},"region":{"startLine":38}}}],"partialFingerprints":{"codehealthFindingId/v1":"38e2cdf18ad074aa549cc358528e6018a271afab5dfafd7ef41108954e5697f9"}},{"ruleId":"X10","level":"note","message":{"text":"Duplicated predicate: \u0060\u0022:\u0022 in line and not line.startswith(\u0022#\u0022)\u0060 appears character-identically in 2 files \u2014 engineering/agenthub/skills/agenthub/scripts/result_ranker.py, engineering/agenthub/skills/agenthub/scripts/session_manager.py. It is one line, so the duplication detector\u0027s token window never sees it; the copies drift when only one is corrected. Give the condition a name and one home."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/agenthub/skills/agenthub/scripts/result_ranker.py"},"region":{"startLine":47}}}],"partialFingerprints":{"codehealthFindingId/v1":"2bf829b613881124b6b34d10d810312f8f695ed4db7af2da6e650aa3485aa11c"}},{"ruleId":"X10","level":"note","message":{"text":"Duplicated predicate: \u0060\u0022:\u0022 in line and not line.strip().startswith(\u0022#\u0022)\u0060 appears character-identically in 2 files \u2014 scripts/sync-hermes-skills.py, scripts/sync-vibe-skills.py. It is one line, so the duplication detector\u0027s token window never sees it; the copies drift when only one is corrected. Give the condition a name and one home."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"scripts/sync-hermes-skills.py"},"region":{"startLine":142}}}],"partialFingerprints":{"codehealthFindingId/v1":"bd3cf93a5196827e5166ce868d512ff6c9d08ccefbe4bb92e9b0d2b56972e540"}},{"ruleId":"X10","level":"note","message":{"text":"Duplicated predicate: \u0060\u0022IL\u0022 in states and domain == \u0022employment\u0022\u0060 appears character-identically in 2 files \u2014 c-level-advisor/chief-ai-officer-advisor/skills/chief-ai-officer-advisor/scripts/ai_risk_classifier.py, c-level-advisor/skills/chief-ai-officer-advisor/scripts/ai_risk_classifier.py. It is one line, so the duplication detector\u0027s token window never sees it; the copies drift when only one is corrected. Give the condition a name and one home."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"c-level-advisor/chief-ai-officer-advisor/skills/chief-ai-officer-advisor/scripts/ai_risk_classifier.py"},"region":{"startLine":226}}}],"partialFingerprints":{"codehealthFindingId/v1":"4f0e73ff1855f9a8a5666dd660e9eeff556eafaf622c470765c43e587f7ab001"}},{"ruleId":"X10","level":"note","message":{"text":"Duplicated predicate: \u0060\u0022IL\u0022 in states and profile.get(\u0022biometric_data_processed\u0022, False)\u0060 appears character-identically in 2 files \u2014 c-level-advisor/chief-ai-officer-advisor/skills/chief-ai-officer-advisor/scripts/ai_risk_classifier.py, c-level-advisor/skills/chief-ai-officer-advisor/scripts/ai_risk_classifier.py. It is one line, so the duplication detector\u0027s token window never sees it; the copies drift when only one is corrected. Give the condition a name and one home."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"c-level-advisor/chief-ai-officer-advisor/skills/chief-ai-officer-advisor/scripts/ai_risk_classifier.py"},"region":{"startLine":247}}}],"partialFingerprints":{"codehealthFindingId/v1":"f0599ca04d29e30cb2a0bd2dbfbf4564b9e06088f535cc9f97d6ece2b4634742"}},{"ruleId":"X10","level":"note","message":{"text":"Duplicated predicate: \u0060\u0022LeaderElection\u0022 in c or \u0022leader-elect\u0022 in c\u0060 appears character-identically in 2 files \u2014 engineering/kubernetes-operator/skills/kubernetes-operator/scripts/operator_capability_audit.py, engineering/skills/kubernetes-operator/scripts/operator_capability_audit.py. It is one line, so the duplication detector\u0027s token window never sees it; the copies drift when only one is corrected. Give the condition a name and one home."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/kubernetes-operator/skills/kubernetes-operator/scripts/operator_capability_audit.py"},"region":{"startLine":30}}}],"partialFingerprints":{"codehealthFindingId/v1":"e9a78d9c7aa791a29fb6c5c5165019b63d068443f802f39b8d1024128176b62a"}},{"ruleId":"X10","level":"note","message":{"text":"Duplicated predicate: \u0060\u0022NY\u0022 in states and domain == \u0022employment\u0022\u0060 appears character-identically in 2 files \u2014 c-level-advisor/chief-ai-officer-advisor/skills/chief-ai-officer-advisor/scripts/ai_risk_classifier.py, c-level-advisor/skills/chief-ai-officer-advisor/scripts/ai_risk_classifier.py. It is one line, so the duplication detector\u0027s token window never sees it; the copies drift when only one is corrected. Give the condition a name and one home."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"c-level-advisor/chief-ai-officer-advisor/skills/chief-ai-officer-advisor/scripts/ai_risk_classifier.py"},"region":{"startLine":202}}}],"partialFingerprints":{"codehealthFindingId/v1":"e2e890310bb8f11cd16e626690bff9749dd8e35ed0e1dde3b0c30a30e6557f8e"}},{"ruleId":"X10","level":"note","message":{"text":"Duplicated predicate: \u0060\u0022agents\u0022 in parts or \u0022commands\u0022 in parts\u0060 appears character-identically in 2 files \u2014 scripts/check_frontmatter.py, scripts/check_paths.py. It is one line, so the duplication detector\u0027s token window never sees it; the copies drift when only one is corrected. Give the condition a name and one home."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"scripts/check_frontmatter.py"},"region":{"startLine":167}}}],"partialFingerprints":{"codehealthFindingId/v1":"5a0c223826305df5aa99b828319b6234f39740b92f05670703c2b019edcfd1cf"}},{"ruleId":"X10","level":"note","message":{"text":"Duplicated predicate: \u0060\u0022chatbot\u0022 in use_case or \u0022deepfake\u0022 in use_case or \u0022image generation\u0022 in use_case or \u0022video generation\u0022 in use_case\u0060 appears character-identically in 2 files \u2014 c-level-advisor/chief-ai-officer-advisor/skills/chief-ai-officer-advisor/scripts/ai_risk_classifier.py, c-level-advisor/skills/chief-ai-officer-advisor/scripts/ai_risk_classifier.py. It is one line, so the duplication detector\u0027s token window never sees it; the copies drift when only one is corrected. Give the condition a name and one home."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"c-level-advisor/chief-ai-officer-advisor/skills/chief-ai-officer-advisor/scripts/ai_risk_classifier.py"},"region":{"startLine":164}}}],"partialFingerprints":{"codehealthFindingId/v1":"9b0bcf6393bb3ddf62743ed3b2c987baca83f774b02aa96af38e4e7b05439768"}},{"ruleId":"X10","level":"note","message":{"text":"Duplicated predicate: \u0060\u0022controllerutil.AddFinalizer\u0022 in src or re.search(r\u0022finalizers\\s*=\u0022, src)\u0060 appears character-identically in 2 files \u2014 engineering/kubernetes-operator/skills/kubernetes-operator/scripts/reconcile_lint.py, engineering/skills/kubernetes-operator/scripts/reconcile_lint.py. It is one line, so the duplication detector\u0027s token window never sees it; the copies drift when only one is corrected. Give the condition a name and one home."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/kubernetes-operator/skills/kubernetes-operator/scripts/reconcile_lint.py"},"region":{"startLine":109}}}],"partialFingerprints":{"codehealthFindingId/v1":"913403bde9a0e6b98daba6cbe78fd1bef142f43499b939efbfa68ca5824989ee"}},{"ruleId":"X10","level":"note","message":{"text":"Duplicated predicate: \u0060\u0022conversion\u0022 in c.lower() and \u0022webhook\u0022 in c.lower()\u0060 appears character-identically in 2 files \u2014 engineering/kubernetes-operator/skills/kubernetes-operator/scripts/operator_capability_audit.py, engineering/skills/kubernetes-operator/scripts/operator_capability_audit.py. It is one line, so the duplication detector\u0027s token window never sees it; the copies drift when only one is corrected. Give the condition a name and one home."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/kubernetes-operator/skills/kubernetes-operator/scripts/operator_capability_audit.py"},"region":{"startLine":29}}}],"partialFingerprints":{"codehealthFindingId/v1":"5b03e8f81bcbf4259968fde6bbfef6f9003f0d64e96c5d985854d689f7e315fb"}},{"ruleId":"X10","level":"note","message":{"text":"Duplicated predicate: \u0060\u0022improve-pipeline-reliability\u0022 in priorities or \u0022reliability\u0022 in str(priorities)\u0060 appears character-identically in 2 files \u2014 c-level-advisor/chief-data-officer-advisor/skills/chief-data-officer-advisor/scripts/data_product_strategy_picker.py, c-level-advisor/skills/chief-data-officer-advisor/scripts/data_product_strategy_picker.py. It is one line, so the duplication detector\u0027s token window never sees it; the copies drift when only one is corrected. Give the condition a name and one home."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"c-level-advisor/chief-data-officer-advisor/skills/chief-data-officer-advisor/scripts/data_product_strategy_picker.py"},"region":{"startLine":206}}}],"partialFingerprints":{"codehealthFindingId/v1":"e8b28a9adb3d0d11763388a9dc11a8589f8fd6f6ed8ff9fc7fe6e9583864d152"}},{"ruleId":"X10","level":"note","message":{"text":"Duplicated predicate: \u0060\u0022metav1.Condition\u0022 in c or \u0022SetStatusCondition\u0022 in c\u0060 appears character-identically in 2 files \u2014 engineering/kubernetes-operator/skills/kubernetes-operator/scripts/operator_capability_audit.py, engineering/skills/kubernetes-operator/scripts/operator_capability_audit.py. It is one line, so the duplication detector\u0027s token window never sees it; the copies drift when only one is corrected. Give the condition a name and one home."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/kubernetes-operator/skills/kubernetes-operator/scripts/operator_capability_audit.py"},"region":{"startLine":35}}}],"partialFingerprints":{"codehealthFindingId/v1":"ea377ec6c5875e614351d928a203a2b64f267b66cc4d82ef1948014b51bc9df9"}},{"ruleId":"X10","level":"note","message":{"text":"Duplicated predicate: \u0060\u0027@Test\u0027 in code and \u0027import org.junit\u0027 in code\u0060 appears character-identically in 2 files \u2014 engineering-team/skills/tdd-guide/scripts/format_detector.py, engineering-team/skills/tdd-guide/scripts/framework_adapter.py. It is one line, so the duplication detector\u0027s token window never sees it; the copies drift when only one is corrected. Give the condition a name and one home."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/skills/tdd-guide/scripts/format_detector.py"},"region":{"startLine":137}}}],"partialFingerprints":{"codehealthFindingId/v1":"201c6e233c85114c69b516771b9d4136d04e149fe1cdb247c44ac8ff1dfcd52f"}},{"ruleId":"X10","level":"note","message":{"text":"Duplicated predicate: \u0060\u0027from \\\u0027@jest/globals\\\u0027\u0027 in code or \u0027@jest/\u0027 in code\u0060 appears character-identically in 2 files \u2014 engineering-team/skills/tdd-guide/scripts/format_detector.py, engineering-team/skills/tdd-guide/scripts/framework_adapter.py. It is one line, so the duplication detector\u0027s token window never sees it; the copies drift when only one is corrected. Give the condition a name and one home."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/skills/tdd-guide/scripts/format_detector.py"},"region":{"startLine":117}}}],"partialFingerprints":{"codehealthFindingId/v1":"9ad6bf689cab60863efd69f80e1d9cbed52ea5516ed7123fac9b6fa1ac8e620f"}},{"ruleId":"X10","level":"note","message":{"text":"Duplicated predicate: \u0060\u0027from \\\u0027vitest\\\u0027\u0027 in code or \u0027import { vi }\u0027 in code\u0060 appears character-identically in 2 files \u2014 engineering-team/skills/tdd-guide/scripts/format_detector.py, engineering-team/skills/tdd-guide/scripts/framework_adapter.py. It is one line, so the duplication detector\u0027s token window never sees it; the copies drift when only one is corrected. Give the condition a name and one home."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/skills/tdd-guide/scripts/format_detector.py"},"region":{"startLine":122}}}],"partialFingerprints":{"codehealthFindingId/v1":"6a9fe48a5a4aa248ef7861f1375a0b128b505e0902676794f26595056840b92d"}},{"ruleId":"X10","level":"note","message":{"text":"Duplicated predicate: \u0060\u0027import unittest\u0027 in code and \u0027unittest.TestCase\u0027 in code\u0060 appears character-identically in 2 files \u2014 engineering-team/skills/tdd-guide/scripts/format_detector.py, engineering-team/skills/tdd-guide/scripts/framework_adapter.py. It is one line, so the duplication detector\u0027s token window never sees it; the copies drift when only one is corrected. Give the condition a name and one home."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/skills/tdd-guide/scripts/format_detector.py"},"region":{"startLine":132}}}],"partialFingerprints":{"codehealthFindingId/v1":"c9096c9e935a0045f1c4bd6c36bfd8b95c680ef8307944d22e224acc23fce88b"}},{"ruleId":"X10","level":"note","message":{"text":"Duplicated predicate: \u0060_read_json(GLOBAL_CONFIG_PATH) or _read_json(project_config_path())\u0060 appears character-identically in 5 files \u2014 markdown-html/skills/design-system/scripts/config_loader.py, research-ops/skills/clinical-research/scripts/config_loader.py, research-ops/skills/market-research/scripts/config_loader.py, research-ops/skills/product-research/scripts/config_loader.py. It is one line, so the duplication detector\u0027s token window never sees it; the copies drift when only one is corrected. Give the condition a name and one home."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"markdown-html/skills/design-system/scripts/config_loader.py"},"region":{"startLine":104}}}],"partialFingerprints":{"codehealthFindingId/v1":"bd7dddb6427108e3a321f31ee4f1feebb6360ed0bd8382c72551c47464110798"}},{"ruleId":"X10","level":"note","message":{"text":"Duplicated predicate: \u0060accuracy == \u0022frontier\u0022 and monthly_q \u003E 1_000_000_000 and ml_capacity \u003E= 20\u0060 appears character-identically in 2 files \u2014 c-level-advisor/chief-ai-officer-advisor/skills/chief-ai-officer-advisor/scripts/model_buildvsbuy_calculator.py, c-level-advisor/skills/chief-ai-officer-advisor/scripts/model_buildvsbuy_calculator.py. It is one line, so the duplication detector\u0027s token window never sees it; the copies drift when only one is corrected. Give the condition a name and one home."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"c-level-advisor/chief-ai-officer-advisor/skills/chief-ai-officer-advisor/scripts/model_buildvsbuy_calculator.py"},"region":{"startLine":152}}}],"partialFingerprints":{"codehealthFindingId/v1":"c6160ab0adcff94ce43bbdd9cdc0e0312c226d69f17bd3333db4663ae2f5a5d5"}},{"ruleId":"X10","level":"note","message":{"text":"Duplicated predicate: \u0060age is not None and age \u003E max_age_days and len(paths) \u003C= min_uses\u0060 appears character-identically in 2 files \u2014 engineering/feature-flags-architect/skills/feature-flags-architect/scripts/flag_debt_scanner.py, engineering/skills/feature-flags-architect/scripts/flag_debt_scanner.py. It is one line, so the duplication detector\u0027s token window never sees it; the copies drift when only one is corrected. Give the condition a name and one home."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/feature-flags-architect/skills/feature-flags-architect/scripts/flag_debt_scanner.py"},"region":{"startLine":86}}}],"partialFingerprints":{"codehealthFindingId/v1":"1d6f28a636922c48a629e89e0766a807fe080d474a6f9ed75d154c621b1f2982"}},{"ruleId":"X10","level":"note","message":{"text":"Duplicated predicate: \u0060annex_iii and annex_iii in ANNEX_III_CATEGORIES\u0060 appears character-identically in 2 files \u2014 ra-qm-team/compliance-team-eu-ai-act/skills/eu-ai-act-specialist/scripts/ai_system_risk_classifier.py, ra-qm-team/skills/eu-ai-act-specialist/scripts/ai_system_risk_classifier.py. It is one line, so the duplication detector\u0027s token window never sees it; the copies drift when only one is corrected. Give the condition a name and one home."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"ra-qm-team/compliance-team-eu-ai-act/skills/eu-ai-act-specialist/scripts/ai_system_risk_classifier.py"},"region":{"startLine":195}}}],"partialFingerprints":{"codehealthFindingId/v1":"8b575309b1cb39943b7685e7530c3ddc25fec6ac8536cbbd7860bc49547c1e6f"}},{"ruleId":"X10","level":"note","message":{"text":"Duplicated predicate: \u0060args.abort_if or \u0022\u003Cmust define abort criteria\u003E\u0022\u0060 appears character-identically in 2 files \u2014 engineering/chaos-engineering/skills/chaos-engineering/scripts/experiment_designer.py, engineering/skills/chaos-engineering/scripts/experiment_designer.py. It is one line, so the duplication detector\u0027s token window never sees it; the copies drift when only one is corrected. Give the condition a name and one home."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/chaos-engineering/skills/chaos-engineering/scripts/experiment_designer.py"},"region":{"startLine":48}}}],"partialFingerprints":{"codehealthFindingId/v1":"7f5828725e18e5940e5c535bea1ea45a61552dcfbb2686aeb240159ff3de2b3b"}},{"ruleId":"X10","level":"note","message":{"text":"Duplicated predicate: \u0060args.author or config.get(\u0022default_author\u0022, \u0022Claude\u0022)\u0060 appears character-identically in 2 files \u2014 engineering/skills/tc-tracker/scripts/tc_create.py, engineering/skills/tc-tracker/scripts/tc_update.py. It is one line, so the duplication detector\u0027s token window never sees it; the copies drift when only one is corrected. Give the condition a name and one home."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/tc-tracker/scripts/tc_create.py"},"region":{"startLine":181}}}],"partialFingerprints":{"codehealthFindingId/v1":"e969e072842e471b3288d17e0314ace16732d61e1c74ab8de5789861ef424a52"}},{"ruleId":"X10","level":"note","message":{"text":"Duplicated predicate: \u0060args.baseline_mean is None or args.baseline_std is None\u0060 appears character-identically in 2 files \u2014 engineering-team/skills/threat-detection/scripts/threat_signal_analyzer.py, engineering/statistical-analyst/skills/statistical-analyst/scripts/sample_size_calculator.py. It is one line, so the duplication detector\u0027s token window never sees it; the copies drift when only one is corrected. Give the condition a name and one home."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/skills/threat-detection/scripts/threat_signal_analyzer.py"},"region":{"startLine":520}}}],"partialFingerprints":{"codehealthFindingId/v1":"7d4bbe6d60bec28ea6bc202c61bd02a4eec67ecfe37c5a945e65ee4f8145129b"}},{"ruleId":"X2","level":"note","message":{"text":"Not all async methods take a CancellationToken: Only 0/4 async methods accept a CancellationToken, so in-flight work can\u0027t be stopped early when the caller gives up \u2014 whatever ends it in your host (shutdown signal, timeout, abandoned request, user cancel). Thread a token through the call chain and honour it at each await and loop; where a method genuinely cannot be interrupted, omitting it is a deliberate choice \u2014 judge against your hosting model."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"bf623a92fb752b336427856888a9b386c434e686662a2cdc1bba21832c0a048c"}},{"ruleId":"X2","level":"warning","message":{"text":"Async method without CancellationToken: HandleClickAsync: No CancellationToken parameter \u2014 this work can\u0027t be stopped early once started."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/skills/code-reviewer/assets/sample_csharp_clean.cs"},"region":{"startLine":43}}}],"partialFingerprints":{"codehealthFindingId/v1":"8263eb69f92c86400a1fb0d503b916d6fd550b60813e4b50eb172b9363b0dddd"}},{"ruleId":"X2","level":"warning","message":{"text":"Async method without CancellationToken: FetchAsync: No CancellationToken parameter \u2014 this work can\u0027t be stopped early once started."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/skills/code-reviewer/assets/sample_csharp_clean.cs"},"region":{"startLine":50}}}],"partialFingerprints":{"codehealthFindingId/v1":"7578e004731db12d472af7a780269eb9074dbba8cc9a366a12f6a247736edaeb"}},{"ruleId":"X2","level":"warning","message":{"text":"Async method without CancellationToken: HandleClick: No CancellationToken parameter \u2014 this work can\u0027t be stopped early once started."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/skills/code-reviewer/assets/sample_csharp_smells.cs"},"region":{"startLine":25}}}],"partialFingerprints":{"codehealthFindingId/v1":"155c2ded2d037d52e2d56aeb9d134028ba4f259a2809b80c61995134c3392b35"}},{"ruleId":"X2","level":"warning","message":{"text":"Async method without CancellationToken: FetchAsync: No CancellationToken parameter \u2014 this work can\u0027t be stopped early once started."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/skills/code-reviewer/assets/sample_csharp_smells.cs"},"region":{"startLine":33}}}],"partialFingerprints":{"codehealthFindingId/v1":"c6211a8c620a68e531471967d9780c4e1dea6c3c88af23fd12b3bdf3e8445782"}},{"ruleId":"X3","level":"warning","message":{"text":"Swallowed exception (empty catch): An empty catch block silently discards the error \u2014 failures vanish with no log and no rethrow. Log it, handle it, or don\u0027t catch it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/skills/code-reviewer/assets/sample_csharp_smells.cs"},"region":{"startLine":49}}}],"partialFingerprints":{"codehealthFindingId/v1":"757601f3c9fcaecd7b90bf091fc1872245fc19ad136ba64ac8dad4ae31b76faa"}},{"ruleId":"X5","level":"note","message":{"text":"Nullable reference types not enabled everywhere: 0/2 C# file(s) are in a nullable-enabled context. This repository commits no project file, so nothing sets \u003CNullable\u003Eenable\u003C/Nullable\u003E for it: a file is enabled only by its own \u0060#nullable enable\u0060, by a Unity \u0060csc.rsp\u0060 with \u0060-nullable:enable\u0060 for its assembly, or as a file-based app (\u0060#:\u0060 directives) whose \u0060#:property Nullable\u0060 does not turn it off. NRTs catch a whole class of null-deref bugs at compile time."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"80b24de9378624a0ce4846d60457395befcaec8e109ea81d289a370c9f7bfd5d"}},{"ruleId":"X7","level":"note","message":{"text":"Silent fallback default in catch: \u0060main\u0060 swallows every exception into \u0060return 0\u0060 \u2014 a data error becomes a silent behavior change with no trail. Log the failure or let it raise. If that constant is the correct answer rather than a stand-in for a value that could not be read, say so in a comment on the handler or in the docstring, and the row stops firing."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"agent-launcher/hooks/session_end.py"},"region":{"startLine":51}}}],"partialFingerprints":{"codehealthFindingId/v1":"663c6d38cd9b4fd64b0b6a583313a416824930c3f494a8cf0be520c2a8242daa"}},{"ruleId":"X7","level":"note","message":{"text":"Silent fallback default in catch: \u0060main\u0060 swallows every exception into \u0060return 0\u0060 \u2014 a data error becomes a silent behavior change with no trail. Log the failure or let it raise. If that constant is the correct answer rather than a stand-in for a value that could not be read, say so in a comment on the handler or in the docstring, and the row stops firing."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"agent-launcher/hooks/session_start.py"},"region":{"startLine":76}}}],"partialFingerprints":{"codehealthFindingId/v1":"98978b7f10a2e4069eb571c3dbdc9a3efcfe852c74be9b1e256b1565c78dc756"}},{"ruleId":"X7","level":"note","message":{"text":"Silent fallback default on parse failure: \u0060_load\u0060 returns \u0060{}\u0060 when \u0060(json.JSONDecodeError, OSError)\u0060 is raised, with no log or raise \u2014 a malformed value silently becomes that default. Log the input or fail validation. If that constant is the correct answer rather than a stand-in for a value that could not be read, say so in a comment on the handler or in the docstring, and the row stops firing."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"agent-launcher/skills/agent-launcher-orchestrator/scripts/goal_state.py"},"region":{"startLine":43}}}],"partialFingerprints":{"codehealthFindingId/v1":"b9c871c19bd22fc6d52840ff47717df1dc5be5cdda7ee2215525625c015d1f85"}},{"ruleId":"X7","level":"note","message":{"text":"Silent fallback default on parse failure: \u0060_compute_iso\u0060 returns \u0060\u0027\u0027\u0060 when \u0060ValueError\u0060 is raised, with no log or raise \u2014 a malformed value silently becomes that default. Log the input or fail validation. If that constant is the correct answer rather than a stand-in for a value that could not be read, say so in a comment on the handler or in the docstring, and the row stops firing."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"business-operations/skills/internal-comms/scripts/comms_calendar_builder.py"},"region":{"startLine":73}}}],"partialFingerprints":{"codehealthFindingId/v1":"01c0b780fa714ddabdfd1bf3394e71f61cb22babaa8332b967f3ab99ca241b7f"}},{"ruleId":"X7","level":"note","message":{"text":"Silent fallback default on parse failure: \u0060_calculate_quarter_progress\u0060 returns \u00600.5\u0060 when \u0060(ValueError, TypeError)\u0060 is raised, with no log or raise \u2014 a malformed value silently becomes that default. Log the input or fail validation. If that constant is the correct answer rather than a stand-in for a value that could not be read, say so in a comment on the handler or in the docstring, and the row stops firing."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"c-level-advisor/skills/coo-advisor/scripts/okr_tracker.py"},"region":{"startLine":788}}}],"partialFingerprints":{"codehealthFindingId/v1":"510ba282ee4fa0d89b5beb1a5b7dfcba99325dabb24a650a5d03b0babaa7275b"}},{"ruleId":"X7","level":"note","message":{"text":"Silent fallback default in catch: \u0060read_file_content\u0060 swallows every exception into \u0060return \u0027\u0027\u0060 \u2014 a data error becomes a silent behavior change with no trail. Log the failure or let it raise. If that constant is the correct answer rather than a stand-in for a value that could not be read, say so in a comment on the handler or in the docstring, and the row stops firing."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering-team/skills/code-reviewer/scripts/code_quality_checker.py"},"region":{"startLine":71}}}],"partialFingerprints":{"codehealthFindingId/v1":"6e30220152355fb857088c9c965ee8f68c4287c3c9aab71002e92275a671e8f6"}},{"ruleId":"X7","level":"note","message":{"text":"Silent fallback default in catch: \u0060main\u0060 swallows every exception into \u0060return 0\u0060 \u2014 a data error becomes a silent behavior change with no trail. Log the failure or let it raise. If that constant is the correct answer rather than a stand-in for a value that could not be read, say so in a comment on the handler or in the docstring, and the row stops firing."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/agent-memory/hooks/session_end.py"},"region":{"startLine":42}}}],"partialFingerprints":{"codehealthFindingId/v1":"803fc545835d97e66cb685430fbd8d6bc5a6f736e7c429067f5ee6c7edf49db0"}},{"ruleId":"X7","level":"note","message":{"text":"Silent fallback default in catch: \u0060main\u0060 swallows every exception into \u0060return 0\u0060 \u2014 a data error becomes a silent behavior change with no trail. Log the failure or let it raise. If that constant is the correct answer rather than a stand-in for a value that could not be read, say so in a comment on the handler or in the docstring, and the row stops firing."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/agent-memory/hooks/session_start.py"},"region":{"startLine":129}}}],"partialFingerprints":{"codehealthFindingId/v1":"706048ad47339f7537ea5ee38b5827737179fbcc0e4f225944746e400ccc3d1a"}},{"ruleId":"X7","level":"note","message":{"text":"Silent fallback default in catch: \u0060main\u0060 swallows every exception into \u0060return 0\u0060 \u2014 a data error becomes a silent behavior change with no trail. Log the failure or let it raise. If that constant is the correct answer rather than a stand-in for a value that could not be read, say so in a comment on the handler or in the docstring, and the row stops firing."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/agent-memory/hooks/user_prompt_submit.py"},"region":{"startLine":132}}}],"partialFingerprints":{"codehealthFindingId/v1":"ba9ce4f09cd700daa84cf29df2a25721d59e93cc34dd5f3b7663d298df550097"}},{"ruleId":"X7","level":"note","message":{"text":"Silent fallback default on parse failure: \u0060read\u0060 returns \u0060[]\u0060 when \u0060json.JSONDecodeError\u0060 is raised, with no log or raise \u2014 a malformed value silently becomes that default. Log the input or fail validation. If that constant is the correct answer rather than a stand-in for a value that could not be read, say so in a comment on the handler or in the docstring, and the row stops firing."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/agent-memory/skills/agent-memory/scripts/memory_core.py"},"region":{"startLine":213}}}],"partialFingerprints":{"codehealthFindingId/v1":"43c26c84fcadca6d5380960499a6c51b50a861625ba2fe5e636cbd01c8829861"}},{"ruleId":"X7","level":"note","message":{"text":"Silent fallback default on parse failure: \u0060get_branch_commit_count\u0060 returns \u00600\u0060 when \u0060ValueError\u0060 is raised, with no log or raise \u2014 a malformed value silently becomes that default. Log the input or fail validation. If that constant is the correct answer rather than a stand-in for a value that could not be read, say so in a comment on the handler or in the docstring, and the row stops firing."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/agenthub/skills/agenthub/scripts/dag_analyzer.py"},"region":{"startLine":58}}}],"partialFingerprints":{"codehealthFindingId/v1":"4dc72c0415b2e339beb9062b7fb98bdd3bf84a9bedbe80be28bab86226cbe795"}},{"ruleId":"X7","level":"note","message":{"text":"Silent fallback default in catch: \u0060count_epub_chapters\u0060 swallows every exception into \u0060return 0\u0060 \u2014 a data error becomes a silent behavior change with no trail. Log the failure or let it raise. If that constant is the correct answer rather than a stand-in for a value that could not be read, say so in a comment on the handler or in the docstring, and the row stops firing."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/book-to-skill/skills/book-to-skill/scripts/book_to_skill/parsers/epub.py"},"region":{"startLine":142}}}],"partialFingerprints":{"codehealthFindingId/v1":"621496393a5ddb29fb7ccbbde9a1ed42fac17ef6e57289628179658d686e6898"}},{"ruleId":"X7","level":"note","message":{"text":"Silent fallback default in catch: \u0060count_pages\u0060 swallows every exception into \u0060return 0\u0060 \u2014 a data error becomes a silent behavior change with no trail. Log the failure or let it raise. If that constant is the correct answer rather than a stand-in for a value that could not be read, say so in a comment on the handler or in the docstring, and the row stops firing."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/book-to-skill/skills/book-to-skill/scripts/book_to_skill/parsers/pdf.py"},"region":{"startLine":141}}}],"partialFingerprints":{"codehealthFindingId/v1":"2eb924e0241b000153bf47fe3c71be03df84fc6652793aea15680c6c6bbe73f1"}},{"ruleId":"X7","level":"note","message":{"text":"Silent fallback default on parse failure: \u0060load_state\u0060 returns \u0060set()\u0060 when \u0060(json.JSONDecodeError, IOError)\u0060 is raised, with no log or raise \u2014 a malformed value silently becomes that default. Log the input or fail validation. If that constant is the correct answer rather than a stand-in for a value that could not be read, say so in a comment on the handler or in the docstring, and the row stops firing."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/security-guidance/hooks/security_reminder_hook.py"},"region":{"startLine":193}}}],"partialFingerprints":{"codehealthFindingId/v1":"306b70b9e762f0958a11b5f57bb63d2318beea13413f8f092d3df312df66a5a4"}},{"ruleId":"X7","level":"note","message":{"text":"Silent fallback default in catch: \u0060_read_text\u0060 swallows every exception into \u0060return \u0027\u0027\u0060 \u2014 a data error becomes a silent behavior change with no trail. Log the failure or let it raise. If that constant is the correct answer rather than a stand-in for a value that could not be read, say so in a comment on the handler or in the docstring, and the row stops firing."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skillopt-sleep/skillopt_sleep/__main__.py"},"region":{"startLine":46}}}],"partialFingerprints":{"codehealthFindingId/v1":"9d6f9a1d793351bf3150c3b1b9fb9bcf79dc8c93038d5405db1807b2bc3795a8"}},{"ruleId":"X7","level":"note","message":{"text":"Silent fallback default in catch: \u0060_call\u0060 swallows every exception into \u0060return \u0027\u0027\u0060 \u2014 a data error becomes a silent behavior change with no trail. Log the failure or let it raise. If that constant is the correct answer rather than a stand-in for a value that could not be read, say so in a comment on the handler or in the docstring, and the row stops firing."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skillopt-sleep/skillopt_sleep/backend.py"},"region":{"startLine":642}}}],"partialFingerprints":{"codehealthFindingId/v1":"9b3fe30c19e241955ac81edb7247f9630659cb5d6ca46126dc6102d8d2b25466"}},{"ruleId":"X7","level":"note","message":{"text":"Silent fallback default in catch: \u0060_call\u0060 swallows every exception into \u0060return \u0027\u0027\u0060 \u2014 a data error becomes a silent behavior change with no trail. Log the failure or let it raise. If that constant is the correct answer rather than a stand-in for a value that could not be read, say so in a comment on the handler or in the docstring, and the row stops firing."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skillopt-sleep/skillopt_sleep/backend.py"},"region":{"startLine":1031}}}],"partialFingerprints":{"codehealthFindingId/v1":"c4f75f6a34e3dc9b9bdd43f9ca9dbea228d1c4726e35c5ec74bf1ae739d3a60a"}},{"ruleId":"X7","level":"note","message":{"text":"Silent fallback default in catch: \u0060_load_file\u0060 swallows every exception into \u0060return {}\u0060 \u2014 a data error becomes a silent behavior change with no trail. Log the failure or let it raise. If that constant is the correct answer rather than a stand-in for a value that could not be read, say so in a comment on the handler or in the docstring, and the row stops firing."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skillopt-sleep/skillopt_sleep/config.py"},"region":{"startLine":145}}}],"partialFingerprints":{"codehealthFindingId/v1":"ad35d6f94f37ac7b8c970119e14e96a59cce0b04e83b70452ae22302878e1e1d"}},{"ruleId":"X7","level":"note","message":{"text":"Silent fallback default in catch: \u0060_read\u0060 swallows every exception into \u0060return \u0027\u0027\u0060 \u2014 a data error becomes a silent behavior change with no trail. Log the failure or let it raise. If that constant is the correct answer rather than a stand-in for a value that could not be read, say so in a comment on the handler or in the docstring, and the row stops firing."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skillopt-sleep/skillopt_sleep/cycle.py"},"region":{"startLine":52}}}],"partialFingerprints":{"codehealthFindingId/v1":"a7f230b5adedb958eb0684a8ef1715a9c53aa16a4f1f8acfd6adf925f6c5cd0b"}},{"ruleId":"X7","level":"note","message":{"text":"Silent fallback default in catch: \u0060_read_crontab\u0060 swallows every exception into \u0060return \u0027\u0027\u0060 \u2014 a data error becomes a silent behavior change with no trail. Log the failure or let it raise. If that constant is the correct answer rather than a stand-in for a value that could not be read, say so in a comment on the handler or in the docstring, and the row stops firing."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skillopt-sleep/skillopt_sleep/scheduler.py"},"region":{"startLine":39}}}],"partialFingerprints":{"codehealthFindingId/v1":"0879a6fc8022f0535fab930952018b13e986a9c46c0734545abb3cb70c60f139"}},{"ruleId":"X7","level":"note","message":{"text":"Silent fallback default in catch: \u0060read_package_scripts\u0060 swallows every exception into \u0060return {}\u0060 \u2014 a data error becomes a silent behavior change with no trail. Log the failure or let it raise. If that constant is the correct answer rather than a stand-in for a value that could not be read, say so in a comment on the handler or in the docstring, and the row stops firing."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/ci-cd-pipeline-builder/scripts/stack_detector.py"},"region":{"startLine":69}}}],"partialFingerprints":{"codehealthFindingId/v1":"620764144a0df4d77416fb8d3a65bd2e693d82c1522e08ca7aec9fc28d4a08ee"}},{"ruleId":"X7","level":"note","message":{"text":"Silent fallback default in catch: \u0060_compare_versions\u0060 swallows every exception into \u0060return 0\u0060 \u2014 a data error becomes a silent behavior change with no trail. Log the failure or let it raise. If that constant is the correct answer rather than a stand-in for a value that could not be read, say so in a comment on the handler or in the docstring, and the row stops firing."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/dependency-auditor/scripts/dep_scanner.py"},"region":{"startLine":303}}}],"partialFingerprints":{"codehealthFindingId/v1":"45ce690ca6a9fff534423903c1603e420004af9549b5d159b02f6c559b440db0"}},{"ruleId":"X7","level":"note","message":{"text":"Silent fallback default in catch: \u0060load_json\u0060 swallows every exception into \u0060return {}\u0060 \u2014 a data error becomes a silent behavior change with no trail. Log the failure or let it raise. If that constant is the correct answer rather than a stand-in for a value that could not be read, say so in a comment on the handler or in the docstring, and the row stops firing."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/monorepo-navigator/scripts/monorepo_analyzer.py"},"region":{"startLine":17}}}],"partialFingerprints":{"codehealthFindingId/v1":"c08f5d0126004570b573a55eb3c67ec0943c16ea55b3e266a03ddd7e0a405451"}},{"ruleId":"X7","level":"note","message":{"text":"Silent fallback default in catch: \u0060read_json_file\u0060 swallows every exception into \u0060return {}\u0060 \u2014 a data error becomes a silent behavior change with no trail. Log the failure or let it raise. If that constant is the correct answer rather than a stand-in for a value that could not be read, say so in a comment on the handler or in the docstring, and the row stops firing."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/ship-gate/scripts/ship_gate_scanner.py"},"region":{"startLine":219}}}],"partialFingerprints":{"codehealthFindingId/v1":"fdff9fed264bf268b42cc63091ae83cd91ef8faa25111a0fb33a855fdcd662f3"}},{"ruleId":"X7","level":"note","message":{"text":"Silent fallback default in catch: \u0060_derive_danger_color\u0060 swallows every exception into \u0060return \u0027#D04646\u0027\u0060 \u2014 a data error becomes a silent behavior change with no trail. Log the failure or let it raise. If that constant is the correct answer rather than a stand-in for a value that could not be read, say so in a comment on the handler or in the docstring, and the row stops firing."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"markdown-html/skills/md-review/scripts/review_html_renderer.py"},"region":{"startLine":83}}}],"partialFingerprints":{"codehealthFindingId/v1":"a47c9ccb87657e140cc354fffae8688f42ede74952e61938613ac1e27ecf192b"}},{"ruleId":"X7","level":"note","message":{"text":"Silent fallback default on parse failure: \u0060_num\u0060 returns \u00600\u0060 when \u0060ValueError\u0060 is raised, with no log or raise \u2014 a malformed value silently becomes that default. Log the input or fail validation. If that constant is the correct answer rather than a stand-in for a value that could not be read, say so in a comment on the handler or in the docstring, and the row stops firing."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"marketing/linkedin/skills/linkedin-analytics/scripts/post_performance_analyzer.py"},"region":{"startLine":107}}}],"partialFingerprints":{"codehealthFindingId/v1":"64830186934e6542a54072d0167d4cbea23d77c533425a6b9a6b8541ac82f975"}},{"ruleId":"X7","level":"note","message":{"text":"Silent fallback default on parse failure: \u0060load_ledger\u0060 returns \u0060{}\u0060 when \u0060(json.JSONDecodeError, OSError)\u0060 is raised, with no log or raise \u2014 a malformed value silently becomes that default. Log the input or fail validation. If that constant is the correct answer rather than a stand-in for a value that could not be read, say so in a comment on the handler or in the docstring, and the row stops firing."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"marketing/linkedin/skills/linkedin-content/scripts/repurpose_splitter.py"},"region":{"startLine":191}}}],"partialFingerprints":{"codehealthFindingId/v1":"ac6dc2dc83818582887891b4f5098501a23f2d17d43bc7a00ee7ce4848ff9cdd"}},{"ruleId":"X7","level":"note","message":{"text":"Silent fallback default in catch: \u0060main\u0060 swallows every exception into \u0060return 0\u0060 \u2014 a data error becomes a silent behavior change with no trail. Log the failure or let it raise. If that constant is the correct answer rather than a stand-in for a value that could not be read, say so in a comment on the handler or in the docstring, and the row stops firing."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"productivity/handoff/hooks/session_end.py"},"region":{"startLine":98}}}],"partialFingerprints":{"codehealthFindingId/v1":"8215c3a71809abb463844ad8bbfbde56aeb52391ebe8209e4fdb22e472817e96"}},{"ruleId":"X7","level":"note","message":{"text":"Silent fallback default in catch: \u0060main\u0060 swallows every exception into \u0060return 0\u0060 \u2014 a data error becomes a silent behavior change with no trail. Log the failure or let it raise. If that constant is the correct answer rather than a stand-in for a value that could not be read, say so in a comment on the handler or in the docstring, and the row stops firing."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"productivity/handoff/hooks/session_start.py"},"region":{"startLine":107}}}],"partialFingerprints":{"codehealthFindingId/v1":"7841a7eeb3ded55798bd02f886c704feda55b83f211d70b99b1d4e7311322c97"}},{"ruleId":"X7","level":"note","message":{"text":"Silent fallback default on parse failure: \u0060_calculate_timeline_variance\u0060 returns \u00600.0\u0060 when \u0060(ValueError, ZeroDivisionError)\u0060 is raised, with no log or raise \u2014 a malformed value silently becomes that default. Log the input or fail validation. If that constant is the correct answer rather than a stand-in for a value that could not be read, say so in a comment on the handler or in the docstring, and the row stops firing."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"project-management/skills/senior-pm/scripts/project_health_dashboard.py"},"region":{"startLine":191}}}],"partialFingerprints":{"codehealthFindingId/v1":"129669a79b8291dc5cfffc8c7d8138c81697907d75cac82bb27c857347a06222"}},{"ruleId":"X7","level":"note","message":{"text":"Silent fallback default on parse failure: \u0060integer_value\u0060 returns \u00600\u0060 when \u0060(TypeError, ValueError)\u0060 is raised, with no log or raise \u2014 a malformed value silently becomes that default. Log the input or fail validation. If that constant is the correct answer rather than a stand-in for a value that could not be read, say so in a comment on the handler or in the docstring, and the row stops firing."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"research/pulse/skills/pulse/scripts/citation_tracker.py"},"region":{"startLine":127}}}],"partialFingerprints":{"codehealthFindingId/v1":"aa61cfe8cc46b8d1914b91d8534ba80544e24e471381702b0c28097776ae7c3d"}},{"ruleId":"X7","level":"note","message":{"text":"Silent fallback default in catch: \u0060read_frontmatter\u0060 swallows every exception into \u0060return {}\u0060 \u2014 a data error becomes a silent behavior change with no trail. Log the failure or let it raise. If that constant is the correct answer rather than a stand-in for a value that could not be read, say so in a comment on the handler or in the docstring, and the row stops firing."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"scripts/sync-hermes-skills.py"},"region":{"startLine":146}}}],"partialFingerprints":{"codehealthFindingId/v1":"d8e9f639f20b7d3be5d650ca8555934ebc17296de68f069b0a82291126937c56"}},{"ruleId":"X7","level":"note","message":{"text":"Silent fallback default in catch: \u0060read_frontmatter\u0060 swallows every exception into \u0060return {}\u0060 \u2014 a data error becomes a silent behavior change with no trail. Log the failure or let it raise. If that constant is the correct answer rather than a stand-in for a value that could not be read, say so in a comment on the handler or in the docstring, and the row stops firing."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"scripts/sync-vibe-skills.py"},"region":{"startLine":159}}}],"partialFingerprints":{"codehealthFindingId/v1":"40b2cab5f2ec03136a0ec6e558f328a7b9754c4612e8bd7957146f2adc4eb523"}},{"ruleId":"X7","level":"note","message":{"text":"Silent fallback default in catch: \u0060fetchRecentActivity\u0060 swallows every exception into \u0060return []\u0060 \u2014 a data error becomes a silent behavior change with no trail. Log the failure or let it raise. If that constant is the correct answer rather than a stand-in for a value that could not be read, say so in a comment on the handler or in the docstring, and the row stops firing."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"engineering/skills/tech-debt-tracker/assets/sample_codebase/src/frontend.js"},"region":{"startLine":261}}}],"partialFingerprints":{"codehealthFindingId/v1":"6f098190a2e1a9b6845d7bf29baef708979b01404b2e833bca247a30f97064e5"}}],"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-1032","guid":"5f21e517-68aa-a650-9a25-5771ef024637","name":"OWASP Top Ten \u2014 Security Misconfiguration category","shortDescription":{"text":"OWASP Top Ten \u2014 Security Misconfiguration category"},"helpUri":"https://cwe.mitre.org/data/definitions/1032.html"},{"id":"CWE-1059","guid":"a2381a08-60f6-9554-a8b8-f3018cfaaca5","name":"Insufficient Technical Documentation","shortDescription":{"text":"Insufficient Technical Documentation"},"helpUri":"https://cwe.mitre.org/data/definitions/1059.html"},{"id":"CWE-1104","guid":"4c918cb5-b2a6-6c55-9963-a44ee464305e","name":"Use of Unmaintained Third Party Components","shortDescription":{"text":"Use of Unmaintained Third Party Components"},"helpUri":"https://cwe.mitre.org/data/definitions/1104.html"},{"id":"CWE-1352","guid":"5257f322-5cfc-6b52-bedd-0b9a526b4c7d","name":"CWE-1352","shortDescription":{"text":"CWE-1352"},"helpUri":"https://cwe.mitre.org/data/definitions/1352.html"},{"id":"CWE-1357","guid":"e4d2e772-757e-0a5c-bd7d-77052949d866","name":"Reliance on Insufficiently Trustworthy Component","shortDescription":{"text":"Reliance on Insufficiently Trustworthy Component"},"helpUri":"https://cwe.mitre.org/data/definitions/1357.html"},{"id":"CWE-1395","guid":"800e09e7-c11a-8654-9fa6-86f398995fed","name":"Dependency on Vulnerable Third-Party Component","shortDescription":{"text":"Dependency on Vulnerable Third-Party Component"},"helpUri":"https://cwe.mitre.org/data/definitions/1395.html"},{"id":"CWE-16","guid":"659db3ea-affc-8453-8add-c1218fbfcb92","name":"Configuration","shortDescription":{"text":"Configuration"},"helpUri":"https://cwe.mitre.org/data/definitions/16.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-276","guid":"4e27da05-61af-1d5c-aeb5-9f56b6ede3e3","name":"Incorrect Default Permissions","shortDescription":{"text":"Incorrect Default Permissions"},"helpUri":"https://cwe.mitre.org/data/definitions/276.html"},{"id":"CWE-327","guid":"e51910ff-67b5-3c51-aa3d-92837d9eab90","name":"Use of a Broken or Risky Cryptographic Algorithm","shortDescription":{"text":"Use of a Broken or Risky Cryptographic Algorithm"},"helpUri":"https://cwe.mitre.org/data/definitions/327.html"},{"id":"CWE-353","guid":"09d7e902-d4ee-f05d-ae6c-0a1554d0c18f","name":"Missing Support for Integrity Check","shortDescription":{"text":"Missing Support for Integrity Check"},"helpUri":"https://cwe.mitre.org/data/definitions/353.html"},{"id":"CWE-494","guid":"b8a65e0d-e459-4a55-a931-fc1136482375","name":"Download of Code Without Integrity Check","shortDescription":{"text":"Download of Code Without Integrity Check"},"helpUri":"https://cwe.mitre.org/data/definitions/494.html"},{"id":"CWE-506","guid":"401d6455-56e3-0552-9a39-f77461673e3f","name":"Embedded Malicious Code","shortDescription":{"text":"Embedded Malicious Code"},"helpUri":"https://cwe.mitre.org/data/definitions/506.html"},{"id":"CWE-522","guid":"71fb233e-ce6a-ae57-9419-ef8373540b09","name":"Insufficiently Protected Credentials","shortDescription":{"text":"Insufficiently Protected Credentials"},"helpUri":"https://cwe.mitre.org/data/definitions/522.html"},{"id":"CWE-676","guid":"550e6fab-2881-3252-8a05-c688a6b19c14","name":"Use of Potentially Dangerous Function","shortDescription":{"text":"Use of Potentially Dangerous Function"},"helpUri":"https://cwe.mitre.org/data/definitions/676.html"},{"id":"CWE-732","guid":"1da27e8f-b330-7650-ab63-bd61953eae5d","name":"Incorrect Permission Assignment for Critical Resource","shortDescription":{"text":"Incorrect Permission Assignment for Critical Resource"},"helpUri":"https://cwe.mitre.org/data/definitions/732.html"},{"id":"CWE-77","guid":"332c8ade-6612-9f56-a06b-d8d90b1a8750","name":"Improper Neutralization of Special Elements used in a Command (\u0027Command Injection\u0027)","shortDescription":{"text":"Improper Neutralization of Special Elements used in a Command (\u0027Command Injection\u0027)"},"helpUri":"https://cwe.mitre.org/data/definitions/77.html"},{"id":"CWE-78","guid":"2e31ceaf-c7ae-2e5e-9661-cfb1362789cf","name":"Improper Neutralization of Special Elements used in an OS Command (\u0027OS Command Injection\u0027)","shortDescription":{"text":"Improper Neutralization of Special Elements used in an OS Command (\u0027OS Command Injection\u0027)"},"helpUri":"https://cwe.mitre.org/data/definitions/78.html"},{"id":"CWE-79","guid":"fd45580b-e8c4-fc5e-8c2f-aa8fab0b4dbf","name":"Improper Neutralization of Input During Web Page Generation (\u0027Cross-site Scripting\u0027)","shortDescription":{"text":"Improper Neutralization of Input During Web Page Generation (\u0027Cross-site Scripting\u0027)"},"helpUri":"https://cwe.mitre.org/data/definitions/79.html"},{"id":"CWE-798","guid":"5e8f057d-fee3-995a-a0cb-9fc5b0d174d1","name":"Use of Hard-coded Credentials","shortDescription":{"text":"Use of Hard-coded Credentials"},"helpUri":"https://cwe.mitre.org/data/definitions/798.html"},{"id":"CWE-829","guid":"13c33925-97fb-5a5e-b40c-56d328b8a4d7","name":"Inclusion of Functionality from Untrusted Control Sphere","shortDescription":{"text":"Inclusion of Functionality from Untrusted Control Sphere"},"helpUri":"https://cwe.mitre.org/data/definitions/829.html"},{"id":"CWE-89","guid":"6d08fdad-37eb-c150-bbf0-d7d946863407","name":"Improper Neutralization of Special Elements used in an SQL Command (\u0027SQL Injection\u0027)","shortDescription":{"text":"Improper Neutralization of Special Elements used in an SQL Command (\u0027SQL Injection\u0027)"},"helpUri":"https://cwe.mitre.org/data/definitions/89.html"},{"id":"CWE-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-94","guid":"75e7f50c-6c2f-dd52-bf40-bf6c52b861fd","name":"Improper Control of Generation of Code (\u0027Code Injection\u0027)","shortDescription":{"text":"Improper Control of Generation of Code (\u0027Code Injection\u0027)"},"helpUri":"https://cwe.mitre.org/data/definitions/94.html"}]},{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61","version":"2025","organization":"OWASP Foundation","informationUri":"https://top10.owasp.org/2025/","isComprehensive":false,"shortDescription":{"text":"The OWASP Top 10:2025 web application security risks."},"taxa":[{"id":"A01:2025","guid":"df693558-c822-0452-8f7b-4d53cb6bcc59","name":"Broken Access Control","shortDescription":{"text":"Broken Access Control"},"helpUri":"https://top10.owasp.org/2025/A01_2025-Broken_Access_Control/"},{"id":"A02:2025","guid":"668dee9e-41bc-6354-97d0-fdf8f40c50c1","name":"Security Misconfiguration","shortDescription":{"text":"Security Misconfiguration"},"helpUri":"https://top10.owasp.org/2025/A02_2025-Security_Misconfiguration/"},{"id":"A03:2025","guid":"168e227c-7735-2e57-bc6e-997affe644c5","name":"Software Supply Chain Failures","shortDescription":{"text":"Software Supply Chain Failures"},"helpUri":"https://top10.owasp.org/2025/A03_2025-Software_Supply_Chain_Failures/"},{"id":"A04:2025","guid":"6a9f5bfd-1a56-6453-beec-a7eff0ba3007","name":"Cryptographic Failures","shortDescription":{"text":"Cryptographic Failures"},"helpUri":"https://top10.owasp.org/2025/A04_2025-Cryptographic_Failures/"},{"id":"A05:2025","guid":"87e86033-3231-8458-8e4a-5cb82743553a","name":"Injection","shortDescription":{"text":"Injection"},"helpUri":"https://top10.owasp.org/2025/A05_2025-Injection/"},{"id":"A06:2025","guid":"491554d7-b8e4-9652-91a9-53700dc92ece","name":"Insecure Design","shortDescription":{"text":"Insecure Design"},"helpUri":"https://top10.owasp.org/2025/A06_2025-Insecure_Design/"},{"id":"A07:2025","guid":"334ddd78-539d-d35c-83dd-253647eb7eaf","name":"Authentication Failures","shortDescription":{"text":"Authentication Failures"},"helpUri":"https://top10.owasp.org/2025/A07_2025-Authentication_Failures/"},{"id":"A08:2025","guid":"84b0c297-710e-9a5f-9335-936ecb260c36","name":"Software or Data Integrity Failures","shortDescription":{"text":"Software or Data Integrity Failures"},"helpUri":"https://top10.owasp.org/2025/A08_2025-Software_or_Data_Integrity_Failures/"}]},{"name":"OWASP Top 10 CI/CD Security Risks","guid":"3c9b2a6e-5d14-4f7b-8e02-6a1d9c4b7f35","organization":"OWASP Foundation","informationUri":"https://owasp.org/www-project-top-10-ci-cd-security-risks/","isComprehensive":false,"shortDescription":{"text":"The OWASP Top 10 CI/CD Security Risks."},"taxa":[{"id":"CICD-SEC-3","guid":"458c83a6-ebf7-cf55-8cc3-b4d949bbf271","name":"Dependency Chain Abuse","shortDescription":{"text":"Dependency Chain Abuse"},"helpUri":"https://owasp.github.io/www-project-top-10-ci-cd-security-risks/CICD-SEC-03-Dependency-Chain-Abuse"},{"id":"CICD-SEC-6","guid":"f2ee2486-b260-2952-a41f-6b67fa713940","name":"Insufficient Credential Hygiene","shortDescription":{"text":"Insufficient Credential Hygiene"},"helpUri":"https://owasp.github.io/www-project-top-10-ci-cd-security-risks/CICD-SEC-06-Insufficient-Credential-Hygiene"},{"id":"CICD-SEC-7","guid":"4c4af28d-49e3-2d51-b597-e1396c49658b","name":"Insecure System Configuration","shortDescription":{"text":"Insecure System Configuration"},"helpUri":"https://owasp.github.io/www-project-top-10-ci-cd-security-risks/CICD-SEC-07-Insecure-System-Configuration"},{"id":"CICD-SEC-8","guid":"b6b2dacf-a168-4957-876e-a8c73ee00eb0","name":"Ungoverned Usage of 3rd Party Services","shortDescription":{"text":"Ungoverned Usage of 3rd Party Services"},"helpUri":"https://owasp.github.io/www-project-top-10-ci-cd-security-risks/CICD-SEC-08-Ungoverned-Usage-of-3rd-Party-Services"},{"id":"CICD-SEC-9","guid":"b3d36727-0395-5b51-94c4-5e173d62eab3","name":"Improper Artifact Integrity Validation","shortDescription":{"text":"Improper Artifact Integrity Validation"},"helpUri":"https://owasp.github.io/www-project-top-10-ci-cd-security-risks/CICD-SEC-09-Improper-Artifact-Integrity-Validation"}]}],"properties":{"codehealthPublication":{"public":true,"notice":"This is the PUBLIC form of this artifact. Findings are listed in full, but the details of SECURITY findings \u2014 which rule fired, in which file, on which line, and how to fix it \u2014 are deliberately withheld, and any secret-scanner results are excluded entirely. Where detail is absent here it was REMOVED FOR PUBLICATION; it is not missing from the analysis. The complete artifact is available from the repository owner.","securityFindingsRedacted":116,"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."]}]}