{"$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":"D9","name":"Test Distribution","shortDescription":{"text":"Test Distribution"},"helpUri":"https://codehealth.canine.dev/dimensions/D9"},{"id":"D10","name":"Test Quality","shortDescription":{"text":"Test Quality"},"helpUri":"https://codehealth.canine.dev/dimensions/D10"},{"id":"D12","name":"Dependency Hygiene","shortDescription":{"text":"Dependency Hygiene"},"helpUri":"https://codehealth.canine.dev/dimensions/D12"},{"id":"D13","name":"Secret Scanning","shortDescription":{"text":"Secret Scanning"},"helpUri":"https://codehealth.canine.dev/dimensions/D13","relationships":[{"target":{"id":"CWE-798","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},"kinds":["relevant"]},{"target":{"id":"CWE-259","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},"kinds":["relevant"]},{"target":{"id":"A07:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}},"kinds":["relevant"]}],"properties":{"cwe":["CWE-798","CWE-259"],"owasp":"A07:2025"}},{"id":"D14","name":"License Compliance","shortDescription":{"text":"License Compliance"},"helpUri":"https://codehealth.canine.dev/dimensions/D14"},{"id":"D15","name":"Churn \u00D7 Complexity Hotspots","shortDescription":{"text":"Churn \u00D7 Complexity Hotspots"},"helpUri":"https://codehealth.canine.dev/dimensions/D15"},{"id":"D16","name":"Bus Factor","shortDescription":{"text":"Bus Factor"},"helpUri":"https://codehealth.canine.dev/dimensions/D16"},{"id":"D17","name":"Explicit Debt","shortDescription":{"text":"Explicit Debt"},"helpUri":"https://codehealth.canine.dev/dimensions/D17"},{"id":"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":"D26","name":"Project Cohesion","shortDescription":{"text":"Project Cohesion"},"helpUri":"https://codehealth.canine.dev/dimensions/D26"},{"id":"D28","name":"Secrets (history)","shortDescription":{"text":"Secrets (history)"},"helpUri":"https://codehealth.canine.dev/dimensions/D28","relationships":[{"target":{"id":"CWE-798","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},"kinds":["relevant"]},{"target":{"id":"CWE-259","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},"kinds":["relevant"]},{"target":{"id":"A07:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}},"kinds":["relevant"]}],"properties":{"cwe":["CWE-798","CWE-259"],"owasp":"A07:2025"}},{"id":"D29","name":"Static Analysis (SAST)","shortDescription":{"text":"Static Analysis (SAST)"},"helpUri":"https://codehealth.canine.dev/dimensions/D29","relationships":[{"target":{"id":"CWE-79","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},"kinds":["relevant"]},{"target":{"id":"CWE-89","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},"kinds":["relevant"]},{"target":{"id":"CWE-78","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},"kinds":["relevant"]},{"target":{"id":"CWE-94","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},"kinds":["relevant"]},{"target":{"id":"CWE-77","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},"kinds":["relevant"]},{"target":{"id":"A05:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}},"kinds":["relevant"]}],"properties":{"cwe":["CWE-79","CWE-89","CWE-78","CWE-94","CWE-77"],"owasp":"A05:2025"}},{"id":"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":"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":"AX10","name":"Code composition","shortDescription":{"text":"Code composition"},"helpUri":"https://codehealth.canine.dev/dimensions/AX10"},{"id":"AX2","name":"Stateful singletons","shortDescription":{"text":"Stateful singletons"},"helpUri":"https://codehealth.canine.dev/dimensions/AX2"},{"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":"AX5","name":"Architecture \u0026 structure","shortDescription":{"text":"Architecture \u0026 structure"},"helpUri":"https://codehealth.canine.dev/dimensions/AX5"},{"id":"AX6","name":"Interface segregation","shortDescription":{"text":"Interface segregation"},"helpUri":"https://codehealth.canine.dev/dimensions/AX6"},{"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":"R11","name":"Import Boundaries","shortDescription":{"text":"Import Boundaries"},"helpUri":"https://codehealth.canine.dev/dimensions/R11"},{"id":"R2","name":"Cyclomatic Complexity","shortDescription":{"text":"Cyclomatic Complexity"},"helpUri":"https://codehealth.canine.dev/dimensions/R2"},{"id":"R3","name":"Large Files","shortDescription":{"text":"Large Files"},"helpUri":"https://codehealth.canine.dev/dimensions/R3"},{"id":"R4","name":"Test Coverage","shortDescription":{"text":"Test Coverage"},"helpUri":"https://codehealth.canine.dev/dimensions/R4"},{"id":"R5","name":"Dependency Freshness","shortDescription":{"text":"Dependency Freshness"},"helpUri":"https://codehealth.canine.dev/dimensions/R5"},{"id":"R6","name":"Tooling","shortDescription":{"text":"Tooling"},"helpUri":"https://codehealth.canine.dev/dimensions/R6"},{"id":"R7","name":"Dead Code","shortDescription":{"text":"Dead Code"},"helpUri":"https://codehealth.canine.dev/dimensions/R7"},{"id":"R8","name":"Dependency Hygiene","shortDescription":{"text":"Dependency Hygiene"},"helpUri":"https://codehealth.canine.dev/dimensions/R8"},{"id":"R9","name":"Circular Imports","shortDescription":{"text":"Circular Imports"},"helpUri":"https://codehealth.canine.dev/dimensions/R9"},{"id":"S1","name":"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":"X27","name":"Collection changed while being enumerated","shortDescription":{"text":"Collection changed while being enumerated"},"helpUri":"https://codehealth.canine.dev/dimensions/X27"},{"id":"X28","name":"Index access outside its own emptiness guard","shortDescription":{"text":"Index access outside its own emptiness guard"},"helpUri":"https://codehealth.canine.dev/dimensions/X28"},{"id":"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":"RuleForm.RuleForm (cyclomatic 42): RuleForm.RuleForm has cyclomatic complexity 42 (threshold 15). Of this number, 16 points are the body\u0027s own statements and 26 belong to 12 function items inside it that branch. To reduce it, name the conditions: bind each compound test to a well-named local or a small predicate function, so the body reads as a sequence of named decisions rather than a chain of operators."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"apps/rule-manager/client/src/ts/components/RuleForm.tsx"},"region":{"startLine":73}}}],"partialFingerprints":{"codehealthFindingId/v1":"d7eca9e253d1ebe68712e5a8ad2b497d813c25ebf7e50dde7738b2646740b9f3"}},{"ruleId":"D1","level":"warning","message":{"text":"PaginatedRulesTable.PaginatedRulesTable (cyclomatic 24): PaginatedRulesTable.PaginatedRulesTable has cyclomatic complexity 24 (threshold 15). Most of this is not in the body itself: 1 of the 24 points is its own statement and the rest belongs to 10 function literals inside it that branch (lines 182, 344, 252, \u2026). The decisions are inside those literals, which nothing outside this body can call, review or test on its own, so splitting the enclosing body is not the move available here. To reduce it, lift the literals\u0027 work into a named function or method at the enclosing scope and have each literal call it, then reduce whichever part then reads as the largest."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"apps/rule-manager/client/src/ts/components/table/PaginatedRulesTable.tsx"},"region":{"startLine":160}}}],"partialFingerprints":{"codehealthFindingId/v1":"cba2779d64910f48001af017d8265dc84d2dd3de8d42bfbd81f3b33cacd924eb"}},{"ruleId":"D1","level":"warning","message":{"text":"RuleContent.RuleContent (cyclomatic 16): RuleContent.RuleContent 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":"apps/rule-manager/client/src/ts/components/RuleContent.tsx"},"region":{"startLine":50}}}],"partialFingerprints":{"codehealthFindingId/v1":"1dc67d9c741d3de7de84d4afaba0c3c910c68223f7164d985fbe469fd39b53fe"}},{"ruleId":"D2","level":"warning","message":{"text":"RuleForm.RuleForm (cognitive 40): RuleForm.RuleForm has cognitive complexity 40 (threshold 15). Drivers by points: boolean chains 23, if/else 15, ternaries 2. Most of this is not in the body itself: 14 of the 40 points are its own statements and the rest belongs to 12 function items inside it that branch (a function literal at line 130, publishRuleHandler, a function literal at line 110, \u2026). The named helpers are already separate functions; the literals\u0027 work cannot be called, reviewed or tested from outside this body. To reduce it, move the named helpers out of the body to the enclosing scope and lift each literal\u0027s work into a named function there, so each is measured, reviewed and tested on its own, and reduce whichever one then reads as the largest."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"apps/rule-manager/client/src/ts/components/RuleForm.tsx"},"region":{"startLine":73}}}],"partialFingerprints":{"codehealthFindingId/v1":"8814914237b2bb542391741ed91774a861c0dffd6062ac46deb7a34f935e04ee"}},{"ruleId":"D2","level":"warning","message":{"text":"RuleManager.unpublishRule (cognitive 29): RuleManager.unpublishRule has cognitive complexity 29 (threshold 15). Drivers by points: loops 7 (28 pts), error handling 1 (nesting depth added 21). To reduce it, break up the iteration: give each loop body a named function, and split a multi-phase loop into one function per phase so no single body carries the whole pipeline."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"apps/rule-manager/app/service/RuleManager.scala"},"region":{"startLine":425}}}],"partialFingerprints":{"codehealthFindingId/v1":"e6f8eb26b84f7ce00ab73e69249f6436d244d82d433cb4ac2575b139d98f58e0"}},{"ruleId":"D2","level":"warning","message":{"text":"SpellDictionaryBuilder.tokenizeInput (cognitive 22): SpellDictionaryBuilder.tokenizeInput has cognitive complexity 22 (threshold 15). Drivers by points: if/else 12 (21 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":"apps/checker/app/services/collins/SpellDictionaryBuilder.scala"},"region":{"startLine":49}}}],"partialFingerprints":{"codehealthFindingId/v1":"50122b8570ff4e4a7e116d456282788d24d872b5719282e7cee5a26040bcba16"}},{"ruleId":"D2","level":"warning","message":{"text":"DictionaryBuilder.addFreqData (cognitive 21): DictionaryBuilder.addFreqData has cognitive complexity 21 (threshold 15). Drivers by points: if/else 8 (17 pts), boolean chains 2, error handling 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":"apps/checker/app/services/collins/DictionaryBuilder.scala"},"region":{"startLine":115}}}],"partialFingerprints":{"codehealthFindingId/v1":"a5edec7859ba374a8b7e0112515dea2859f4515820c0b71ef6cd43f595cc9ee7"}},{"ruleId":"D2","level":"warning","message":{"text":"PaginatedRulesTable.PaginatedRulesTable (cognitive 20): PaginatedRulesTable.PaginatedRulesTable has cognitive complexity 20 (threshold 15). Drivers by points: if/else 7, boolean chains 6, ternaries 5 (6 pts), match/switch 1 (nesting depth added 1). None of this is in the body itself: all 20 points belong to 10 function literals inside it that branch (lines 344, 182, 252, \u2026). The decisions are inside those literals, which nothing outside this body can call, review or test on its own, so splitting the enclosing body is not the move available here. To reduce it, lift the literals\u0027 work into a named function or method at the enclosing scope and have each literal call it, then reduce whichever part then reads as the largest."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"apps/rule-manager/client/src/ts/components/table/PaginatedRulesTable.tsx"},"region":{"startLine":160}}}],"partialFingerprints":{"codehealthFindingId/v1":"635ac7fc53dd7bcff1d83c73765bbf267d9ed402b2c354f45f25d66c7f9625c1"}},{"ruleId":"D2","level":"warning","message":{"text":"RuleManager.parseDraftRuleForPublication (cognitive 18): RuleManager.parseDraftRuleForPublication has cognitive complexity 18 (threshold 15). Drivers by points: loops 5 (15 pts), match/switch 1 (2 pts), if/else 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":"apps/rule-manager/app/service/RuleManager.scala"},"region":{"startLine":302}}}],"partialFingerprints":{"codehealthFindingId/v1":"36ff1cecfe12757fb22b4d285b5bf5936e5e311656af2ad92502fb04f780fe06"}},{"ruleId":"D2","level":"warning","message":{"text":"DbRuleDraft.searchRules (cognitive 17): DbRuleDraft.searchRules has cognitive complexity 17 (threshold 15). Drivers by points: if/else 11, match/switch 4, 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":"apps/rule-manager/app/db/DbRuleDraft.scala"},"region":{"startLine":231}}}],"partialFingerprints":{"codehealthFindingId/v1":"f1346768a24c2dad4649a3076b230bbb602ecd24eab371457e5a5ff04794cf46"}},{"ruleId":"D3","level":"warning","message":{"text":"FunctionTooLong: RuleForm.RuleForm: FunctionTooLong \u2014 RuleForm runs 248 significant lines (blank, comment-only and punctuation-only lines excluded) in one body. The bar is 100 significant lines; this is 148 over it, 2.48\u00D7 the bar. This is length, not branching: a long straight-line body scores low on complexity and is still read whole to change any part of it, so the complexity numbers beside this row neither confirm nor excuse it. To reduce it, extract each cohesive step of the body \u2014 the runs of statements that work on the same values and would earn the same name \u2014 into its own named unit, and have this one call them in order."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"apps/rule-manager/client/src/ts/components/RuleForm.tsx"},"region":{"startLine":73}}}],"partialFingerprints":{"codehealthFindingId/v1":"cd40f7f0b2dd63eeba36bebc62082b52ea2fd189b0afb756899c1516b0064ce9"}},{"ruleId":"D3","level":"warning","message":{"text":"FunctionTooLong: PaginatedRulesTable.PaginatedRulesTable: FunctionTooLong \u2014 PaginatedRulesTable runs 203 significant lines (blank, comment-only and punctuation-only lines excluded) in one body. The bar is 100 significant lines; this is 103 over it, 2.03\u00D7 the bar. This is length, not branching: a long straight-line body scores low on complexity and is still read whole to change any part of it, so the complexity numbers beside this row neither confirm nor excuse it. To reduce it, extract each cohesive step of the body \u2014 the runs of statements that work on the same values and would earn the same name \u2014 into its own named unit, and have this one call them in order."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"apps/rule-manager/client/src/ts/components/table/PaginatedRulesTable.tsx"},"region":{"startLine":160}}}],"partialFingerprints":{"codehealthFindingId/v1":"bc6de53dcea4f3aa7cc2e0b34009bd3f45ca3f0205ea91c9b36ef1cd17bedd15"}},{"ruleId":"D3","level":"warning","message":{"text":"FunctionTooLong: Rules.Rules: FunctionTooLong \u2014 Rules runs 202 significant lines (blank, comment-only and punctuation-only lines excluded) in one body. The bar is 100 significant lines; this is 102 over it, 2.02\u00D7 the bar. This is length, not branching: a long straight-line body scores low on complexity and is still read whole to change any part of it, so the complexity numbers beside this row neither confirm nor excuse it. To reduce it, extract each cohesive step of the body \u2014 the runs of statements that work on the same values and would earn the same name \u2014 into its own named unit, and have this one call them in order."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"apps/rule-manager/client/src/ts/components/pages/Rules.tsx"},"region":{"startLine":35}}}],"partialFingerprints":{"codehealthFindingId/v1":"6223793472f6fc5a1be29588f80dfb1ac5023417f791cd9adaf2e4dea52810dc"}},{"ruleId":"D3","level":"warning","message":{"text":"FunctionTooLong: useRule.useRule: FunctionTooLong \u2014 useRule runs 201 significant lines (blank, comment-only and punctuation-only lines excluded) in one body. The bar is 100 significant lines; this is 101 over it, 2.01\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":"apps/rule-manager/client/src/ts/components/hooks/useRule.ts"},"region":{"startLine":45}}}],"partialFingerprints":{"codehealthFindingId/v1":"eb3f109ee1795416d4961422ca87b1432e1597555d84f64913d1234d79d0b315"}},{"ruleId":"D3","level":"warning","message":{"text":"MethodTooLong: Typerighter.constructor: MethodTooLong \u2014 constructor runs 182 significant lines (blank, comment-only and punctuation-only lines excluded) in one body. The bar is 100 significant lines; this is 82 over it, 1.82\u00D7 the bar. This is length, not branching: a long straight-line body scores low on complexity and is still read whole to change any part of it, so the complexity numbers beside this row neither confirm nor excuse it. To reduce it, extract each cohesive step of the body \u2014 the runs of statements that work on the same values and would earn the same name \u2014 into its own named unit, and have this one call them in order."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"cdk/lib/index.ts"},"region":{"startLine":54}}}],"partialFingerprints":{"codehealthFindingId/v1":"5b9e09f1c2c71cdd6008dbf5dc3b4ae7c9f95f8b32c8df4c6ff298bfc4cb4be9"}},{"ruleId":"D3","level":"warning","message":{"text":"FunctionTooLong: RuleContent.RuleContent: FunctionTooLong \u2014 RuleContent runs 149 significant lines (blank, comment-only and punctuation-only lines excluded) in one body. The bar is 100 significant lines; this is 49 over it, 1.49\u00D7 the bar. This is length, not branching: a long straight-line body scores low on complexity and is still read whole to change any part of it, so the complexity numbers beside this row neither confirm nor excuse it. To reduce it, extract each cohesive step of the body \u2014 the runs of statements that work on the same values and would earn the same name \u2014 into its own named unit, and have this one call them in order."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"apps/rule-manager/client/src/ts/components/RuleContent.tsx"},"region":{"startLine":50}}}],"partialFingerprints":{"codehealthFindingId/v1":"9d19cb3475de60b567f6a445dc30ede6f9d2757f1ba01036a32e72a0148fae89"}},{"ruleId":"D3","level":"warning","message":{"text":"FileTooLong: db/DbRuleDraft.scala: FileTooLong \u2014 547 significant lines (blank, comment-only and punctuation-only lines excluded). The bar is 500 significant lines; this is 47 over it, 1.09\u00D7 the bar. To reduce it, split the file along the responsibilities already in it: move each cohesive group of declarations into its own sibling file in the same module or package, so no one file has to be read whole to change one of them."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"apps/rule-manager/app/db/DbRuleDraft.scala"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"450d04b2cab016f712f0035ab07d7c176870b97ed7a38ec02e31fa0a6ff77601"}},{"ruleId":"D3","level":"warning","message":{"text":"FunctionTooLong: tags.TagsProvider: FunctionTooLong \u2014 TagsProvider runs 101 significant lines (blank, comment-only and punctuation-only lines excluded) in one body. The bar is 100 significant lines; this is 1 over it, 1.01\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":"apps/rule-manager/client/src/ts/components/context/tags.tsx"},"region":{"startLine":41}}}],"partialFingerprints":{"codehealthFindingId/v1":"3ee86a6b3518ffb6c5fcc6c6161a20abb53914335ee0dee98b487ba1f8404df2"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (15 lines \u00D7 2): apps/checker/app/AppLoader.scala:7-21 | apps/rule-manager/app/AppLoader.scala:7-21 \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. 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":"apps/checker/app/AppLoader.scala"},"region":{"startLine":7}}}],"partialFingerprints":{"codehealthFindingId/v1":"969095e1a9f6d54cc173b36c94528297d246601a3a18618eb94f2db89701ad62"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (12 lines \u00D7 2): apps/checker/app/services/MatcherPool.scala:159-170 | apps/checker/app/services/MatcherPool.scala:193-204 \u2014 both copies are in the same file, so extract the block into one function there and call it from each site \u2014 the copies drift apart the first time only one of them is edited."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"apps/checker/app/services/MatcherPool.scala"},"region":{"startLine":159}}}],"partialFingerprints":{"codehealthFindingId/v1":"eaadca6a69c0a73d6707577f02cdedb07a9a3ec7582bd90779ea56fa704bab24"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9 lines \u00D7 2): apps/rule-manager/app/db/DbRuleDraft.scala:93-101 | apps/rule-manager/app/db/DbRuleLive.scala:60-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. \u2605 These copies have DRIFTED, and that is worth reading before extracting anything: just before the matched lines, \u0060apps/rule-manager/app/db/DbRuleDraft.scala:92\u0060 calls \u0060boolean\u0060 and \u0060apps/rule-manager/app/db/DbRuleLive.scala:59\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":"apps/rule-manager/app/db/DbRuleDraft.scala"},"region":{"startLine":93}}}],"partialFingerprints":{"codehealthFindingId/v1":"bce700de0f7dae65f2f69e7c933625bb57caf496328fa8edc3c9541fe40f5a81"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2): apps/rule-manager/app/db/DbRuleDraft.scala:553-558 | apps/rule-manager/app/db/DbRuleLive.scala:271-276 \u2014 the copies sit in sibling files of one directory, so a shared home is within easy reach: extract the block into a single shared function 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, \u0060apps/rule-manager/app/db/DbRuleLive.scala:278\u0060 calls \u0060Symbol\u0060 and \u0060apps/rule-manager/app/db/DbRuleDraft.scala:560\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":"apps/rule-manager/app/db/DbRuleDraft.scala"},"region":{"startLine":553}}}],"partialFingerprints":{"codehealthFindingId/v1":"c82fbe408e07ee40e34478a99ad8baff9213911e60e6f50fba5e5a1445836702"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): apps/rule-manager/app/db/DbRuleDraft.scala:546-550 | apps/rule-manager/app/db/DbRuleLive.scala:263-268 \u2014 the copies sit in sibling files of one directory, so a shared home is within easy reach: extract the block into a single shared function 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 \u0060apps/rule-manager/app/db/DbRuleLive.scala:263\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":"apps/rule-manager/app/db/DbRuleDraft.scala"},"region":{"startLine":546}}}],"partialFingerprints":{"codehealthFindingId/v1":"23060faef0fdde8b9fe15b16ae976d3ffc5d2e868c758cbc7bbc33ea95f3b71a"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (8 lines \u00D7 2): apps/rule-manager/app/db/RuleTagDraft.scala:108-115 | apps/rule-manager/app/db/RuleTagLive.scala:131-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."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"apps/rule-manager/app/db/RuleTagDraft.scala"},"region":{"startLine":108}}}],"partialFingerprints":{"codehealthFindingId/v1":"f767da1bfa121f5c25df31c27d2edd7898a031b18f8fca82e5d90e4d4bd46108"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2): apps/rule-manager/app/db/DbRuleDraft.scala:86-91 | apps/rule-manager/app/db/DbRuleLive.scala:54-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. \u2605 These copies have DRIFTED, and that is worth reading before extracting anything: just after the matched lines, \u0060apps/rule-manager/app/db/DbRuleDraft.scala:92\u0060 calls \u0060boolean\u0060 and \u0060apps/rule-manager/app/db/DbRuleLive.scala:60\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":"apps/rule-manager/app/db/DbRuleDraft.scala"},"region":{"startLine":86}}}],"partialFingerprints":{"codehealthFindingId/v1":"a2e57f3d882a7f8650adff165ddc9cec8e3e0077db6f3eaa2469499cd4451507"}},{"ruleId":"D6","level":"warning","message":{"text":"Low cohesion: RulesController (LCOM4 9): RulesController\u0027s methods fall into 9 groups that share no field and call none of each other, against a bar of more than 3 for this run (LCOM4, configurable \u2014 your repository\u0027s bar is the one quoted here). Each group is a set of methods reachable from one another through shared fields or direct calls, so 9 groups means the type has that many internally-connected clusters with nothing tying them together. Types whose shape makes a high count expected \u2014 and which would otherwise dominate this list \u2014 are excluded before this row is raised, so this is a genuine split candidate rather than a metric reading. It is still a shape, not a defect: confirm the groups match responsibilities you can name before splitting."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"apps/rule-manager/app/controllers/RulesController.scala"},"region":{"startLine":21}}}],"partialFingerprints":{"codehealthFindingId/v1":"15bfa96b7ad3aa28a2c6035910e275b13aa77f94635bbb8dc78e74cb78f4a69d"}},{"ruleId":"D6","level":"warning","message":{"text":"Low cohesion: TagsController (LCOM4 4): TagsController\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":"apps/rule-manager/app/controllers/TagsController.scala"},"region":{"startLine":14}}}],"partialFingerprints":{"codehealthFindingId/v1":"1135e61e1bd80194382a201b11aa352289875b7808fff75b3e75fdea09166cb5"}},{"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":"354692e9b399bdd97973809bcc76410ab84655786f343227d0d6bfe7a7d29eb5"},"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":"d64441805a383fcb2f8c802f41fe6949b77873da535ea9351163fee017538742"},"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":"b194a5f5a6be3e3325f482f94782e7b6792f421f28d5d264441a0db792d8f590"},"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":"f37217a232471543befb01b144b1cbd3dcc819e52ebcf68abf8bb5abb1e6edd6"},"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":"D16","level":"note","message":{"text":"Off-boarding risk: anonymized user #1: If anonymized user #1 becomes unavailable, 1 significant file(s) lose their only recent owner: apps/rule-manager/client/src/ts/components/table/PaginatedRulesTable.tsx. Pair on, review, or document these before any departure."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"911a3ab1699a57317c958692232f4d1b96089f4a935abc1856fc506e2e082a93"}},{"ruleId":"D17","level":"warning","message":{"text":"TodoComment: // TODO: as the word occurrence data from \u2014 source code is not a task system: move the work to your tracker and leave a reference instead (e.g. \u0060// REF: #123\u0060), so the task is planned where tasks live and the ticket links back to the code."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"apps/checker/app/services/collins/SpellDictionaryBuilder.scala"},"region":{"startLine":76}}}],"partialFingerprints":{"codehealthFindingId/v1":"e29bdc70d11d38a2f17f4a22044b83354c6a0ba31aabd67ba87aad25e3438d83"}},{"ruleId":"D19","level":"note","message":{"text":"Documentation: contradicts the code: The architecture decision on Scala vs Typescript for the backend is stale given the current Typescript-only infrastructure. Update the decision to reflect the actual technology stack."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/decision-records/001-management-service.md"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"2820be1824c8bc6e86ffe8dc3474bc7f2447416762edd1ec8a1dd93af9dffd24"}},{"ruleId":"D26","level":"note","message":{"text":"Projects may be oversized for their cohesion: 1 of 4 project(s) overshoot their size bounds, lowering Project Cohesion to 5.2/10. The most over is \u0060(repository root)\u0060 (6116 LoC, 161 module-visible types across 19 directories). Review these for cohesion \u2014 draw the boundary inside the module first (group each responsibility into its own package or directory and keep the cross-boundary members non-public), since splitting a published package moves types between packages and breaks consumers."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"d5a94650dc74886a0f1f08eb9fb6775f1fc395279ef7e901c970c9d26f767a72"}},{"ruleId":"D28","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"1bbe96c66f1f4c2d1544d918cb8363138377bf88607cc24635fc9fce70044836"},"properties":{"commitSha":"ec657ef8b6a24b2335c0dc80ed88320f35a45e64"},"taxa":[{"id":"CWE-259","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-540","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"A01:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"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":"930f0272446ad44ef6f8a82957ad76beb09d2d724d3b6f63aac3eb65d1688f1a"},"properties":{"commitSha":"df41fd9542803a26c4784bc0348ed37e9ed9ce86"}},{"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":"268ec084d706ff00a19215d082202641616769aabddbcec9eccebacad2498f93"},"properties":{"commitSha":"1268369b853d4419537a6d6eb95796be9bcaf51d"},"taxa":[{"id":"CWE-259","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-540","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"A01:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"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":"9f295cdd70bcdd19c7a49c1d939018e53645f529bd45a44f8d567ebb4045a934"},"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":"f44d0325dc77b9545514a6d42b70bfcf1290269ab750602a13e1686fcf26c45a"},"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":"80d3c4768ce11aab6db18f8d48e90560bc6cab277ce7523d64af345f8be8e52e"},"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":"60cf46b856811de54521cea3e02ab3502c0796425c19d89dcdba99875d36ad9d"},"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":"e5e19aa3e95d7eaac0bf5f086c4315831fc2a7bd2bd459e0dc3b745257db5257"},"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":"e9a3f6f2f82c8d69cd68b93a8ab720b21e8024b76b48dc734d04b13916276b99"},"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":"8af93b54d7b6d09176d9c9016e65470b9e3497c2e30cd6af0b8b0a89230292a4"},"taxa":[{"id":"CWE-829","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"A08:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"ruleId":"D29","level":"warning","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"b6832ebf39152beff615c7233819c3353964efda185c51ab95bea7f80100f140"},"taxa":[{"id":"CWE-1104","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-1329","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-8","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":"3c26b193da8f8724d83c4a60f1ccf976f6d44e1a05c28cdf0db5d44555f62de5"},"taxa":[{"id":"CWE-611","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"A02:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"ruleId":"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":"e6c47f2d3de10647aa6aad437e6a8559358c2b93eb9f9a5d4fd0bd9d1284eba0"},"properties":{"dependency":{"package":"fast-xml-parser","version":"5.3.4","advisory":"[GHSA redacted]","aliases":["[CVE redacted]","[CVE redacted]","[CVE redacted]","[CVE redacted]","[CVE redacted]","[CVE redacted]","[GHSA redacted]","[GHSA redacted]","[GHSA redacted]","[GHSA redacted]","[GHSA redacted]"],"reachability":{"kind":"not-imported"}}}},{"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":"6f8159bb2b99ad788dee6961f210d38c4b382dd21d0f6c049fa3576ed8d9a5db"},"properties":{"dependency":{"package":"libthrift","version":"0.23.0","advisory":"[GHSA redacted]","aliases":["BIT-thrift-2026-43871","[CVE redacted]","PYSEC-2026-3926"],"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":"dd8088d7231f8537a76bd573f1b8389331be84c9d04dd37921704f5ecff490b3"},"properties":{"dependency":{"package":"lz4-java","version":"1.8.1","advisory":"[GHSA redacted]","aliases":["[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]"],"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":"46b3c2b89c3f99002093f6da4fb6c0675e01d45f7eacc07f5272d29402e3c2df"},"properties":{"dependency":{"package":"brace-expansion","version":"1.1.11","advisory":"[GHSA redacted]","aliases":["[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]"],"reachability":{"kind":"not-imported"}}}},{"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":"ea9a5d806ebce488b21ef80ec077d0783bde5dc44c32c0ea3fb6673121ca922f"},"properties":{"dependency":{"package":"braces","version":"3.0.3","advisory":"[GHSA redacted]","aliases":["[CVE redacted]"],"reachability":{"kind":"not-imported"}}}},{"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":"15c922a0a209c9049a6188d38136721d29b809423dcf299cf5cb94a266ba7621"},"properties":{"dependency":{"package":"browserslist","version":"4.21.5","advisory":"[GHSA redacted]","aliases":["[CVE redacted]","[CVE redacted]","[GHSA redacted]"],"reachability":{"kind":"not-imported"}}}},{"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":"65ec9d2600023285b610bb1d0bacd8078003bba27494444563bd575f4141fdaf"},"properties":{"dependency":{"package":"cross-spawn","version":"7.0.3","advisory":"[GHSA redacted]","aliases":["[CVE redacted]"],"reachability":{"kind":"not-imported"}}}},{"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":"ebde50d140d9eaffa5c36e3a62c84210deb6566bb39ecb07cd2873f29c9f869f"},"properties":{"dependency":{"package":"js-yaml","version":"3.14.1","advisory":"[GHSA redacted]","aliases":["[CVE redacted]","[CVE redacted]","[CVE redacted]","[CVE redacted]","[GHSA redacted]","[GHSA redacted]","[GHSA redacted]","[GHSA redacted]"],"reachability":{"kind":"not-imported"}}}},{"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":"ec9277ad781424a9d148f6d4b0cfa3fba75fb0a5e0a10e8878093a2e16c5a67d"},"properties":{"dependency":{"package":"lodash.pick","version":"4.4.0","advisory":"[GHSA redacted]","aliases":["[CVE redacted]"],"reachability":{"kind":"not-imported"}}}},{"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":"19df77baa9f3c33500e6bd5f54d0fee412893b2506735e6328d883af76f8ccfb"},"properties":{"dependency":{"package":"minimatch","version":"3.1.2","advisory":"[GHSA redacted]","aliases":["[CVE redacted]","[CVE redacted]","[CVE redacted]","[GHSA redacted]","[GHSA redacted]"],"reachability":{"kind":"not-imported"}}}},{"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":"6de79b4f4d889ce1ab59be5dc12a619b63e9b1e923ed29b867b931eb2770c42c"},"properties":{"dependency":{"package":"nanoid","version":"3.3.6","advisory":"[GHSA redacted]","aliases":["[CVE redacted]","[CVE redacted]","[CVE redacted]","[CVE redacted]","[GHSA redacted]","[GHSA redacted]","[GHSA redacted]"],"reachability":{"kind":"not-imported"}}}},{"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":"c5f6c00e02f705ea96b2c986b3f87a720bb252c23d011d77dd68642f9e24a413"},"properties":{"dependency":{"package":"picomatch","version":"2.3.1","advisory":"[GHSA redacted]","aliases":["[CVE redacted]","[CVE redacted]","[GHSA redacted]"],"reachability":{"kind":"not-imported"}}}},{"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":"960bab509d22daf8e19e0bf45d00b0669cd19e8c26c39295151d83109b29d17a"},"properties":{"dependency":{"package":"postcss","version":"8.4.31","advisory":"[GHSA redacted]","aliases":["[CVE redacted]","[CVE redacted]","[CVE redacted]","[CVE redacted]","[GHSA redacted]","[GHSA redacted]","[GHSA redacted]"],"reachability":{"kind":"not-imported"}}}},{"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":"9f128ad2229be0124fe8d8ac027d28a8d67726d73d22f98758ca2f1b5db7756f"},"properties":{"dependency":{"package":"rollup","version":"3.29.5","advisory":"[GHSA redacted]","aliases":["[CVE redacted]"],"reachability":{"kind":"not-imported"}}}},{"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":"c51a4b5c70b2aa3e229e798acb4bc6d4cdd4f904a19863c827c9c1d764fa660d"},"properties":{"dependency":{"package":"source-map-js","version":"1.0.2","advisory":"[GHSA redacted]","aliases":["[CVE redacted]"],"reachability":{"kind":"not-imported"}}}},{"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":"befd8eb24803341168519f3119afa0cc4b3843d209471a35d4ab13e75103cff9"},"properties":{"dependency":{"package":"vite","version":"4.5.9","advisory":"[GHSA redacted]","aliases":["[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]"],"reachability":{"kind":"production","file":"apps/rule-manager/client/src/ts/index.tsx","line":11}}}},{"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":"3b1493a881ad5588ded8ce9122631d60a533c8077c7c3f8a09eafd3212efe758"},"properties":{"dependency":{"package":"aws-cdk-lib","version":"2.234.1","advisory":"[GHSA redacted]","aliases":["[CVE redacted]","[CVE redacted]","[GHSA redacted]","[GHSA redacted]","GO-2026-6093"],"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":"f45a95a7a5d0894cb9ca54815fbf80bd990a54be6f4edc3a62b4c18c3e72b3e5"},"properties":{"dependency":{"package":"brace-expansion","version":"2.0.1","advisory":"[GHSA redacted]","aliases":["[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]"],"reachability":{"kind":"not-imported"}}}},{"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":"238a58ebef077e0db2701ba424f9de8812f9e3ab92d92e6cbf9dd1dc5999b849"},"properties":{"dependency":{"package":"browserslist","version":"4.23.2","advisory":"[GHSA redacted]","aliases":["[CVE redacted]","[CVE redacted]","[GHSA redacted]"],"reachability":{"kind":"not-imported"}}}},{"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":"631c617a98faed88914fc7bfff5cf756c679942b65f8a851663f156407d68165"},"properties":{"dependency":{"package":"js-yaml","version":"4.1.1","advisory":"[GHSA redacted]","aliases":["[CVE redacted]","[CVE redacted]","[CVE redacted]","[GHSA redacted]","[GHSA redacted]","[GHSA redacted]"],"reachability":{"kind":"not-imported"}}}},{"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":"29ed518c9976de4ad41d9fe32b979f4db077e8b353e61a279d2aa294801b8e09"},"properties":{"dependency":{"package":"minimatch","version":"5.1.6","advisory":"[GHSA redacted]","aliases":["[CVE redacted]","[CVE redacted]","[CVE redacted]","[GHSA redacted]","[GHSA redacted]"],"reachability":{"kind":"not-imported"}}}},{"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":"1b3ade10dae77e70d7f5b5c99afda4be14c2619a7ef721ffb7b1dcea2dd3e08f"},"properties":{"dependency":{"package":"minimatch","version":"9.0.5","advisory":"[GHSA redacted]","aliases":["[CVE redacted]","[CVE redacted]","[CVE redacted]","[GHSA redacted]","[GHSA redacted]"],"reachability":{"kind":"not-imported"}}}},{"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":"f873ac09e2a50927295199787a8b8d5810fe91b509abcabc02d08c40a4136c82"},"properties":{"dependency":{"package":"@babel/helpers","version":"7.21.5","advisory":"[GHSA redacted]","aliases":["[CVE redacted]"],"reachability":{"kind":"not-imported"}}}},{"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":"8e3a0e7f693a0407a43604e137aef1a703aefa80fde9790827c0c746b69d091a"},"properties":{"dependency":{"package":"@babel/runtime","version":"7.21.0","advisory":"[GHSA redacted]","aliases":["[CVE redacted]"],"reachability":{"kind":"not-imported"}}}},{"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":"bd5a134187b974a0bd48fb695d4f9889565d778af33c62125a6dbb44d83da526"},"properties":{"dependency":{"package":"@remix-run/router","version":"1.23.2","advisory":"[GHSA redacted]","aliases":["[CVE redacted]"],"reachability":{"kind":"not-imported"}}}},{"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":"544f613e033e1b54c6ef7c23565a34f8440c5a0dfb03c9c652ef23e95be05698"},"properties":{"dependency":{"package":"esbuild","version":"0.18.12","advisory":"[GHSA redacted]","reachability":{"kind":"not-imported"}}}},{"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":"1f0e6d2b96a0d231b21adfac7dc1e7e5b8297967f879e6904745afe440bebaff"},"properties":{"dependency":{"package":"micromatch","version":"4.0.5","advisory":"[GHSA redacted]","aliases":["[CVE redacted]"],"reachability":{"kind":"not-imported"}}}},{"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":"cafa8534a18787c25b470aa67823df95935e86dd6178b4704849b1c872279bab"},"properties":{"dependency":{"package":"moment","version":"2.29.4","advisory":"[GHSA redacted]","aliases":["[CVE 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":"eca8252fc166caf89f958174bd9fe729c08e41c8b46cd651fb88d2fb849309a3"},"properties":{"dependency":{"package":"prismjs","version":"1.27.0","advisory":"[GHSA redacted]","aliases":["[CVE redacted]"],"reachability":{"kind":"not-imported"}}}},{"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":"8f5e5e60c3de8459764dff6783fdbf4bcd218caf8684e49604fb27c2d5e9cfa5"},"properties":{"dependency":{"package":"react-router","version":"6.30.3","advisory":"[GHSA redacted]","aliases":["[CVE redacted]","[CVE redacted]","[CVE redacted]","[GHSA redacted]","[GHSA redacted]"],"reachability":{"kind":"not-imported"}}}},{"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":"d05a5243596cb4cf6e7305fa2892462ee15d2b28b603eb2cb34a350cdaf6c0f6"},"properties":{"dependency":{"package":"react-router-dom","version":"6.30.3","advisory":"[GHSA redacted]","aliases":["[CVE redacted]"],"reachability":{"kind":"production","file":"apps/rule-manager/client/src/ts/components/PageNotFound.tsx","line":3}}}},{"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":"8c7d6aca1d740425d43b6db6ef5cb01eba9a281eb7db694d73e34947d32aa1b3"},"properties":{"dependency":{"package":"sprintf-js","version":"1.0.3","advisory":"[GHSA redacted]","aliases":["[CVE redacted]"],"reachability":{"kind":"not-imported"}}}},{"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":"06dbd106b188aaee61ba6fb8810ad43e97f7e6c12d5ac5e8ad0966868456cb94"},"properties":{"dependency":{"package":"uuid","version":"8.3.2","advisory":"[GHSA redacted]","aliases":["[CVE redacted]","[CVE redacted]"],"reachability":{"kind":"not-imported"}}}},{"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":"ab781685ab74c0e330a7660ededa497b8e14645c5a3020274a95c1e03079676c"},"properties":{"dependency":{"package":"yaml","version":"1.10.2","advisory":"[GHSA redacted]","aliases":["[CVE redacted]"],"reachability":{"kind":"not-imported"}}}},{"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":"11f02d6882344c76e00f052cd51e6cec0ede756576eff8cdcf6692e101734439"},"properties":{"dependency":{"package":"@babel/helpers","version":"7.24.8","advisory":"[GHSA redacted]","aliases":["[CVE redacted]"],"reachability":{"kind":"not-imported"}}}},{"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":"2598514339ee23ffba1f54ccdb7fb54def7cb7e99e9f08aa6d55eb160ef9eccd"},"properties":{"dependency":{"package":"ajv","version":"8.12.0","advisory":"[GHSA redacted]","aliases":["[CVE redacted]"],"reachability":{"kind":"not-imported"}}}},{"ruleId":"D30","level":"note","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"c98eddb89dd85c4e0cedc710d68b3e8323efc71c4f0b6d9d7ba7413a5e88cedb"},"properties":{"dependency":{"package":"@babel/core","version":"7.21.8","advisory":"[GHSA redacted]","aliases":["[CVE redacted]"],"reachability":{"kind":"not-imported"}}}},{"ruleId":"D30","level":"note","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"061075f1b4f607a6301128697a0d152287abfa2f2c9856689caa88c8d3f12b12"},"properties":{"dependency":{"package":"@babel/core","version":"7.24.8","advisory":"[GHSA redacted]","aliases":["[CVE redacted]"],"reachability":{"kind":"not-imported"}}}},{"ruleId":"D30","level":"note","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"f61418bff5ea43e5e19b2b8bbb7509360134c300f30b5c0e1c5b4710be73f599"},"properties":{"dependency":{"package":"diff","version":"4.0.2","advisory":"[GHSA redacted]","aliases":["[CVE redacted]"],"reachability":{"kind":"not-imported"}}}},{"ruleId":"D31","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"ab92a1628cd1667b980737ded7ccc3626ac57a21801920a558f6441bf7c0c5af"},"taxa":[{"id":"CWE-250","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-668","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"A01:2025","toolComponent":{"name":"OWASP Top 10","guid":"7d1f0c2e-4b6a-4e39-9a51-0b2e8c3d5f61"}}]},{"ruleId":"D31","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":"2def96c7527a0760956db9f4b7ea49bcf60e6b53d845d94c1ad28e66d1c4c6e6"},"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":"D31","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":"040ea9712e41e29d3c3d066bf826267fc1557188581aaf2bc5a44a7a54af3c53"},"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":"D34","level":"note","message":{"text":"Concentrated knowledge decay: 45 of 49 significant files have no living knowledge, while the repository is still being changed at a low rate (13 commit(s) in the last 90 days) \u2014 so this is one repo-wide knowledge-decay state, not 45 separate risks. Counted over 49 of the 136 production source files in this repository: the rest are under the ~2,400-byte size floor this dimension measures over. The code moved on without the people who understood these files: document them or schedule a read-through before the next change lands in them."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"008bd8d3156a7f5206da709f59f1f87af76671c6b9becea72c8c9cffbcbd4f8e"}},{"ruleId":"D34","level":"note","message":{"text":"Most significant orphaned file: One of the orphaned files carrying the most lost knowledge \u2014 ranked by size weighted by the file\u0027s role in the codebase, the same weighting behind the score above, so core code outranks equally large plumbing. A reasonable place to start a read-through before the aggregate risk above bites."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"apps/rule-manager/app/db/DbRuleDraft.scala"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"4e8df74b5e30f8eaf4824543d56d3645657c3bb5578ff4813c50148230d9f1bf"}},{"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":"apps/rule-manager/app/service/RuleManager.scala"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"6b2b0e1114753bf03576d67b508dc6de636024809d7c811d20208684e5559d9e"}},{"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":"apps/checker/app/services/MatcherPool.scala"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"240878ecf39d7a728cc9ab3e3aa6a5fa586ab2effc1752e682c67f473a7b2c00"}},{"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":"apps/rule-manager/app/controllers/RulesController.scala"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"6ea2053bd22024714d88e2e944a07be473643c628a6f1c5ff354bf6a58c42e3e"}},{"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":"apps/rule-manager/app/db/DbRuleLive.scala"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"39d5cfb4c4c965ab6a4c05faf8e2a16d93cba034b2043ad5b86954e1d118387c"}},{"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":"apps/rule-manager/client/src/ts/components/table/PaginatedRulesTable.tsx"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"a746d57bfb9584dec0e3c31383ac0c36708b5d3c7b0b05719ae6fffe7f7b9c86"}},{"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":"apps/rule-manager/client/src/ts/components/TagsTable.tsx"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"6fba3593a49ba174ab469fa137b7ca326c852ccd64e3d907dfb3b26e6442a971"}},{"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":"apps/rule-manager/client/src/ts/components/RuleForm.tsx"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"9b57f221f9696cd21ecc0d8414f0b0b19657e4b774d1533ce7890de0ba4e3ae7"}},{"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":"apps/rule-manager/client/src/ts/components/Diff.tsx"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"1e807a91a90b6a777193b15806c2744fd444d9f165af08451ae5b757377eccfb"}},{"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":"apps/rule-manager/client/src/ts/components/hooks/useRule.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"85d49ca5540589d6330a2259a660c342bc97f15de8fd6126c3b6642a56f5f6b5"}},{"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":"apps/rule-manager/client/src/ts/components/pages/Rules.tsx"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"f44121d0a8db538b378a22447f07e2aff15e18b7dd07d56fd71dbd101dbfe612"}},{"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":"apps/checker/app/services/collins/DictionaryBuilder.scala"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"9f352771b381b8a13eaf0749d9d4b56bb413a3b1a0dcfc2ab46fd507d0fa25e5"}},{"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":"apps/checker/app/matchers/LanguageToolMatcher.scala"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"d5c50590341c68c0fa66f4cd47d69539f42703ad6e06d6a9f0e541e3a4608e3f"}},{"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":"apps/rule-manager/app/service/SheetsRuleResource.scala"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"cd14ba69b2267c095c03ce6b206634743ffe37fcaa9a66de47eb951656203d59"}},{"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":"apps/rule-manager/app/service/RuleTesting.scala"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"d09a66b667ea8de42b4096412359e3f15a8b5ca049fcffcfbee04ac9efcd34e7"}},{"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":"apps/common-lib/src/main/scala/com/gu/typerighter/model/CheckerRule.scala"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"3121d18871014b2af0a864a5d3bbdefa31b417808e6feb7f33004e34eed8afed"}},{"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":"apps/rule-manager/client/src/ts/components/pages/TestRule.tsx"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"10a87dad85b42f6b6e195baa3cb0b28e140a5ea623a12ea8081d0119d310107e"}},{"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":"apps/rule-manager/client/src/ts/components/RuleContent.tsx"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"e013b673e8f7e74114c8323b0ed352d05a20517dd0e6d5249c33efdb066eae98"}},{"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":"apps/checker/app/matchers/DictionaryMatcher.scala"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"0ef5ae4a6ce7e6cc3f78ced5695a2c20b720df731d6a2fa12f6b267a99606b85"}},{"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":"apps/checker/app/AppComponents.scala"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"102eb3c095ef60b8db58d3b1b1aac2883dd5ee5f333c6aa9acf00425b4f2ae0b"}},{"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":"apps/rule-manager/app/db/Tags.scala"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"d357e74883c2a5e047efd50065baba7c416af18ab8560edda4589ec746218fb6"}},{"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":"apps/rule-manager/client/src/ts/components/context/tags.tsx"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"d246d88bed62f8b26cba7ab62a9ff01aad33fbc9823ff5440be73e14129120dc"}},{"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":"apps/checker/app/services/MatcherProvisionerService.scala"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"f074221f43af1951b98b9cb11633dc126e2072877ece0d8b5f22381d80ba24a6"}},{"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":"apps/rule-manager/app/utils/Dictionary.scala"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"9275b759a348977feda7a5ad893e18ff8368f4eaa5ad491d9cfa00504a1cf706"}},{"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":"apps/rule-manager/app/db/RuleTagLive.scala"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"14873e3f7dd2c2b8ab66176f9d4a8a116757a8446a27d5c2fa867df69a9a8c76"}},{"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":"apps/rule-manager/client/src/ts/components/icons/index.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"9c19e2fb5620f5b77ec984c4fbc204b81b31431903e43b559b943b3409938680"}},{"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":"apps/rule-manager/client/src/ts/utils/TyperighterChunkedAdapter.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"fd8312a5c17d82a56d05d485347ede78465fa7cc1b15067a3f8d79efa73e997a"}},{"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":"apps/rule-manager/client/src/ts/components/hooks/useRules.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"e07641cd53e76ac85211ce2e9c4058b4afd5e6b77b03c1005dcb8792a62d6057"}},{"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":"apps/rule-manager/client/src/ts/components/RuleFormBatchEdit.tsx"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"bceb8365f720bf37163d4ca6e6eedecb6e834eef1faf54e4363c2a025e368a7f"}},{"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":"apps/checker/app/services/collins/SpellDictionaryBuilder.scala"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"5dec6a16540e6ca5bcc4c509945204c02bce90f689f3f625d5d4f7dbf25d444f"}},{"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":"apps/checker/app/controllers/ApiController.scala"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"a51cc3d8c0091b5412c5fb8caa69a51be9185f643ccd6624593849677d9dc9a4"}},{"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":"apps/rule-manager/app/db/RuleTagDraft.scala"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"7c003f2862eb16c0ae0cc4bf2537567a899eb5e636a9bd45074026081a9c1a34"}},{"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":"apps/common-lib/src/main/scala/com/gu/typerighter/model/RuleMatch.scala"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"9beddc007a0e49d91ea3e2616a86cda815da8677675fd6bbd52786b1dd959edc"}},{"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":"apps/rule-manager/client/src/ts/components/context/featureSwitches.tsx"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"d8d9b316e76bd29b9640a6981e6acd7236b6a8bc2f96d1e1608bbf4a9d2b8c42"}},{"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":"apps/rule-manager/app/controllers/TagsController.scala"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"f1b89507f06b556bf63c4324bfbf81d82bb0652f1a6c9fac486cd1704227d899"}},{"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":"apps/rule-manager/app/AppComponents.scala"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"dc46a4460f2ff23bbeeec194d0033016e48c654e3ec8bebbb923844dbe68cf43"}},{"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":"script/js/dump-db.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"87390580e97dbf85d99093fefd0fff2a4a22b2d9adfd0554abb0eb13a455712a"}},{"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":"apps/checker/app/utils/Timer.scala"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"cfeb16667670909f531ec7102ed7056a3f13e9c4c7ce1ab5961f3fc6504a7881"}},{"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":"apps/rule-manager/client/src/ts/components/hooks/useBatchRules.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"256da9f53521428c899f6e4b82ab5cd2c407552d81196b8a216d1c635591fa00"}},{"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":"apps/common-lib/src/main/scala/com/gu/typerighter/lib/CommonConfig.scala"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"bc6c77dd59c504cd95a8bf0d91b7e35c2c08cde5bb6ae932a4291739d6668246"}},{"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":"apps/rule-manager/app/model/CheckerRuleForm.scala"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"9735d2a7c075bdfc21eb4302922f618ca3108934c852ae4bc402669e97f72e39"}},{"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":"apps/rule-manager/client/src/ts/components/RuleHistory.tsx"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"ac4f57955239d422d22e4d86b71b8d39349b47f14d7aa26fe2ee92fb6dcbe90d"}},{"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":"apps/common-lib/src/main/scala/com/gu/typerighter/model/TextBlock.scala"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"3249753b83b5d1262cf2bfbaf9e31e0f4fa04d94c09f3c75659bcc48810247dd"}},{"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":"apps/rule-manager/app/service/DictionaryResource.scala"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"b48028e603bcbfd05789d559529d7fae462aeefc101ad2b914b1df5e6e1b786b"}},{"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":"apps/rule-manager/client/src/ts/components/CategorySelector.tsx"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"23866203005c9f192e71dad7b5718c88e363cde977acc858c54ed96310b3dec0"}},{"ruleId":"D35","level":"warning","message":{"text":"Change coupling: CreateRuleForm.scala \u2194 UpdateRuleForm.scala: \u0060apps/rule-manager/app/model/CreateRuleForm.scala\u0060 and \u0060apps/rule-manager/app/model/UpdateRuleForm.scala\u0060 change together 64% of the time (7 of the 11 commits that touched whichever of the two files changed less often, counting a file under its earlier names as well \u2014 a repo-wide or module-wide sweep is evidence about the sweep rather than about any pair inside it and is left out of BOTH sides of this ratio, while a dependency bump, a formatter/rename sweep, or a commit whose edit to one of the two files was a tool directive such as //go:generate or whitespace only is left out of the shared count ONLY, so the two sides are not taken over identical commit sets). They sit in the same directory, and in this ecosystem sibling files there normally share one namespace/package \u2014 so a direct reference between them needs no import and this pass cannot see whether one exists. Read the pair before acting: if one file only DECLARES what the other consumes (a constants/types file beside its user), the co-change is definitional and the question is whether the split earns its keep; if they duplicate structure, extract the common part into a shared function or type they both call; if neither holds, the coupling is hidden and worth breaking. You can check this without leaving the row: of the 7 shared commits counted here, the most recent 3 are \u006044a76380\u0060 Add languageToolCore to form options, and permit creating and saving \u2026; \u006071db8c07\u0060 Correct validation error message to mention dictionary rules; \u006034cd61d2\u0060 Rename DbRuleManager -\u003E RuleManager, SheetsRuleManager -\u003E SheetsRuleR\u2026 \u2014 run \u0060git show\u0060 on any of them."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"apps/rule-manager/app/model/CreateRuleForm.scala"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"ae7e9723eab35a2c3ef1bce63c4058833fec93aaa0fe998a84ccb3a870d71b64"}},{"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":"AX6","level":"note","message":{"text":"Fat interface: DbRuleCommon (16 abstract members): \u0060DbRuleCommon\u0060 declares 16 abstract members: \u0060ruleType\u0060, \u0060pattern\u0060, \u0060replacement\u0060, \u0060category\u0060, \u0060tags\u0060, \u0060description\u0060, \u0060notes\u0060, \u0060externalId\u0060, \u0060forceRedRule\u0060, \u0060advisoryRule\u0060, \u0060createdAt\u0060, \u0060createdBy\u0060, \u0060updatedAt\u0060, \u0060updatedBy\u0060, \u0060revisionId\u0060, \u0060ruleOrder\u0060. Counted over its ABSTRACT members \u2014 a \u0060def\u0060 with no body or a \u0060val\u0060/\u0060var\u0060 with no initializer, once per signature; concrete members, private and protected members, and members of a companion \u0060object\u0060 are not counted, because no implementer is forced to write them. A wide interface forces every implementer and caller to depend on methods they don\u0027t use (the Interface-Segregation \u0027I\u0027 in SOLID). Split it into focused role-interfaces."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"apps/rule-manager/app/db/DbRule.scala"},"region":{"startLine":5}}}],"partialFingerprints":{"codehealthFindingId/v1":"56badf12dabc5324bd608210817bd2a6a00b2675c2b6bf1f6edbea03d38fc644"}},{"ruleId":"P2","level":"note","message":{"text":"Logging is not universal: Only 1/2 runnable modules use logging (modules with no entry point or server are excluded \u2014 they are libraries a runnable module hosts). Silent: \u0060cdk\u0060."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"91a94e21d6d4d0e6a2003f94505b0b02b157176f0b24c4820f3f82b4447a97fe"}},{"ruleId":"P3","level":"note","message":{"text":"No SAST: No static application security testing detected. For this repository\u0027s stack, add scalafix or scapegoat (or \u0060semgrep --config=auto\u0060, which runs on any language) as a CI step. What was searched, so you can tell an absence from a miss: the 3622 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":"P5","level":"warning","message":{"text":"No DR/backup evidence: A persistence guard (data volume / purge-protection) was found, but no backup, geo-recovery or RTO/RPO controls were evidenced \u2014 a volume that survives a container recreate is not a tested restore from catastrophic loss."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"5daabb38c90b07af65b8738cf94ce884e90a7d8fef810d341de5c186188c8fe0"}},{"ruleId":"P6","level":"note","message":{"text":"No changelog: No CHANGELOG/HISTORY/RELEASES file \u2014 what shipped when isn\u0027t easy to reconstruct for support or audit. (Versioning/tagging makes releases traceable, but a changelog records the what.)"},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"dda5aa5aed8cbb292c3ef2b733bc138f614293ae6426c85e98bf31ef330d9415"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (21 lines \u00D7 4 locations): apps/rule-manager/client/src/ts/components/hooks/useRule.ts:102 \u00B7 apps/rule-manager/client/src/ts/components/hooks/useRule.ts:128 \u00B7 apps/rule-manager/client/src/ts/components/hooks/useRule.ts:154 \u00B7 apps/rule-manager/client/src/ts/components/hooks/useRule.ts:285 \u2014 all 4 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":"apps/rule-manager/client/src/ts/components/hooks/useRule.ts"},"region":{"startLine":102}}}],"partialFingerprints":{"codehealthFindingId/v1":"7d062117f29b3b4ac30242f5aaf536361089d54216882df62e432721c4062323"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (21 lines \u00D7 2 locations): apps/rule-manager/client/src/ts/components/hooks/useRules.ts:87 \u00B7 apps/rule-manager/client/src/ts/components/hooks/useRules.ts:113 \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":"apps/rule-manager/client/src/ts/components/hooks/useRules.ts"},"region":{"startLine":87}}}],"partialFingerprints":{"codehealthFindingId/v1":"8cf8742e603d295fd8901ea42ed274eda1a225055e3a74a008b090d4bd73ecf3"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (20 lines \u00D7 3 locations): apps/rule-manager/client/src/ts/components/context/tags.tsx:67 \u00B7 apps/rule-manager/client/src/ts/components/context/tags.tsx:128 \u00B7 apps/rule-manager/client/src/ts/components/hooks/useRule.ts:222 \u2014 the 3 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":"apps/rule-manager/client/src/ts/components/context/tags.tsx"},"region":{"startLine":67}}}],"partialFingerprints":{"codehealthFindingId/v1":"9f375a4b9b6d4e000173ffff18403245e04dc34d42705a0cfd8ae245c3405bad"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (17 lines \u00D7 2 locations): apps/rule-manager/client/src/ts/components/RuleContent.tsx:170 \u00B7 apps/rule-manager/client/src/ts/components/RuleContent.tsx:187 \u2014 all 2 copies are in the same file, and the SHAPE of this repetition could not be determined. It is not a run of declarations, a listing, a declaration header, a type body or a slice through a construct \u2014 and it was not measured as a run of executable statements either, so this row cannot tell you whether a function can stand where these lines are. Read the two spans before acting, because the move is opposite in the two cases. Where they are statements, the ordinary answer holds: give the shared part one home and call it from each site. Where they turn out to be declarations, a literal\u0027s entries, or the cases of an enumeration, there is no call site to call anything from, and collapsing them would delete what each copy pins \u2014 a shared base type, a generated set, or one exported constant each site refers to is the move instead, and sometimes the honest answer is that there is nothing to extract at all. Reported because the copies drift apart the first time only one of them is edited, which is true whichever of those they are."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"apps/rule-manager/client/src/ts/components/RuleContent.tsx"},"region":{"startLine":170}}}],"partialFingerprints":{"codehealthFindingId/v1":"f4e3bcfce4cd4bc56eb6c7a188376018ae5fd7afbeb10e79f7af8e751647b82a"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (17 lines \u00D7 2 locations): apps/rule-manager/client/src/ts/components/modals/Reason.tsx:61 \u00B7 apps/rule-manager/client/src/ts/components/modals/Revert.tsx:46 \u2014 the 2 copies sit in sibling files in one directory, so check first whether one of them (or an existing module there) already owns this behaviour and the others should call it; otherwise extract it into one module in that directory and have each site call it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"apps/rule-manager/client/src/ts/components/modals/Reason.tsx"},"region":{"startLine":61}}}],"partialFingerprints":{"codehealthFindingId/v1":"846d367fba2528db3dd712b6ddf31e8c225dbef6cd860ae37ec40ccd4e833246"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (16 lines \u00D7 2 locations): apps/rule-manager/client/src/ts/components/hooks/useRule.ts:246 \u00B7 apps/rule-manager/client/src/ts/components/hooks/useRule.ts:276 \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":"apps/rule-manager/client/src/ts/components/hooks/useRule.ts"},"region":{"startLine":246}}}],"partialFingerprints":{"codehealthFindingId/v1":"efdc32bf38441c36eb786bf0dec569b5767e5e3bce04da71136d6a6e3fdf9fac"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (13 lines \u00D7 2 locations): apps/rule-manager/client/src/ts/components/modals/Reason.tsx:36 \u00B7 apps/rule-manager/client/src/ts/components/modals/Revert.tsx:32 \u2014 the 2 copies are spread across 2 files, and the CITED SPAN is not a self-contained block \u2014 it runs from inside one construct into the next (the tail of a branch plus the head of the following one, a run of switch arms, the end of a declaration plus the list that follows it) rather than covering a whole unit. So do not lift these lines literally: no call can be substituted for a half-open construct. Extract the enclosing repeated UNIT instead \u2014 the whole function, component or branch these lines sit in \u2014 and where the repetition IS the construct (a run of switch arms, a stack of near-identical declarations) replace it with one table or registry looked up by key rather than a helper each arm calls. The copies still drift apart the first time only one of them is edited, which is why this is reported."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"apps/rule-manager/client/src/ts/components/modals/Reason.tsx"},"region":{"startLine":36}}}],"partialFingerprints":{"codehealthFindingId/v1":"7ef6092ec26958ab0a25680f2197fc3408d5f5a6f2f9b794eb29b50191660d84"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (11 lines \u00D7 5 locations): apps/rule-manager/client/src/ts/components/hooks/useRule.ts:67 \u00B7 apps/rule-manager/client/src/ts/components/hooks/useRule.ts:93 \u00B7 apps/rule-manager/client/src/ts/components/hooks/useRule.ts:144 \u00B7 apps/rule-manager/client/src/ts/components/hooks/useRule.ts:170 \u00B7 \u002B1 more site(s) not listed \u2014 all 5 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":"apps/rule-manager/client/src/ts/components/hooks/useRule.ts"},"region":{"startLine":67}}}],"partialFingerprints":{"codehealthFindingId/v1":"0b9d6c2085f93886a92cbc70dc5d48cfb6f3d02a9cef85b95fbba2bb1f4a3597"}},{"ruleId":"R10","level":"warning","message":{"text":"Duplicated block (8 lines \u00D7 2 locations): apps/rule-manager/client/src/ts/utils/api.ts:33 \u00B7 apps/rule-manager/client/src/ts/utils/api.ts:42 \u2014 both copies are in the same file, so extract the block into one function there and call it from each site \u2014 the copies drift apart the first time only one of them is edited."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"apps/rule-manager/client/src/ts/utils/api.ts"},"region":{"startLine":33}}}],"partialFingerprints":{"codehealthFindingId/v1":"1c06a71259d29092b01f3bcbbcbba7b180fcdd69ecafd72f4b3c63294c248f8d"}},{"ruleId":"R11","level":"warning","message":{"text":"Boundary violation [package:third-party-deep-import]: apps/rule-manager/client/src/ts/components/RuleStatus.tsx:19 imports @elastic/eui/src/global_styling/mixins/_typography, reaching past a declared dependency\u0027s public entry into its build output \u2014 that path is the package\u0027s toolchain layout, not its API, and a minor version bump can relocate it with no semver signal. Import from the package\u0027s documented entry point instead."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"apps/rule-manager/client/src/ts/components/RuleStatus.tsx"},"region":{"startLine":19}}}],"partialFingerprints":{"codehealthFindingId/v1":"d1df1a08fd88b370355cf689324cda76a43a4461ec7e40e814812f26ea87c5c1"}},{"ruleId":"R11","level":"warning","message":{"text":"Boundary violation [package:third-party-deep-import]: apps/rule-manager/client/src/ts/components/icons/index.ts:1 imports @elastic/eui/src/components/icon/icon, reaching past a declared dependency\u0027s public entry into its build output \u2014 that path is the package\u0027s toolchain layout, not its API, and a minor version bump can relocate it with no semver signal. Import from the package\u0027s documented entry point instead."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"apps/rule-manager/client/src/ts/components/icons/index.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"03741e491abe1edbf312752b9c45a8470a6f7c72ad68699a3343e2837e2e546f"}},{"ruleId":"R11","level":"warning","message":{"text":"Boundary violation [package:third-party-deep-import]: apps/rule-manager/client/src/ts/components/icons/index.ts:2 imports @elastic/eui/src/components/icon/assets/arrow_down, reaching past a declared dependency\u0027s public entry into its build output \u2014 that path is the package\u0027s toolchain layout, not its API, and a minor version bump can relocate it with no semver signal. Import from the package\u0027s documented entry point instead."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"apps/rule-manager/client/src/ts/components/icons/index.ts"},"region":{"startLine":2}}}],"partialFingerprints":{"codehealthFindingId/v1":"5503679d822213f5b17b4f10bddf5f05ab335dd5e6befae3daf1a724adf8b96d"}},{"ruleId":"R11","level":"warning","message":{"text":"Boundary violation [package:third-party-deep-import]: apps/rule-manager/client/src/ts/components/icons/index.ts:3 imports @elastic/eui/src/components/icon/assets/arrow_right, reaching past a declared dependency\u0027s public entry into its build output \u2014 that path is the package\u0027s toolchain layout, not its API, and a minor version bump can relocate it with no semver signal. Import from the package\u0027s documented entry point instead."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"apps/rule-manager/client/src/ts/components/icons/index.ts"},"region":{"startLine":3}}}],"partialFingerprints":{"codehealthFindingId/v1":"a4c82dc4c112353c59518aa06e36aa44f26f3abf4d29ff3145ed83e9135527bd"}},{"ruleId":"R11","level":"warning","message":{"text":"Boundary violation [package:third-party-deep-import]: apps/rule-manager/client/src/ts/components/icons/index.ts:4 imports @elastic/eui/src/components/icon/assets/arrow_left, reaching past a declared dependency\u0027s public entry into its build output \u2014 that path is the package\u0027s toolchain layout, not its API, and a minor version bump can relocate it with no semver signal. Import from the package\u0027s documented entry point instead."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"apps/rule-manager/client/src/ts/components/icons/index.ts"},"region":{"startLine":4}}}],"partialFingerprints":{"codehealthFindingId/v1":"e1b6c2fa1e9c2cdf2c65426c62c451def2e4660fc0e7352b18bf851482f8f83a"}},{"ruleId":"R11","level":"warning","message":{"text":"Boundary violation [package:third-party-deep-import]: apps/rule-manager/client/src/ts/components/icons/index.ts:5 imports @elastic/eui/src/components/icon/assets/arrowStart, reaching past a declared dependency\u0027s public entry into its build output \u2014 that path is the package\u0027s toolchain layout, not its API, and a minor version bump can relocate it with no semver signal. Import from the package\u0027s documented entry point instead."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"apps/rule-manager/client/src/ts/components/icons/index.ts"},"region":{"startLine":5}}}],"partialFingerprints":{"codehealthFindingId/v1":"cb370db82e7def61f0a140ac2f9bb975106c7e5906b07a365458f14961cd87e8"}},{"ruleId":"R11","level":"warning","message":{"text":"Boundary violation [package:third-party-deep-import]: apps/rule-manager/client/src/ts/components/icons/index.ts:6 imports @elastic/eui/src/components/icon/assets/arrowEnd, reaching past a declared dependency\u0027s public entry into its build output \u2014 that path is the package\u0027s toolchain layout, not its API, and a minor version bump can relocate it with no semver signal. Import from the package\u0027s documented entry point instead."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"apps/rule-manager/client/src/ts/components/icons/index.ts"},"region":{"startLine":6}}}],"partialFingerprints":{"codehealthFindingId/v1":"9d0ac532d7fb3a8e5e37320804ffdf4fa42e9b2e0960d8bcdf7bf515989935d0"}},{"ruleId":"R11","level":"warning","message":{"text":"Boundary violation [package:third-party-deep-import]: apps/rule-manager/client/src/ts/components/icons/index.ts:7 imports @elastic/eui/src/components/icon/assets/check, reaching past a declared dependency\u0027s public entry into its build output \u2014 that path is the package\u0027s toolchain layout, not its API, and a minor version bump can relocate it with no semver signal. Import from the package\u0027s documented entry point instead."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"apps/rule-manager/client/src/ts/components/icons/index.ts"},"region":{"startLine":7}}}],"partialFingerprints":{"codehealthFindingId/v1":"bc527829d0fd560a40ce77fe19d6b85990d152f77291fa3074934a23691f2706"}},{"ruleId":"R11","level":"warning","message":{"text":"Boundary violation [package:third-party-deep-import]: apps/rule-manager/client/src/ts/components/icons/index.ts:8 imports @elastic/eui/src/components/icon/assets/cross, reaching past a declared dependency\u0027s public entry into its build output \u2014 that path is the package\u0027s toolchain layout, not its API, and a minor version bump can relocate it with no semver signal. Import from the package\u0027s documented entry point instead."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"apps/rule-manager/client/src/ts/components/icons/index.ts"},"region":{"startLine":8}}}],"partialFingerprints":{"codehealthFindingId/v1":"7f4bd40362726a307379d0190b6bdb247a852f10567a59a51f01140947813adc"}},{"ruleId":"R11","level":"warning","message":{"text":"Boundary violation [package:third-party-deep-import]: apps/rule-manager/client/src/ts/components/icons/index.ts:9 imports @elastic/eui/src/components/icon/assets/empty, reaching past a declared dependency\u0027s public entry into its build output \u2014 that path is the package\u0027s toolchain layout, not its API, and a minor version bump can relocate it with no semver signal. Import from the package\u0027s documented entry point instead."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"apps/rule-manager/client/src/ts/components/icons/index.ts"},"region":{"startLine":9}}}],"partialFingerprints":{"codehealthFindingId/v1":"13321cbca0969096e4407a294e7eb79aa427f4fcca7e9d4634c7390fdcee7da9"}},{"ruleId":"R11","level":"warning","message":{"text":"Boundary violation [package:third-party-deep-import]: apps/rule-manager/client/src/ts/components/icons/index.ts:11 imports @elastic/eui/src/components/icon/assets/error, reaching past a declared dependency\u0027s public entry into its build output \u2014 that path is the package\u0027s toolchain layout, not its API, and a minor version bump can relocate it with no semver signal. Import from the package\u0027s documented entry point instead."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"apps/rule-manager/client/src/ts/components/icons/index.ts"},"region":{"startLine":11}}}],"partialFingerprints":{"codehealthFindingId/v1":"07be04d886c98ced6599865fbf7742a9b2945ef897c2c1169f6af3bd7c874004"}},{"ruleId":"R11","level":"warning","message":{"text":"Boundary violation [package:third-party-deep-import]: apps/rule-manager/client/src/ts/components/icons/index.ts:12 imports @elastic/eui/src/components/icon/assets/exit, reaching past a declared dependency\u0027s public entry into its build output \u2014 that path is the package\u0027s toolchain layout, not its API, and a minor version bump can relocate it with no semver signal. Import from the package\u0027s documented entry point instead."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"apps/rule-manager/client/src/ts/components/icons/index.ts"},"region":{"startLine":12}}}],"partialFingerprints":{"codehealthFindingId/v1":"2bdae7989e559ecea325933d1c902dc83aff48f23489cb65bb6afad0a4af1d55"}},{"ruleId":"R11","level":"warning","message":{"text":"Boundary violation [package:third-party-deep-import]: apps/rule-manager/client/src/ts/components/icons/index.ts:13 imports @elastic/eui/src/components/icon/assets/star_empty, reaching past a declared dependency\u0027s public entry into its build output \u2014 that path is the package\u0027s toolchain layout, not its API, and a minor version bump can relocate it with no semver signal. Import from the package\u0027s documented entry point instead."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"apps/rule-manager/client/src/ts/components/icons/index.ts"},"region":{"startLine":13}}}],"partialFingerprints":{"codehealthFindingId/v1":"a6bf333c1b375494ac86126e4e45247f79ed99848b0538f21da88cb4399b1994"}},{"ruleId":"R11","level":"warning","message":{"text":"Boundary violation [package:third-party-deep-import]: apps/rule-manager/client/src/ts/components/icons/index.ts:14 imports @elastic/eui/src/components/icon/assets/star_filled, reaching past a declared dependency\u0027s public entry into its build output \u2014 that path is the package\u0027s toolchain layout, not its API, and a minor version bump can relocate it with no semver signal. Import from the package\u0027s documented entry point instead."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"apps/rule-manager/client/src/ts/components/icons/index.ts"},"region":{"startLine":14}}}],"partialFingerprints":{"codehealthFindingId/v1":"1f5e0c9cd4eb2bdaed68fd6dece216b0fa084cb251932560bfcb0d160e912ae8"}},{"ruleId":"R11","level":"warning","message":{"text":"Boundary violation [package:third-party-deep-import]: apps/rule-manager/client/src/ts/components/icons/index.ts:15 imports @elastic/eui/src/components/icon/assets/pencil, reaching past a declared dependency\u0027s public entry into its build output \u2014 that path is the package\u0027s toolchain layout, not its API, and a minor version bump can relocate it with no semver signal. Import from the package\u0027s documented entry point instead."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"apps/rule-manager/client/src/ts/components/icons/index.ts"},"region":{"startLine":15}}}],"partialFingerprints":{"codehealthFindingId/v1":"21decd830530625d42f8730da4f64ad3a1ac2f3aeaa7043ad3908eebce46f7af"}},{"ruleId":"R11","level":"warning","message":{"text":"Boundary violation [package:third-party-deep-import]: apps/rule-manager/client/src/ts/components/icons/index.ts:16 imports @elastic/eui/src/components/icon/assets/return_key, reaching past a declared dependency\u0027s public entry into its build output \u2014 that path is the package\u0027s toolchain layout, not its API, and a minor version bump can relocate it with no semver signal. Import from the package\u0027s documented entry point instead."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"apps/rule-manager/client/src/ts/components/icons/index.ts"},"region":{"startLine":16}}}],"partialFingerprints":{"codehealthFindingId/v1":"c5ea6a8cfec7ca9747d2f7eaa73c67d06256c62d0b57672af24d6a6ebda8bfb6"}},{"ruleId":"R11","level":"warning","message":{"text":"Boundary violation [package:third-party-deep-import]: apps/rule-manager/client/src/ts/components/icons/index.ts:17 imports @elastic/eui/src/components/icon/assets/warning, reaching past a declared dependency\u0027s public entry into its build output \u2014 that path is the package\u0027s toolchain layout, not its API, and a minor version bump can relocate it with no semver signal. Import from the package\u0027s documented entry point instead."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"apps/rule-manager/client/src/ts/components/icons/index.ts"},"region":{"startLine":17}}}],"partialFingerprints":{"codehealthFindingId/v1":"83b884b180e2dcf6f381de99eb38f4c91b40a2a8c6c9a20a1bf2cc42c2c9e84d"}},{"ruleId":"R11","level":"warning","message":{"text":"Boundary violation [package:third-party-deep-import]: apps/rule-manager/client/src/ts/components/icons/index.ts:18 imports @elastic/eui/src/components/icon/assets/pageSelect, reaching past a declared dependency\u0027s public entry into its build output \u2014 that path is the package\u0027s toolchain layout, not its API, and a minor version bump can relocate it with no semver signal. Import from the package\u0027s documented entry point instead."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"apps/rule-manager/client/src/ts/components/icons/index.ts"},"region":{"startLine":18}}}],"partialFingerprints":{"codehealthFindingId/v1":"3b9288a4b740f0bc22e8c247a4b7a6e70a7538dbcbd828e7bee4da791ec14f45"}},{"ruleId":"R11","level":"warning","message":{"text":"Boundary violation [package:third-party-deep-import]: apps/rule-manager/client/src/ts/components/icons/index.ts:19 imports @elastic/eui/src/components/icon/assets/dot, reaching past a declared dependency\u0027s public entry into its build output \u2014 that path is the package\u0027s toolchain layout, not its API, and a minor version bump can relocate it with no semver signal. Import from the package\u0027s documented entry point instead."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"apps/rule-manager/client/src/ts/components/icons/index.ts"},"region":{"startLine":19}}}],"partialFingerprints":{"codehealthFindingId/v1":"93af7423a39c5e8f202463b6562170cadff54288fbf6565719c5021d6c96340b"}},{"ruleId":"R11","level":"warning","message":{"text":"Boundary violation [package:third-party-deep-import]: apps/rule-manager/client/src/ts/components/icons/index.ts:20 imports @elastic/eui/src/components/icon/assets/checkInCircleFilled, reaching past a declared dependency\u0027s public entry into its build output \u2014 that path is the package\u0027s toolchain layout, not its API, and a minor version bump can relocate it with no semver signal. Import from the package\u0027s documented entry point instead."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"apps/rule-manager/client/src/ts/components/icons/index.ts"},"region":{"startLine":20}}}],"partialFingerprints":{"codehealthFindingId/v1":"f253c164a75e5eb8caaaca6068846954bcffb03fd2b33d799db404e5b048c624"}},{"ruleId":"R11","level":"warning","message":{"text":"Boundary violation [package:third-party-deep-import]: apps/rule-manager/client/src/ts/components/icons/index.ts:21 imports @elastic/eui/src/components/icon/assets/apps, reaching past a declared dependency\u0027s public entry into its build output \u2014 that path is the package\u0027s toolchain layout, not its API, and a minor version bump can relocate it with no semver signal. Import from the package\u0027s documented entry point instead."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"apps/rule-manager/client/src/ts/components/icons/index.ts"},"region":{"startLine":21}}}],"partialFingerprints":{"codehealthFindingId/v1":"a4368c37ace22ac080442160c9b8deb48fb692fc586693e2b15ecdd625f807f3"}},{"ruleId":"R11","level":"warning","message":{"text":"Boundary violation [package:third-party-deep-import]: apps/rule-manager/client/src/ts/components/icons/index.ts:22 imports @elastic/eui/src/components/icon/assets/eye, reaching past a declared dependency\u0027s public entry into its build output \u2014 that path is the package\u0027s toolchain layout, not its API, and a minor version bump can relocate it with no semver signal. Import from the package\u0027s documented entry point instead."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"apps/rule-manager/client/src/ts/components/icons/index.ts"},"region":{"startLine":22}}}],"partialFingerprints":{"codehealthFindingId/v1":"eb2cfa5a868c6feb5f53bdb2dd640442e27bd7ddf009550a223ac7a7aa78ec8b"}},{"ruleId":"R11","level":"warning","message":{"text":"Boundary violation [package:third-party-deep-import]: apps/rule-manager/client/src/ts/components/icons/index.ts:23 imports @elastic/eui/src/components/icon/assets/eye_closed, reaching past a declared dependency\u0027s public entry into its build output \u2014 that path is the package\u0027s toolchain layout, not its API, and a minor version bump can relocate it with no semver signal. Import from the package\u0027s documented entry point instead."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"apps/rule-manager/client/src/ts/components/icons/index.ts"},"region":{"startLine":23}}}],"partialFingerprints":{"codehealthFindingId/v1":"a131dfd289fb953f0ab67a77aa6bfca0f567bf367c5ed43d4229aee6f044a956"}},{"ruleId":"R11","level":"warning","message":{"text":"Boundary violation [package:third-party-deep-import]: apps/rule-manager/client/src/ts/components/icons/index.ts:24 imports @elastic/eui/src/components/icon/assets/iInCircle, reaching past a declared dependency\u0027s public entry into its build output \u2014 that path is the package\u0027s toolchain layout, not its API, and a minor version bump can relocate it with no semver signal. Import from the package\u0027s documented entry point instead."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"apps/rule-manager/client/src/ts/components/icons/index.ts"},"region":{"startLine":24}}}],"partialFingerprints":{"codehealthFindingId/v1":"d3c81be66e9fdabe132c15ff343cf6d597033447837629254aa81ab4facc3707"}},{"ruleId":"R11","level":"warning","message":{"text":"Boundary violation [package:third-party-deep-import]: apps/rule-manager/client/src/ts/components/icons/index.ts:25 imports @elastic/eui/src/components/icon/assets/sort_down, reaching past a declared dependency\u0027s public entry into its build output \u2014 that path is the package\u0027s toolchain layout, not its API, and a minor version bump can relocate it with no semver signal. Import from the package\u0027s documented entry point instead."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"apps/rule-manager/client/src/ts/components/icons/index.ts"},"region":{"startLine":25}}}],"partialFingerprints":{"codehealthFindingId/v1":"6e50e68eaa1a0966d88b5ddfec83fb2b103c8163effcfd622b01ce66be6a6ef5"}},{"ruleId":"R11","level":"warning","message":{"text":"Boundary violation [package:third-party-deep-import]: apps/rule-manager/client/src/ts/components/icons/index.ts:26 imports @elastic/eui/src/components/icon/assets/sort_up, reaching past a declared dependency\u0027s public entry into its build output \u2014 that path is the package\u0027s toolchain layout, not its API, and a minor version bump can relocate it with no semver signal. Import from the package\u0027s documented entry point instead."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"apps/rule-manager/client/src/ts/components/icons/index.ts"},"region":{"startLine":26}}}],"partialFingerprints":{"codehealthFindingId/v1":"41c0ad567c09c2379e96f911e94a50b9c9e177d67c0003f42c1b39edf8e39cf6"}},{"ruleId":"R11","level":"warning","message":{"text":"Boundary violation [package:third-party-deep-import]: apps/rule-manager/client/src/ts/components/icons/index.ts:27 imports @elastic/eui/src/components/icon/assets/trash, reaching past a declared dependency\u0027s public entry into its build output \u2014 that path is the package\u0027s toolchain layout, not its API, and a minor version bump can relocate it with no semver signal. Import from the package\u0027s documented entry point instead."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"apps/rule-manager/client/src/ts/components/icons/index.ts"},"region":{"startLine":27}}}],"partialFingerprints":{"codehealthFindingId/v1":"deba276a47b7645813c4172a0432ed0b97d73e7c4924faa769aae1880af23f6d"}},{"ruleId":"R11","level":"warning","message":{"text":"Boundary violation [package:third-party-deep-import]: apps/rule-manager/client/src/ts/components/icons/index.ts:28 imports @elastic/eui/src/components/icon/assets/grab, reaching past a declared dependency\u0027s public entry into its build output \u2014 that path is the package\u0027s toolchain layout, not its API, and a minor version bump can relocate it with no semver signal. Import from the package\u0027s documented entry point instead."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"apps/rule-manager/client/src/ts/components/icons/index.ts"},"region":{"startLine":28}}}],"partialFingerprints":{"codehealthFindingId/v1":"bf945b5df9b8a22199db4f478c2dbfbada20f47307b4b4e3485497c15a4748c5"}},{"ruleId":"R11","level":"warning","message":{"text":"Boundary violation [package:third-party-deep-import]: apps/rule-manager/client/src/ts/components/icons/index.ts:29 imports @elastic/eui/src/components/icon/assets/keyboard, reaching past a declared dependency\u0027s public entry into its build output \u2014 that path is the package\u0027s toolchain layout, not its API, and a minor version bump can relocate it with no semver signal. Import from the package\u0027s documented entry point instead."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"apps/rule-manager/client/src/ts/components/icons/index.ts"},"region":{"startLine":29}}}],"partialFingerprints":{"codehealthFindingId/v1":"4d45077518f365eb0c5e9c54387af204a2e676401f4851eac438b9bdd706588a"}},{"ruleId":"R11","level":"warning","message":{"text":"Boundary violation [package:third-party-deep-import]: apps/rule-manager/client/src/ts/components/icons/index.ts:30 imports @elastic/eui/src/components/icon/assets/table_density_normal, reaching past a declared dependency\u0027s public entry into its build output \u2014 that path is the package\u0027s toolchain layout, not its API, and a minor version bump can relocate it with no semver signal. Import from the package\u0027s documented entry point instead."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"apps/rule-manager/client/src/ts/components/icons/index.ts"},"region":{"startLine":30}}}],"partialFingerprints":{"codehealthFindingId/v1":"09abd8cc16e2a16b828b3f1cbaf8101dfdd5361023f32eec6881ff523232a265"}},{"ruleId":"R11","level":"warning","message":{"text":"Boundary violation [package:third-party-deep-import]: apps/rule-manager/client/src/ts/components/icons/index.ts:31 imports @elastic/eui/src/components/icon/assets/table_density_expanded, reaching past a declared dependency\u0027s public entry into its build output \u2014 that path is the package\u0027s toolchain layout, not its API, and a minor version bump can relocate it with no semver signal. Import from the package\u0027s documented entry point instead."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"apps/rule-manager/client/src/ts/components/icons/index.ts"},"region":{"startLine":31}}}],"partialFingerprints":{"codehealthFindingId/v1":"0d0793cde59ee6e31ab2a709c05a9cc60d145987d8005f9d3fe3dbc03b068356"}},{"ruleId":"R11","level":"warning","message":{"text":"Boundary violation [package:third-party-deep-import]: apps/rule-manager/client/src/ts/components/icons/index.ts:32 imports @elastic/eui/src/components/icon/assets/table_density_compact, reaching past a declared dependency\u0027s public entry into its build output \u2014 that path is the package\u0027s toolchain layout, not its API, and a minor version bump can relocate it with no semver signal. Import from the package\u0027s documented entry point instead."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"apps/rule-manager/client/src/ts/components/icons/index.ts"},"region":{"startLine":32}}}],"partialFingerprints":{"codehealthFindingId/v1":"05b8acaa70551893dd7a2114f8f12b17b967c832c0e2ce961d7cf8ca6b2ab6b4"}},{"ruleId":"R11","level":"warning","message":{"text":"Boundary violation [package:third-party-deep-import]: apps/rule-manager/client/src/ts/components/icons/index.ts:33 imports @elastic/eui/src/components/icon/assets/list_add, reaching past a declared dependency\u0027s public entry into its build output \u2014 that path is the package\u0027s toolchain layout, not its API, and a minor version bump can relocate it with no semver signal. Import from the package\u0027s documented entry point instead."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"apps/rule-manager/client/src/ts/components/icons/index.ts"},"region":{"startLine":33}}}],"partialFingerprints":{"codehealthFindingId/v1":"3f1c38deb10fb2e42dfca225a80315c67b2b1f5b8a2a0ea72e6560bd6ab602b8"}},{"ruleId":"R11","level":"warning","message":{"text":"Boundary violation [package:third-party-deep-import]: apps/rule-manager/client/src/ts/components/icons/index.ts:34 imports @elastic/eui/src/components/icon/assets/full_screen, reaching past a declared dependency\u0027s public entry into its build output \u2014 that path is the package\u0027s toolchain layout, not its API, and a minor version bump can relocate it with no semver signal. Import from the package\u0027s documented entry point instead."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"apps/rule-manager/client/src/ts/components/icons/index.ts"},"region":{"startLine":34}}}],"partialFingerprints":{"codehealthFindingId/v1":"aca54ac90b81d5972ca06005189636e9d9a526548bc1ecff16822705fab4b61e"}},{"ruleId":"R11","level":"warning","message":{"text":"Boundary violation [package:third-party-deep-import]: apps/rule-manager/client/src/ts/components/icons/index.ts:35 imports @elastic/eui/src/components/icon/assets/sortable, reaching past a declared dependency\u0027s public entry into its build output \u2014 that path is the package\u0027s toolchain layout, not its API, and a minor version bump can relocate it with no semver signal. Import from the package\u0027s documented entry point instead."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"apps/rule-manager/client/src/ts/components/icons/index.ts"},"region":{"startLine":35}}}],"partialFingerprints":{"codehealthFindingId/v1":"e06c38d15a038ebae5cd1be7aa3623b86607dcdd64c067b59ef41e9921170df5"}},{"ruleId":"R11","level":"warning","message":{"text":"Boundary violation [package:third-party-deep-import]: apps/rule-manager/client/src/ts/components/icons/index.ts:36 imports @elastic/eui/src/components/icon/assets/expandMini, reaching past a declared dependency\u0027s public entry into its build output \u2014 that path is the package\u0027s toolchain layout, not its API, and a minor version bump can relocate it with no semver signal. Import from the package\u0027s documented entry point instead."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"apps/rule-manager/client/src/ts/components/icons/index.ts"},"region":{"startLine":36}}}],"partialFingerprints":{"codehealthFindingId/v1":"9aa570c7bebe9655060706cef31efe1b2f581606f5f1479c478abb409ba0accc"}},{"ruleId":"R11","level":"warning","message":{"text":"Boundary violation [package:third-party-deep-import]: apps/rule-manager/client/src/ts/components/icons/index.ts:37 imports @elastic/eui/src/components/icon/assets/sortLeft, reaching past a declared dependency\u0027s public entry into its build output \u2014 that path is the package\u0027s toolchain layout, not its API, and a minor version bump can relocate it with no semver signal. Import from the package\u0027s documented entry point instead."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"apps/rule-manager/client/src/ts/components/icons/index.ts"},"region":{"startLine":37}}}],"partialFingerprints":{"codehealthFindingId/v1":"c4b6160e65e1171abc98ad3b38b0676cf1aca4e7c6997376b6361300a348b6b1"}},{"ruleId":"R11","level":"warning","message":{"text":"Boundary violation [package:third-party-deep-import]: apps/rule-manager/client/src/ts/components/icons/index.ts:38 imports @elastic/eui/src/components/icon/assets/sortRight, reaching past a declared dependency\u0027s public entry into its build output \u2014 that path is the package\u0027s toolchain layout, not its API, and a minor version bump can relocate it with no semver signal. Import from the package\u0027s documented entry point instead."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"apps/rule-manager/client/src/ts/components/icons/index.ts"},"region":{"startLine":38}}}],"partialFingerprints":{"codehealthFindingId/v1":"9a74e179cd80f0e14ac3217bb85209e5dddecff4b65f60413dc3b82d04b6b561"}},{"ruleId":"R11","level":"warning","message":{"text":"Boundary violation [package:third-party-deep-import]: apps/rule-manager/client/src/ts/components/icons/index.ts:39 imports @elastic/eui/src/components/icon/assets/fullScreenExit, reaching past a declared dependency\u0027s public entry into its build output \u2014 that path is the package\u0027s toolchain layout, not its API, and a minor version bump can relocate it with no semver signal. Import from the package\u0027s documented entry point instead."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"apps/rule-manager/client/src/ts/components/icons/index.ts"},"region":{"startLine":39}}}],"partialFingerprints":{"codehealthFindingId/v1":"5eb64aa1e8abf3643b250859ef8a8efce4280ba171ca757e96b57401358c6478"}},{"ruleId":"R11","level":"warning","message":{"text":"Boundary violation [package:third-party-deep-import]: apps/rule-manager/client/src/ts/components/icons/index.ts:40 imports @elastic/eui/src/components/icon/assets/tokenString, reaching past a declared dependency\u0027s public entry into its build output \u2014 that path is the package\u0027s toolchain layout, not its API, and a minor version bump can relocate it with no semver signal. Import from the package\u0027s documented entry point instead."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"apps/rule-manager/client/src/ts/components/icons/index.ts"},"region":{"startLine":40}}}],"partialFingerprints":{"codehealthFindingId/v1":"8fdb43ba93bbdfe790aa03a315c3ff0b53b98b1e181459bc93ed51e467d6f910"}},{"ruleId":"R11","level":"warning","message":{"text":"Boundary violation [package:third-party-deep-import]: apps/rule-manager/client/src/ts/components/icons/index.ts:41 imports @elastic/eui/src/components/icon/assets/beaker, reaching past a declared dependency\u0027s public entry into its build output \u2014 that path is the package\u0027s toolchain layout, not its API, and a minor version bump can relocate it with no semver signal. Import from the package\u0027s documented entry point instead."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"apps/rule-manager/client/src/ts/components/icons/index.ts"},"region":{"startLine":41}}}],"partialFingerprints":{"codehealthFindingId/v1":"f9e512e90904afdb14be0a9cce2ab793739fae17567526aea75263f1ddc419ad"}},{"ruleId":"R11","level":"warning","message":{"text":"Boundary violation [package:third-party-deep-import]: apps/rule-manager/client/src/ts/components/pages/Rules.tsx:17 imports @elastic/eui/src/components/form/field_search, reaching past a declared dependency\u0027s public entry into its build output \u2014 that path is the package\u0027s toolchain layout, not its API, and a minor version bump can relocate it with no semver signal. Import from the package\u0027s documented entry point instead."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"apps/rule-manager/client/src/ts/components/pages/Rules.tsx"},"region":{"startLine":17}}}],"partialFingerprints":{"codehealthFindingId/v1":"9709747f6dd752ca2a98e39255f0f6eee3cf9ac1eea4a95ae3f2c6b9b794818b"}},{"ruleId":"R11","level":"warning","message":{"text":"Boundary violation [package:third-party-deep-import]: apps/rule-manager/client/src/ts/components/table/PaginatedRulesTable.tsx:27 imports @elastic/eui/src/components/datagrid/data_grid_types, reaching past a declared dependency\u0027s public entry into its build output \u2014 that path is the package\u0027s toolchain layout, not its API, and a minor version bump can relocate it with no semver signal. Import from the package\u0027s documented entry point instead."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"apps/rule-manager/client/src/ts/components/table/PaginatedRulesTable.tsx"},"region":{"startLine":27}}}],"partialFingerprints":{"codehealthFindingId/v1":"0e64e92c63792fa2c2d780e704dd0cbf2f8bdf454f5f8afa71d36bf1da924081"}},{"ruleId":"R11","level":"warning","message":{"text":"Boundary violation [package:third-party-deep-import]: apps/rule-manager/client/src/ts/components/table/PaginatedRulesTable.tsx:28 imports @elastic/eui/src/global_styling/mixins/_typography, reaching past a declared dependency\u0027s public entry into its build output \u2014 that path is the package\u0027s toolchain layout, not its API, and a minor version bump can relocate it with no semver signal. Import from the package\u0027s documented entry point instead."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"apps/rule-manager/client/src/ts/components/table/PaginatedRulesTable.tsx"},"region":{"startLine":28}}}],"partialFingerprints":{"codehealthFindingId/v1":"0362e1aec5b2556718d84e1f14a0551af87beef63f3691d59340e2cc75a496b3"}},{"ruleId":"R11","level":"warning","message":{"text":"Boundary violation [package:third-party-deep-import]: apps/rule-manager/client/src/ts/utils/rule.ts:2 imports @elastic/eui/src/components/icon, reaching past a declared dependency\u0027s public entry into its build output \u2014 that path is the package\u0027s toolchain layout, not its API, and a minor version bump can relocate it with no semver signal. Import from the package\u0027s documented entry point instead."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"apps/rule-manager/client/src/ts/utils/rule.ts"},"region":{"startLine":2}}}],"partialFingerprints":{"codehealthFindingId/v1":"a954f1c255c5d693a267d003321783679ce224b2606dd56b525d4fe6c46b1c2b"}},{"ruleId":"R11","level":"warning","message":{"text":"Boundary violation [package:third-party-deep-import]: cdk/lib/index.ts:9 imports @guardian/cdk/lib/constructs/dns/dns-records, reaching past a declared dependency\u0027s public entry into its build output \u2014 that path is the package\u0027s toolchain layout, not its API, and a minor version bump can relocate it with no semver signal. Import from the package\u0027s documented entry point instead."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"cdk/lib/index.ts"},"region":{"startLine":9}}}],"partialFingerprints":{"codehealthFindingId/v1":"68e032e1a58d76b63f5eda7bcfc10efdb483de67be9b814d65bc4366355dcd6e"}},{"ruleId":"R11","level":"warning","message":{"text":"Boundary violation [package:third-party-deep-import]: cdk/lib/index.ts:13 imports @guardian/cdk/lib/constructs/core/stack, reaching past a declared dependency\u0027s public entry into its build output \u2014 that path is the package\u0027s toolchain layout, not its API, and a minor version bump can relocate it with no semver signal. Import from the package\u0027s documented entry point instead."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"cdk/lib/index.ts"},"region":{"startLine":13}}}],"partialFingerprints":{"codehealthFindingId/v1":"54b8c24709b25619f8e60309028c0a6af64961852757273e93df0621bc1d4d3a"}},{"ruleId":"R11","level":"warning","message":{"text":"Boundary violation [package:third-party-deep-import]: cdk/lib/index.ts:15 imports @guardian/cdk/lib/constructs/iam, reaching past a declared dependency\u0027s public entry into its build output \u2014 that path is the package\u0027s toolchain layout, not its API, and a minor version bump can relocate it with no semver signal. Import from the package\u0027s documented entry point instead."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"cdk/lib/index.ts"},"region":{"startLine":15}}}],"partialFingerprints":{"codehealthFindingId/v1":"274b8fa43b4968c24803d3aebf1c60e8301b92744050b4b961f718f79b5c068a"}},{"ruleId":"R11","level":"warning","message":{"text":"Boundary violation [package:third-party-deep-import]: cdk/lib/index.ts:19 imports @guardian/cdk/lib/constructs/ec2, reaching past a declared dependency\u0027s public entry into its build output \u2014 that path is the package\u0027s toolchain layout, not its API, and a minor version bump can relocate it with no semver signal. Import from the package\u0027s documented entry point instead."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"cdk/lib/index.ts"},"region":{"startLine":19}}}],"partialFingerprints":{"codehealthFindingId/v1":"f948683cbb537eeb0ec638066f4eab98646d9fcdaac9f04c742cc03dbdf3eacc"}},{"ruleId":"R11","level":"warning","message":{"text":"Boundary violation [package:third-party-deep-import]: cdk/lib/index.ts:21 imports @guardian/cdk/lib/constructs/s3, reaching past a declared dependency\u0027s public entry into its build output \u2014 that path is the package\u0027s toolchain layout, not its API, and a minor version bump can relocate it with no semver signal. Import from the package\u0027s documented entry point instead."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"cdk/lib/index.ts"},"region":{"startLine":21}}}],"partialFingerprints":{"codehealthFindingId/v1":"36b6b199dbe2bf9639f850a89046f95d40f7a9461f396420b999f1b572b68e61"}},{"ruleId":"R11","level":"warning","message":{"text":"Boundary violation [package:third-party-deep-import]: cdk/lib/index.ts:36 imports @guardian/cdk/lib/constructs/rds, reaching past a declared dependency\u0027s public entry into its build output \u2014 that path is the package\u0027s toolchain layout, not its API, and a minor version bump can relocate it with no semver signal. Import from the package\u0027s documented entry point instead."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"cdk/lib/index.ts"},"region":{"startLine":36}}}],"partialFingerprints":{"codehealthFindingId/v1":"08ac6135845fbb56c0caefd93b64dff3ce2891ea28868d20794837265184d9b1"}},{"ruleId":"R11","level":"warning","message":{"text":"Boundary violation [package:third-party-deep-import]: cdk/lib/index.ts:44 imports @guardian/cdk/lib/constructs/core, reaching past a declared dependency\u0027s public entry into its build output \u2014 that path is the package\u0027s toolchain layout, not its API, and a minor version bump can relocate it with no semver signal. Import from the package\u0027s documented entry point instead."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"cdk/lib/index.ts"},"region":{"startLine":44}}}],"partialFingerprints":{"codehealthFindingId/v1":"0c960ee8c849fad49f88e64f9720fdc2d73524b9341c573061a42eb3d756dfac"}},{"ruleId":"R11","level":"warning","message":{"text":"Boundary violation [package:third-party-deep-import]: cdk/lib/index.ts:45 imports @guardian/cdk/lib/constants/access, reaching past a declared dependency\u0027s public entry into its build output \u2014 that path is the package\u0027s toolchain layout, not its API, and a minor version bump can relocate it with no semver signal. Import from the package\u0027s documented entry point instead."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"cdk/lib/index.ts"},"region":{"startLine":45}}}],"partialFingerprints":{"codehealthFindingId/v1":"973250f91e7ba6a1a649e0de3c3f54ecb6aa10d6fd4dd111055e388f7638367c"}},{"ruleId":"R2","level":"warning","message":{"text":"Complex function RuleForm (cyclomatic 17, cognitive 15): RuleForm has cyclomatic complexity 17 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":"apps/rule-manager/client/src/ts/components/RuleForm.tsx"},"region":{"startLine":73}}}],"partialFingerprints":{"codehealthFindingId/v1":"19260283ab75f48bd01887fb9a9e45efd1ae0fa602f67151d17101b9fad2a7d4"}},{"ruleId":"R2","level":"warning","message":{"text":"Complex function RuleContent (cyclomatic 16, cognitive 15): RuleContent 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":"apps/rule-manager/client/src/ts/components/RuleContent.tsx"},"region":{"startLine":50}}}],"partialFingerprints":{"codehealthFindingId/v1":"a49df3548733da9b109ad1e6e69e0474dbedfb3d23c8b483061161de66b0e4df"}},{"ruleId":"R3","level":"warning","message":{"text":"apps/rule-manager/client/src/ts/components/TagsTable.tsx: 410 lines of code: apps/rule-manager/client/src/ts/components/TagsTable.tsx has 410 significant lines (blank lines excluded), over the 400-line bar, and contains logic \u2014 a file this long is usually several responsibilities in one module."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"apps/rule-manager/client/src/ts/components/TagsTable.tsx"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"c90dca8401dfc9ee5b5cef6270528ee961be029b967d7f8062c4d52d6777d0df"}},{"ruleId":"R3","level":"warning","message":{"text":"apps/rule-manager/client/src/ts/components/table/PaginatedRulesTable.tsx: 409 lines of code: apps/rule-manager/client/src/ts/components/table/PaginatedRulesTable.tsx has 409 significant lines (blank lines excluded), over the 400-line bar, and contains logic \u2014 a file this long is usually several responsibilities in one module."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"apps/rule-manager/client/src/ts/components/table/PaginatedRulesTable.tsx"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"5b6d40ffa32c624a15cdb4199df43a42e0ce5300dd8c8eaac3d2be4cb8212db8"}},{"ruleId":"R4","level":"warning","message":{"text":"No test rig can mount a component in this workspace: apps/rule-manager/client/jest.config.cjs declares environment \u0022node\u0022, and no package here declares a DOM implementation (jsdom / happy-dom), a component testing library or a browser runner \u2014 so none of the 20 unreached component module(s) can be tested as written, however the suite is authored: apps/rule-manager/client/src/ts/components/table/PaginatedRulesTable.tsx, apps/rule-manager/client/src/ts/components/TagsTable.tsx, apps/rule-manager/client/src/ts/components/pages/Rules.tsx, apps/rule-manager/client/src/ts/components/pages/TestRule.tsx, apps/rule-manager/client/src/ts/components/layout/Page.tsx, apps/rule-manager/client/src/ts/components/RuleFormBatchEdit.tsx and 14 more. Add a DOM environment and a component testing library (for example jsdom \u002B @testing-library, or the runner\u0027s browser mode), then test the components. Reported once because these files share one cause, not one omission each."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"apps/rule-manager/client/jest.config.cjs"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"9075ee2bb19396a5fc951d804891856dd8de977f837d3d6e8688ac98f24f8b02"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"apps/rule-manager/client/src/ts/utils/TyperighterChunkedAdapter.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"3a24b27bc106d1eb61b34bc24e25f3e2b92f0e70ecbb35a33a951249c069c3cc"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"apps/rule-manager/client/src/ts/components/hooks/useRules.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"7a4aaf5f8d005f916f8012ce01dc685ad9139ffc34d0f93f80147a52c8720464"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"script/js/compare-rule-xml.js"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"7b5d48f87a368f091392c6ff19fcf38752c72d7917477b1e01976a5c3d491db6"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"script/js/dump-db.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"8a134b804e484e213fa01a8766d94d1af39a8c41396cfc2cdbc0f4c0a53bee88"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"apps/rule-manager/client/src/ts/components/hooks/useBatchRules.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"7fbf6f8d0b7305e0bb0f4d2649d15953010166c2355a517a24b35d460544baa4"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"apps/rule-manager/client/src/ts/components/icons/index.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"6e10b7d146430cf01f466f7e5613815907381e18e6846f6154d50b3307bcdfb9"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"apps/rule-manager/client/src/ts/utils/jsonSeq.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"f0f7ddd99a07493646a97634dfabd58ea83a24d4de0a5cbc97fc421e9c0e5c73"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"cdk/bin/index.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"562051e918d7f44b93894cb376d18954089237f561e6a49aecbaf100b6f5147c"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"apps/rule-manager/client/src/ts/components/helpers/hasCreateEditPermissions.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"60440c898cb07503bfe230a4d905af1dba8952db18ce02d576d9e1636b5df45b"}},{"ruleId":"R4","level":"warning","message":{"text":"No test reaches this file: No test imports this module directly or transitively. Import reachability cannot see a test that executes a file by path instead of importing it, nor one that drives it through a running browser by navigating to a URL \u2014 if neither does, no test reaches this one."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"cdk/jest.setup.js"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"cf099d96150f829467da1ca79f242bd935682b3455f61f675f95feb9f238907b"}},{"ruleId":"R7","level":"warning","message":{"text":"Dead file (~117 LoC): no import path from any entry point (2 application, 4 tooling, 3 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":"script/js/dump-db.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"102de35bcb6f79fdcf3b238a765856ae80e94197319d41b5ffc50251f5c7a4d4"}},{"ruleId":"R7","level":"note","message":{"text":"Unused export \u0027existingTags\u0027: Nothing imports this binding \u2014 it is safe to review for removal."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"apps/rule-manager/client/src/ts/constants/constants.ts"},"region":{"startLine":8}}}],"partialFingerprints":{"codehealthFindingId/v1":"bed479b8efa6e6b20f83c3778b06762f9236d526429d93b5da665f4e5a5fe9d6"}},{"ruleId":"R7","level":"note","message":{"text":"Unused export \u0027OkIStringResponse\u0027: Nothing imports this binding \u2014 it is safe to review for removal."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"apps/rule-manager/client/src/ts/utils/api.ts"},"region":{"startLine":8}}}],"partialFingerprints":{"codehealthFindingId/v1":"bb6632fb4ef33f0994621e70e41cbe243c33b9961fc886892fb491be76812200"}},{"ruleId":"R8","level":"warning","message":{"text":"Unused dependency \u0027utility-types\u0027: Declared in apps/rule-manager/client/package.json but never imported anywhere in that package or its workspace members \u2014 no static import reaches it. Usually that is dead weight and attack surface, but two shapes are indistinguishable from source and are NOT dead: an optional or native peer that another dependency loads dynamically at runtime, and a package a build, docs or test step installs and invokes separately. Confirm which of the three this is before removing it."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"e07122ad63ac1127f04a5f7c4b0145150204efe5d4e629409d9adaa26bef9583"}},{"ruleId":"R8","level":"warning","message":{"text":"Unused dependency \u0027constructs\u0027: Declared in cdk/package.json but never imported anywhere in that package or its workspace members \u2014 no static import reaches it. Usually that is dead weight and attack surface, but two shapes are indistinguishable from source and are NOT dead: an optional or native peer that another dependency loads dynamically at runtime, and a package a build, docs or test step installs and invokes separately. Confirm which of the three this is before removing it."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"45acc17b7c777f7485191a0bd0c295ffc73ff2f65304acaa909457d8e81508fa"}},{"ruleId":"R9","level":"error","message":{"text":"Import cycle (2 files): apps/rule-manager/client/src/ts/components/layout/Breadcrumbs.tsx \u2192 apps/rule-manager/client/src/ts/components/layout/Page.tsx \u2192 apps/rule-manager/client/src/ts/components/layout/Breadcrumbs.tsx"},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"apps/rule-manager/client/src/ts/components/layout/Breadcrumbs.tsx"},"region":{"startLine":3}}}],"partialFingerprints":{"codehealthFindingId/v1":"7fa9f774454b65049c61e4c62636bc964c0213d98e9e512472ba9236d50c4a3c"}},{"ruleId":"S1","level":"warning","message":{"text":"Third-party script without Subresource Integrity: \u0060http://localhost:5173/@vite/client\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. The URL also names no version, so it resolves to whatever that origin serves at fetch time \u2014 the executed bytes can change with nobody touching this repository. 2 such include(s) across the repository\u0027s markup."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"apps/rule-manager/app/views/index.scala.html"},"region":{"startLine":26}}}],"partialFingerprints":{"codehealthFindingId/v1":"3c16b33c4dd1d883bdd6792f75b2eb99efda6de71c861540f687915cea0b1ac7"}},{"ruleId":"X2","level":"note","message":{"text":"Not all async functions that make a request accept an AbortSignal: Only 2/19 async functions that make a cancellable request (fetch, axios, ky, ofetch) accept an AbortSignal or pass one on, so a request keeps running after whatever wanted it has given up \u2014 a page navigated away from, an unmounted component, a timed-out job. Take a \u0060signal\u0060 (or an options object that carries one) and hand it to the request; where nothing could ever cancel the call, omitting it is a deliberate choice \u2014 judge against how the function is used."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"bd89d014f84408f7063269aa5892ba3df7c9af3e981ecfb0752c5731bc62d406"}},{"ruleId":"X2","level":"warning","message":{"text":"Async function without AbortSignal: fetchTags: \u0060fetchTags\u0060 awaits \u0060fetch(\u2026)\u0060 but neither accepts an AbortSignal nor passes one on, so its caller cannot stop the request once it has started. Accept \u0060{ signal }\u0060 and pass it through: \u0060fetch(url, { signal })\u0060."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"apps/rule-manager/client/src/ts/components/context/tags.tsx"},"region":{"startLine":47}}}],"partialFingerprints":{"codehealthFindingId/v1":"f94ed40108085e12b7714be7246ee6a68f72738445c415538e47c19f859812b9"}},{"ruleId":"X2","level":"warning","message":{"text":"Async function without AbortSignal: updateTag: \u0060updateTag\u0060 awaits \u0060fetch(\u2026)\u0060 but neither accepts an AbortSignal nor passes one on, so its caller cannot stop the request once it has started. Accept \u0060{ signal }\u0060 and pass it through: \u0060fetch(url, { signal })\u0060."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"apps/rule-manager/client/src/ts/components/context/tags.tsx"},"region":{"startLine":69}}}],"partialFingerprints":{"codehealthFindingId/v1":"2aa1d8b87eb20a7627cdfde7d862b3ae760f04be79324ffba4928e6ec547a144"}},{"ruleId":"X2","level":"warning","message":{"text":"Async function without AbortSignal: createTag: \u0060createTag\u0060 awaits \u0060fetch(\u2026)\u0060 but neither accepts an AbortSignal nor passes one on, so its caller cannot stop the request once it has started. Accept \u0060{ signal }\u0060 and pass it through: \u0060fetch(url, { signal })\u0060."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"apps/rule-manager/client/src/ts/components/context/tags.tsx"},"region":{"startLine":105}}}],"partialFingerprints":{"codehealthFindingId/v1":"6c514ebf6ad8dcb0c01e7895adb057d9130e2f7caf7d2b9bfc9aecdc63286b85"}},{"ruleId":"X2","level":"warning","message":{"text":"Async function without AbortSignal: deleteTag: \u0060deleteTag\u0060 awaits \u0060fetch(\u2026)\u0060 but neither accepts an AbortSignal nor passes one on, so its caller cannot stop the request once it has started. Accept \u0060{ signal }\u0060 and pass it through: \u0060fetch(url, { signal })\u0060."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"apps/rule-manager/client/src/ts/components/context/tags.tsx"},"region":{"startLine":130}}}],"partialFingerprints":{"codehealthFindingId/v1":"af690ff99325f549009b8071e198d9518ac78477cc52f48fb528a0055e1288dc"}},{"ruleId":"X2","level":"warning","message":{"text":"Async function without AbortSignal: refreshRules: \u0060refreshRules\u0060 awaits \u0060fetch(\u2026)\u0060 but neither accepts an AbortSignal nor passes one on, so its caller cannot stop the request once it has started. Accept \u0060{ signal }\u0060 and pass it through: \u0060fetch(url, { signal })\u0060."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"apps/rule-manager/client/src/ts/components/hooks/useRules.ts"},"region":{"startLine":92}}}],"partialFingerprints":{"codehealthFindingId/v1":"64ca573693e0ab1953bad5ba8228ac65dee7742d351b8539583ef329a2d0128a"}},{"ruleId":"X2","level":"warning","message":{"text":"Async function without AbortSignal: refreshDictionaryRules: \u0060refreshDictionaryRules\u0060 awaits \u0060fetch(\u2026)\u0060 but neither accepts an AbortSignal nor passes one on, so its caller cannot stop the request once it has started. Accept \u0060{ signal }\u0060 and pass it through: \u0060fetch(url, { signal })\u0060."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"apps/rule-manager/client/src/ts/components/hooks/useRules.ts"},"region":{"startLine":118}}}],"partialFingerprints":{"codehealthFindingId/v1":"d3f1107e9771f32df25aec1abf982513b1dd41f57eeb2e4a9a0f1bceadfeb3ef"}},{"ruleId":"X2","level":"warning","message":{"text":"Async function without AbortSignal: fetchRule: \u0060fetchRule\u0060 awaits \u0060fetch(\u2026)\u0060 but neither accepts an AbortSignal nor passes one on, so its caller cannot stop the request once it has started. Accept \u0060{ signal }\u0060 and pass it through: \u0060fetch(url, { signal })\u0060."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"apps/rule-manager/client/src/ts/components/hooks/useRule.ts"},"region":{"startLine":62}}}],"partialFingerprints":{"codehealthFindingId/v1":"c19a49573ff7190f345e6106ceb11275b1aacc9b3811e329f735ea6fac455a2d"}},{"ruleId":"X2","level":"warning","message":{"text":"Async function without AbortSignal: publishRule: \u0060publishRule\u0060 awaits \u0060fetch(\u2026)\u0060 but neither accepts an AbortSignal nor passes one on, so its caller cannot stop the request once it has started. Accept \u0060{ signal }\u0060 and pass it through: \u0060fetch(url, { signal })\u0060."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"apps/rule-manager/client/src/ts/components/hooks/useRule.ts"},"region":{"startLine":82}}}],"partialFingerprints":{"codehealthFindingId/v1":"242929de3c483784a00eefd13a89bd1a678b884c0c8a9c268542269f28c13e50"}},{"ruleId":"X2","level":"warning","message":{"text":"Async function without AbortSignal: archiveRule: \u0060archiveRule\u0060 awaits \u0060fetch(\u2026)\u0060 but neither accepts an AbortSignal nor passes one on, so its caller cannot stop the request once it has started. Accept \u0060{ signal }\u0060 and pass it through: \u0060fetch(url, { signal })\u0060."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"apps/rule-manager/client/src/ts/components/hooks/useRule.ts"},"region":{"startLine":109}}}],"partialFingerprints":{"codehealthFindingId/v1":"862b6fe0068293c47e1ea7414988c290ec555aa863a38e8609068c403db2db0d"}},{"ruleId":"X2","level":"warning","message":{"text":"Async function without AbortSignal: unarchiveRule: \u0060unarchiveRule\u0060 awaits \u0060fetch(\u2026)\u0060 but neither accepts an AbortSignal nor passes one on, so its caller cannot stop the request once it has started. Accept \u0060{ signal }\u0060 and pass it through: \u0060fetch(url, { signal })\u0060."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"apps/rule-manager/client/src/ts/components/hooks/useRule.ts"},"region":{"startLine":135}}}],"partialFingerprints":{"codehealthFindingId/v1":"c846f2dd5ffcf8cbc70f7003bff9aa7c3e05034f6b16a13ce81c4acabc70c44e"}},{"ruleId":"X2","level":"warning","message":{"text":"Async function without AbortSignal: unpublishRule: \u0060unpublishRule\u0060 awaits \u0060fetch(\u2026)\u0060 but neither accepts an AbortSignal nor passes one on, so its caller cannot stop the request once it has started. Accept \u0060{ signal }\u0060 and pass it through: \u0060fetch(url, { signal })\u0060."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"apps/rule-manager/client/src/ts/components/hooks/useRule.ts"},"region":{"startLine":161}}}],"partialFingerprints":{"codehealthFindingId/v1":"b8731c59bb42b8e617c09905412e8e0cf3ea16e789e370f22e52c2dc62d15443"}},{"ruleId":"X2","level":"warning","message":{"text":"Async function without AbortSignal: validateRule: \u0060validateRule\u0060 awaits \u0060fetch(\u2026)\u0060 but neither accepts an AbortSignal nor passes one on, so its caller cannot stop the request once it has started. Accept \u0060{ signal }\u0060 and pass it through: \u0060fetch(url, { signal })\u0060."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"apps/rule-manager/client/src/ts/components/hooks/useRule.ts"},"region":{"startLine":187}}}],"partialFingerprints":{"codehealthFindingId/v1":"cfb756c380f03bb7abbb9b170165d462eccd394da3584906663c68a56aae5421"}},{"ruleId":"X2","level":"warning","message":{"text":"Async function without AbortSignal: updateRule: \u0060updateRule\u0060 awaits \u0060fetch(\u2026)\u0060 but neither accepts an AbortSignal nor passes one on, so its caller cannot stop the request once it has started. Accept \u0060{ signal }\u0060 and pass it through: \u0060fetch(url, { signal })\u0060."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"apps/rule-manager/client/src/ts/components/hooks/useRule.ts"},"region":{"startLine":224}}}],"partialFingerprints":{"codehealthFindingId/v1":"76159ea20722ca9bb0a3703f84a7dd94b03f91f0dff726f6bce3928029359c00"}},{"ruleId":"X2","level":"warning","message":{"text":"Async function without AbortSignal: createRule: \u0060createRule\u0060 awaits \u0060fetch(\u2026)\u0060 but neither accepts an AbortSignal nor passes one on, so its caller cannot stop the request once it has started. Accept \u0060{ signal }\u0060 and pass it through: \u0060fetch(url, { signal })\u0060."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"apps/rule-manager/client/src/ts/components/hooks/useRule.ts"},"region":{"startLine":262}}}],"partialFingerprints":{"codehealthFindingId/v1":"236d72fdd1e0df33e90e1429827837f3079ef79209a6a08d3339975f295279b6"}},{"ruleId":"X2","level":"warning","message":{"text":"Async function without AbortSignal: discardRuleChanges: \u0060discardRuleChanges\u0060 awaits \u0060fetch(\u2026)\u0060 but neither accepts an AbortSignal nor passes one on, so its caller cannot stop the request once it has started. Accept \u0060{ signal }\u0060 and pass it through: \u0060fetch(url, { signal })\u0060."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"apps/rule-manager/client/src/ts/components/hooks/useRule.ts"},"region":{"startLine":292}}}],"partialFingerprints":{"codehealthFindingId/v1":"580b6ea01da9fdd9a9ba362828c6633ba366472e10e0cc429ef187417b2ae0e6"}},{"ruleId":"X2","level":"warning","message":{"text":"Async function without AbortSignal: fetchRules: \u0060fetchRules\u0060 awaits \u0060fetch(\u2026)\u0060 but neither accepts an AbortSignal nor passes one on, so its caller cannot stop the request once it has started. Accept \u0060{ signal }\u0060 and pass it through: \u0060fetch(url, { signal })\u0060."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"apps/rule-manager/client/src/ts/components/hooks/useBatchRules.ts"},"region":{"startLine":11}}}],"partialFingerprints":{"codehealthFindingId/v1":"23d291f52767a62bd4f083cc2d4e6aef0fb210225ad2b24f7240b1cc386ca6e1"}},{"ruleId":"X2","level":"warning","message":{"text":"Async function without AbortSignal: updateRules: \u0060updateRules\u0060 awaits \u0060fetch(\u2026)\u0060 but neither accepts an AbortSignal nor passes one on, so its caller cannot stop the request once it has started. Accept \u0060{ signal }\u0060 and pass it through: \u0060fetch(url, { signal })\u0060."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"apps/rule-manager/client/src/ts/components/hooks/useBatchRules.ts"},"region":{"startLine":32}}}],"partialFingerprints":{"codehealthFindingId/v1":"3401283d479a3f6ffa1e16d468cd7cf25b50f4350ac7784d62e535e3f0e1c491"}},{"ruleId":"X4","level":"note","message":{"text":"Interpolated log message defeats structured logging: \u0060info\u0060 at line 46 is handed an interpolated string as its message through SLF4J, so the logger receives one finished string \u2014 the values in it cannot be queried, filtered or aggregated as fields, every occurrence reads as a different message, and the string is built even when the level is filtered out. Pass a constant pattern and the values beside it instead: \u0060log.info(\u0022Order {} moved to {}\u0022, orderId, status)\u0060, which keeps the pattern and its arguments apart on the event for a structured encoder (logstash-logback-encoder, OpenTelemetry), or \u0060log.atInfo().addKeyValue(\u0022order_id\u0022, orderId).log(\u0022order moved\u0022)\u0060 with SLF4J 2\u0027s fluent API. scala-logging\u0027s \u0060LazyLogging\u0060 logger takes an \u0060s\u0022\u2026\u0022\u0060 message apart into that pattern at compile time, so switching to it is also a fix."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"apps/checker/app/utils/CloudWatchClient.scala"},"region":{"startLine":46}}}],"partialFingerprints":{"codehealthFindingId/v1":"39da47b145e0a96b046a02ab9e354a95b36869218ccb05cb3895e8b59af7c38c"}},{"ruleId":"X4","level":"note","message":{"text":"Interpolated log message defeats structured logging: \u0060error\u0060 at line 51 is handed an interpolated string as its message through SLF4J, so the logger receives one finished string \u2014 the values in it cannot be queried, filtered or aggregated as fields, every occurrence reads as a different message, and the string is built even when the level is filtered out. Pass a constant pattern and the values beside it instead: \u0060log.error(\u0022Order {} moved to {}\u0022, orderId, status)\u0060, which keeps the pattern and its arguments apart on the event for a structured encoder (logstash-logback-encoder, OpenTelemetry), or \u0060log.atInfo().addKeyValue(\u0022order_id\u0022, orderId).log(\u0022order moved\u0022)\u0060 with SLF4J 2\u0027s fluent API. scala-logging\u0027s \u0060LazyLogging\u0060 logger takes an \u0060s\u0022\u2026\u0022\u0060 message apart into that pattern at compile time, so switching to it is also a fix."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"apps/checker/app/utils/CloudWatchClient.scala"},"region":{"startLine":51}}}],"partialFingerprints":{"codehealthFindingId/v1":"b7d17364288354f3a965aabb67cd1a32cff56fd80288b594540881d7bb6180a9"}},{"ruleId":"X4","level":"note","message":{"text":"Interpolated log message defeats structured logging: \u0060info\u0060 at line 29 is handed an interpolated string as its message through SLF4J, so the logger receives one finished string \u2014 the values in it cannot be queried, filtered or aggregated as fields, every occurrence reads as a different message, and the string is built even when the level is filtered out. Pass a constant pattern and the values beside it instead: \u0060log.info(\u0022Order {} moved to {}\u0022, orderId, status)\u0060, which keeps the pattern and its arguments apart on the event for a structured encoder (logstash-logback-encoder, OpenTelemetry), or \u0060log.atInfo().addKeyValue(\u0022order_id\u0022, orderId).log(\u0022order moved\u0022)\u0060 with SLF4J 2\u0027s fluent API. scala-logging\u0027s \u0060LazyLogging\u0060 logger takes an \u0060s\u0022\u2026\u0022\u0060 message apart into that pattern at compile time, so switching to it is also a fix."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"apps/common-lib/src/main/scala/com/gu/typerighter/controllers/PandaAuthController.scala"},"region":{"startLine":29}}}],"partialFingerprints":{"codehealthFindingId/v1":"5d71b39507b780d642641663512046f373cf59fbedcdd6a08d4c18603d029c0f"}},{"ruleId":"X4","level":"note","message":{"text":"Interpolated log message defeats structured logging: \u0060warn\u0060 at line 85 is handed an interpolated string as its message through SLF4J, so the logger receives one finished string \u2014 the values in it cannot be queried, filtered or aggregated as fields, every occurrence reads as a different message, and the string is built even when the level is filtered out. Pass a constant pattern and the values beside it instead: \u0060log.warn(\u0022Order {} moved to {}\u0022, orderId, status)\u0060, which keeps the pattern and its arguments apart on the event for a structured encoder (logstash-logback-encoder, OpenTelemetry), or \u0060log.atInfo().addKeyValue(\u0022order_id\u0022, orderId).log(\u0022order moved\u0022)\u0060 with SLF4J 2\u0027s fluent API. scala-logging\u0027s \u0060LazyLogging\u0060 logger takes an \u0060s\u0022\u2026\u0022\u0060 message apart into that pattern at compile time, so switching to it is also a fix."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"apps/common-lib/src/main/scala/com/gu/typerighter/lib/CommonConfig.scala"},"region":{"startLine":85}}}],"partialFingerprints":{"codehealthFindingId/v1":"d1bdc1a1aecba2dca9555e51b6b478dd1d4f403dc9852495ac4ac16365213f8e"}},{"ruleId":"X4","level":"note","message":{"text":"Interpolated log message defeats structured logging: \u0060info\u0060 at line 64 is handed an interpolated string as its message through SLF4J, so the logger receives one finished string \u2014 the values in it cannot be queried, filtered or aggregated as fields, every occurrence reads as a different message, and the string is built even when the level is filtered out. Pass a constant pattern and the values beside it instead: \u0060log.info(\u0022Order {} moved to {}\u0022, orderId, status)\u0060, which keeps the pattern and its arguments apart on the event for a structured encoder (logstash-logback-encoder, OpenTelemetry), or \u0060log.atInfo().addKeyValue(\u0022order_id\u0022, orderId).log(\u0022order moved\u0022)\u0060 with SLF4J 2\u0027s fluent API. scala-logging\u0027s \u0060LazyLogging\u0060 logger takes an \u0060s\u0022\u2026\u0022\u0060 message apart into that pattern at compile time, so switching to it is also a fix."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"apps/rule-manager/app/service/RuleTesting.scala"},"region":{"startLine":64}}}],"partialFingerprints":{"codehealthFindingId/v1":"c5361c237d9fd245da07b65ddaff6150d73728089d88db7b12166e04067d702d"}},{"ruleId":"X4","level":"note","message":{"text":"Interpolated log message defeats structured logging: \u0060info\u0060 at line 76 is handed an interpolated string as its message through SLF4J, so the logger receives one finished string \u2014 the values in it cannot be queried, filtered or aggregated as fields, every occurrence reads as a different message, and the string is built even when the level is filtered out. Pass a constant pattern and the values beside it instead: \u0060log.info(\u0022Order {} moved to {}\u0022, orderId, status)\u0060, which keeps the pattern and its arguments apart on the event for a structured encoder (logstash-logback-encoder, OpenTelemetry), or \u0060log.atInfo().addKeyValue(\u0022order_id\u0022, orderId).log(\u0022order moved\u0022)\u0060 with SLF4J 2\u0027s fluent API. scala-logging\u0027s \u0060LazyLogging\u0060 logger takes an \u0060s\u0022\u2026\u0022\u0060 message apart into that pattern at compile time, so switching to it is also a fix."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"apps/rule-manager/app/service/RuleTesting.scala"},"region":{"startLine":76}}}],"partialFingerprints":{"codehealthFindingId/v1":"8fd254236bac8c4bdd4fe9ae2e5ed64dd8e2cfa980daf0d544a766afbbb7e337"}},{"ruleId":"X4","level":"note","message":{"text":"Interpolated log message defeats structured logging: \u0060info\u0060 at line 136 is handed an interpolated string as its message through SLF4J, so the logger receives one finished string \u2014 the values in it cannot be queried, filtered or aggregated as fields, every occurrence reads as a different message, and the string is built even when the level is filtered out. Pass a constant pattern and the values beside it instead: \u0060log.info(\u0022Order {} moved to {}\u0022, orderId, status)\u0060, which keeps the pattern and its arguments apart on the event for a structured encoder (logstash-logback-encoder, OpenTelemetry), or \u0060log.atInfo().addKeyValue(\u0022order_id\u0022, orderId).log(\u0022order moved\u0022)\u0060 with SLF4J 2\u0027s fluent API. scala-logging\u0027s \u0060LazyLogging\u0060 logger takes an \u0060s\u0022\u2026\u0022\u0060 message apart into that pattern at compile time, so switching to it is also a fix."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"apps/rule-manager/app/service/RuleTesting.scala"},"region":{"startLine":136}}}],"partialFingerprints":{"codehealthFindingId/v1":"da4fa221144a24868a1cbfe8a69ba609cbb0160e921d0ee62a8de3d57c5f7705"}},{"ruleId":"X4","level":"note","message":{"text":"Interpolated log message defeats structured logging: \u0060info\u0060 at line 156 is handed an interpolated string as its message through SLF4J, so the logger receives one finished string \u2014 the values in it cannot be queried, filtered or aggregated as fields, every occurrence reads as a different message, and the string is built even when the level is filtered out. Pass a constant pattern and the values beside it instead: \u0060log.info(\u0022Order {} moved to {}\u0022, orderId, status)\u0060, which keeps the pattern and its arguments apart on the event for a structured encoder (logstash-logback-encoder, OpenTelemetry), or \u0060log.atInfo().addKeyValue(\u0022order_id\u0022, orderId).log(\u0022order moved\u0022)\u0060 with SLF4J 2\u0027s fluent API. scala-logging\u0027s \u0060LazyLogging\u0060 logger takes an \u0060s\u0022\u2026\u0022\u0060 message apart into that pattern at compile time, so switching to it is also a fix."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"apps/rule-manager/app/service/RuleTesting.scala"},"region":{"startLine":156}}}],"partialFingerprints":{"codehealthFindingId/v1":"b6e5ddc109b8b56760a383cedefafe329eb0ffcb8065e6bc0714a6caf97fd402"}},{"ruleId":"X4","level":"note","message":{"text":"Interpolated log message defeats structured logging: \u0060error\u0060 at line 163 is handed an interpolated string as its message through SLF4J, so the logger receives one finished string \u2014 the values in it cannot be queried, filtered or aggregated as fields, every occurrence reads as a different message, and the string is built even when the level is filtered out. Pass a constant pattern and the values beside it instead: \u0060log.error(\u0022Order {} moved to {}\u0022, orderId, status)\u0060, which keeps the pattern and its arguments apart on the event for a structured encoder (logstash-logback-encoder, OpenTelemetry), or \u0060log.atInfo().addKeyValue(\u0022order_id\u0022, orderId).log(\u0022order moved\u0022)\u0060 with SLF4J 2\u0027s fluent API. scala-logging\u0027s \u0060LazyLogging\u0060 logger takes an \u0060s\u0022\u2026\u0022\u0060 message apart into that pattern at compile time, so switching to it is also a fix."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"apps/rule-manager/app/service/RuleTesting.scala"},"region":{"startLine":163}}}],"partialFingerprints":{"codehealthFindingId/v1":"f74bf971e798b6278e4ded611c1f0b16a90908a457c2e3b3b27ea3db732bdad6"}},{"ruleId":"X4","level":"note","message":{"text":"Interpolated log message defeats structured logging: \u0060error\u0060 at line 72 is handed an interpolated string as its message through SLF4J, so the logger receives one finished string \u2014 the values in it cannot be queried, filtered or aggregated as fields, every occurrence reads as a different message, and the string is built even when the level is filtered out. Pass a constant pattern and the values beside it instead: \u0060log.error(\u0022Order {} moved to {}\u0022, orderId, status)\u0060, which keeps the pattern and its arguments apart on the event for a structured encoder (logstash-logback-encoder, OpenTelemetry), or \u0060log.atInfo().addKeyValue(\u0022order_id\u0022, orderId).log(\u0022order moved\u0022)\u0060 with SLF4J 2\u0027s fluent API. scala-logging\u0027s \u0060LazyLogging\u0060 logger takes an \u0060s\u0022\u2026\u0022\u0060 message apart into that pattern at compile time, so switching to it is also a fix."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"apps/rule-manager/app/service/RuleManager.scala"},"region":{"startLine":72}}}],"partialFingerprints":{"codehealthFindingId/v1":"14518bc7eddbb4273867195379b8c4eb932ede9904265765987c52b2ca8f8405"}},{"ruleId":"X4","level":"note","message":{"text":"Interpolated log message defeats structured logging: \u0060error\u0060 at line 76 is handed an interpolated string as its message through SLF4J, so the logger receives one finished string \u2014 the values in it cannot be queried, filtered or aggregated as fields, every occurrence reads as a different message, and the string is built even when the level is filtered out. Pass a constant pattern and the values beside it instead: \u0060log.error(\u0022Order {} moved to {}\u0022, orderId, status)\u0060, which keeps the pattern and its arguments apart on the event for a structured encoder (logstash-logback-encoder, OpenTelemetry), or \u0060log.atInfo().addKeyValue(\u0022order_id\u0022, orderId).log(\u0022order moved\u0022)\u0060 with SLF4J 2\u0027s fluent API. scala-logging\u0027s \u0060LazyLogging\u0060 logger takes an \u0060s\u0022\u2026\u0022\u0060 message apart into that pattern at compile time, so switching to it is also a fix."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"apps/rule-manager/app/service/RuleManager.scala"},"region":{"startLine":76}}}],"partialFingerprints":{"codehealthFindingId/v1":"ee23d9294fa9e48cc4844e05121f3fcaa869333ab71fcee7fcecf356840fdd84"}},{"ruleId":"X4","level":"note","message":{"text":"Interpolated log message defeats structured logging: \u0060error\u0060 at line 101 is handed an interpolated string as its message through SLF4J, so the logger receives one finished string \u2014 the values in it cannot be queried, filtered or aggregated as fields, every occurrence reads as a different message, and the string is built even when the level is filtered out. Pass a constant pattern and the values beside it instead: \u0060log.error(\u0022Order {} moved to {}\u0022, orderId, status)\u0060, which keeps the pattern and its arguments apart on the event for a structured encoder (logstash-logback-encoder, OpenTelemetry), or \u0060log.atInfo().addKeyValue(\u0022order_id\u0022, orderId).log(\u0022order moved\u0022)\u0060 with SLF4J 2\u0027s fluent API. scala-logging\u0027s \u0060LazyLogging\u0060 logger takes an \u0060s\u0022\u2026\u0022\u0060 message apart into that pattern at compile time, so switching to it is also a fix."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"apps/rule-manager/app/service/RuleManager.scala"},"region":{"startLine":101}}}],"partialFingerprints":{"codehealthFindingId/v1":"7b3006f7080a84fd59e61cef3bf9c4fb13ea71eadc418b1f16f470617fe70fd3"}},{"ruleId":"X4","level":"note","message":{"text":"Interpolated log message defeats structured logging: \u0060error\u0060 at line 105 is handed an interpolated string as its message through SLF4J, so the logger receives one finished string \u2014 the values in it cannot be queried, filtered or aggregated as fields, every occurrence reads as a different message, and the string is built even when the level is filtered out. Pass a constant pattern and the values beside it instead: \u0060log.error(\u0022Order {} moved to {}\u0022, orderId, status)\u0060, which keeps the pattern and its arguments apart on the event for a structured encoder (logstash-logback-encoder, OpenTelemetry), or \u0060log.atInfo().addKeyValue(\u0022order_id\u0022, orderId).log(\u0022order moved\u0022)\u0060 with SLF4J 2\u0027s fluent API. scala-logging\u0027s \u0060LazyLogging\u0060 logger takes an \u0060s\u0022\u2026\u0022\u0060 message apart into that pattern at compile time, so switching to it is also a fix."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"apps/rule-manager/app/service/RuleManager.scala"},"region":{"startLine":105}}}],"partialFingerprints":{"codehealthFindingId/v1":"3f56bed9c39abc21edfdfb4cafafabdbb19a03f8cd0355f07ed0dfb78d009013"}},{"ruleId":"X4","level":"note","message":{"text":"Interpolated log message defeats structured logging: \u0060info\u0060 at line 353 is handed an interpolated string as its message through SLF4J, so the logger receives one finished string \u2014 the values in it cannot be queried, filtered or aggregated as fields, every occurrence reads as a different message, and the string is built even when the level is filtered out. Pass a constant pattern and the values beside it instead: \u0060log.info(\u0022Order {} moved to {}\u0022, orderId, status)\u0060, which keeps the pattern and its arguments apart on the event for a structured encoder (logstash-logback-encoder, OpenTelemetry), or \u0060log.atInfo().addKeyValue(\u0022order_id\u0022, orderId).log(\u0022order moved\u0022)\u0060 with SLF4J 2\u0027s fluent API. scala-logging\u0027s \u0060LazyLogging\u0060 logger takes an \u0060s\u0022\u2026\u0022\u0060 message apart into that pattern at compile time, so switching to it is also a fix."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"apps/rule-manager/app/service/RuleManager.scala"},"region":{"startLine":353}}}],"partialFingerprints":{"codehealthFindingId/v1":"5b8290da9bc8bdeee07ae0b9f2b8afa56ab9685f598ed6cd210cdf996f8e1e1c"}},{"ruleId":"X4","level":"note","message":{"text":"Interpolated log message defeats structured logging: \u0060error\u0060 at line 410 is handed an interpolated string as its message through SLF4J, so the logger receives one finished string \u2014 the values in it cannot be queried, filtered or aggregated as fields, every occurrence reads as a different message, and the string is built even when the level is filtered out. Pass a constant pattern and the values beside it instead: \u0060log.error(\u0022Order {} moved to {}\u0022, orderId, status)\u0060, which keeps the pattern and its arguments apart on the event for a structured encoder (logstash-logback-encoder, OpenTelemetry), or \u0060log.atInfo().addKeyValue(\u0022order_id\u0022, orderId).log(\u0022order moved\u0022)\u0060 with SLF4J 2\u0027s fluent API. scala-logging\u0027s \u0060LazyLogging\u0060 logger takes an \u0060s\u0022\u2026\u0022\u0060 message apart into that pattern at compile time, so switching to it is also a fix."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"apps/rule-manager/app/service/RuleManager.scala"},"region":{"startLine":410}}}],"partialFingerprints":{"codehealthFindingId/v1":"6dcfeff50cc32e33bc6cbd2a9fb62003b9ea52742991837f61625b2e3b5f2b0d"}},{"ruleId":"X4","level":"note","message":{"text":"Interpolated log message defeats structured logging: \u0060error\u0060 at line 411 is handed an interpolated string as its message through SLF4J, so the logger receives one finished string \u2014 the values in it cannot be queried, filtered or aggregated as fields, every occurrence reads as a different message, and the string is built even when the level is filtered out. Pass a constant pattern and the values beside it instead: \u0060log.error(\u0022Order {} moved to {}\u0022, orderId, status)\u0060, which keeps the pattern and its arguments apart on the event for a structured encoder (logstash-logback-encoder, OpenTelemetry), or \u0060log.atInfo().addKeyValue(\u0022order_id\u0022, orderId).log(\u0022order moved\u0022)\u0060 with SLF4J 2\u0027s fluent API. scala-logging\u0027s \u0060LazyLogging\u0060 logger takes an \u0060s\u0022\u2026\u0022\u0060 message apart into that pattern at compile time, so switching to it is also a fix."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"apps/rule-manager/app/service/RuleManager.scala"},"region":{"startLine":411}}}],"partialFingerprints":{"codehealthFindingId/v1":"716c6bef72be317df90a35f4291e0a66bee1cba041d285f32fb586d45594944d"}},{"ruleId":"X4","level":"note","message":{"text":"Interpolated log message defeats structured logging: \u0060info\u0060 at line 559 is handed an interpolated string as its message through SLF4J, so the logger receives one finished string \u2014 the values in it cannot be queried, filtered or aggregated as fields, every occurrence reads as a different message, and the string is built even when the level is filtered out. Pass a constant pattern and the values beside it instead: \u0060log.info(\u0022Order {} moved to {}\u0022, orderId, status)\u0060, which keeps the pattern and its arguments apart on the event for a structured encoder (logstash-logback-encoder, OpenTelemetry), or \u0060log.atInfo().addKeyValue(\u0022order_id\u0022, orderId).log(\u0022order moved\u0022)\u0060 with SLF4J 2\u0027s fluent API. scala-logging\u0027s \u0060LazyLogging\u0060 logger takes an \u0060s\u0022\u2026\u0022\u0060 message apart into that pattern at compile time, so switching to it is also a fix."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"apps/rule-manager/app/service/RuleManager.scala"},"region":{"startLine":559}}}],"partialFingerprints":{"codehealthFindingId/v1":"4d307bcd83578e199470da3e021d400c4a5d28b898e409feaf5101fecc167c3b"}},{"ruleId":"X4","level":"note","message":{"text":"Interpolated log message defeats structured logging: \u0060info\u0060 at line 561 is handed an interpolated string as its message through SLF4J, so the logger receives one finished string \u2014 the values in it cannot be queried, filtered or aggregated as fields, every occurrence reads as a different message, and the string is built even when the level is filtered out. Pass a constant pattern and the values beside it instead: \u0060log.info(\u0022Order {} moved to {}\u0022, orderId, status)\u0060, which keeps the pattern and its arguments apart on the event for a structured encoder (logstash-logback-encoder, OpenTelemetry), or \u0060log.atInfo().addKeyValue(\u0022order_id\u0022, orderId).log(\u0022order moved\u0022)\u0060 with SLF4J 2\u0027s fluent API. scala-logging\u0027s \u0060LazyLogging\u0060 logger takes an \u0060s\u0022\u2026\u0022\u0060 message apart into that pattern at compile time, so switching to it is also a fix."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"apps/rule-manager/app/service/RuleManager.scala"},"region":{"startLine":561}}}],"partialFingerprints":{"codehealthFindingId/v1":"6014ac3472d8a45d5e97176860911b8e579c0136a2b29cf7ee7b7d9123d24366"}},{"ruleId":"X4","level":"note","message":{"text":"Interpolated log message defeats structured logging: \u0060info\u0060 at line 572 is handed an interpolated string as its message through SLF4J, so the logger receives one finished string \u2014 the values in it cannot be queried, filtered or aggregated as fields, every occurrence reads as a different message, and the string is built even when the level is filtered out. Pass a constant pattern and the values beside it instead: \u0060log.info(\u0022Order {} moved to {}\u0022, orderId, status)\u0060, which keeps the pattern and its arguments apart on the event for a structured encoder (logstash-logback-encoder, OpenTelemetry), or \u0060log.atInfo().addKeyValue(\u0022order_id\u0022, orderId).log(\u0022order moved\u0022)\u0060 with SLF4J 2\u0027s fluent API. scala-logging\u0027s \u0060LazyLogging\u0060 logger takes an \u0060s\u0022\u2026\u0022\u0060 message apart into that pattern at compile time, so switching to it is also a fix."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"apps/rule-manager/app/service/RuleManager.scala"},"region":{"startLine":572}}}],"partialFingerprints":{"codehealthFindingId/v1":"380fa08c4185051ae3816d15733d9608a7d024cd963eee8131d5c375a9e2c44f"}},{"ruleId":"X4","level":"note","message":{"text":"Interpolated log message defeats structured logging: \u0060info\u0060 at line 574 is handed an interpolated string as its message through SLF4J, so the logger receives one finished string \u2014 the values in it cannot be queried, filtered or aggregated as fields, every occurrence reads as a different message, and the string is built even when the level is filtered out. Pass a constant pattern and the values beside it instead: \u0060log.info(\u0022Order {} moved to {}\u0022, orderId, status)\u0060, which keeps the pattern and its arguments apart on the event for a structured encoder (logstash-logback-encoder, OpenTelemetry), or \u0060log.atInfo().addKeyValue(\u0022order_id\u0022, orderId).log(\u0022order moved\u0022)\u0060 with SLF4J 2\u0027s fluent API. scala-logging\u0027s \u0060LazyLogging\u0060 logger takes an \u0060s\u0022\u2026\u0022\u0060 message apart into that pattern at compile time, so switching to it is also a fix."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"apps/rule-manager/app/service/RuleManager.scala"},"region":{"startLine":574}}}],"partialFingerprints":{"codehealthFindingId/v1":"618bdef4df0caad85eebc19279edfcb4727c34624002405efbaf5f3744b626ce"}},{"ruleId":"X5","level":"note","message":{"text":"Scala\u0027s null is not held to the type system everywhere: No build over this repository\u0027s 75 Scala product file(s) passes \u0060-Yexplicit-nulls\u0060, enables WartRemover\u0027s \u0060Null\u0060 wart or runs Scalafix\u0027s \u0060DisableSyntax.noNulls\u0060, so every reference type admits null and nothing reports a \u0060null\u0060 written into the code or returned from a Java API \u2014 the first one to reach a method call is a \u0060NullPointerException\u0060. \u0060Option\u0060 by convention is a habit no tool here holds the code to."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"23e7c3c6da50151f07723c64ca4f881fd5903e713d143161a7c0594ad7ba29cc"}}],"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-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-1329","guid":"f70f1c3f-4ccf-cb5e-bdd3-03ba4868d36d","name":"Reliance on Component That is Not Updateable","shortDescription":{"text":"Reliance on Component That is Not Updateable"},"helpUri":"https://cwe.mitre.org/data/definitions/1329.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-250","guid":"52ee12e8-390a-7351-b1e6-388afa694e54","name":"CWE-250","shortDescription":{"text":"CWE-250"},"helpUri":"https://cwe.mitre.org/data/definitions/250.html"},{"id":"CWE-259","guid":"ae9ad959-fbb6-9d5e-892d-3dca66da0b69","name":"Use of Hard-coded Password","shortDescription":{"text":"Use of Hard-coded Password"},"helpUri":"https://cwe.mitre.org/data/definitions/259.html"},{"id":"CWE-353","guid":"09d7e902-d4ee-f05d-ae6c-0a1554d0c18f","name":"Missing Support for Integrity Check","shortDescription":{"text":"Missing Support for Integrity Check"},"helpUri":"https://cwe.mitre.org/data/definitions/353.html"},{"id":"CWE-494","guid":"b8a65e0d-e459-4a55-a931-fc1136482375","name":"Download of Code Without Integrity Check","shortDescription":{"text":"Download of Code Without Integrity Check"},"helpUri":"https://cwe.mitre.org/data/definitions/494.html"},{"id":"CWE-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-540","guid":"1a9db5db-e5bb-ae5d-935a-d1b4e9ee080b","name":"Inclusion of Sensitive Information in Source Code","shortDescription":{"text":"Inclusion of Sensitive Information in Source Code"},"helpUri":"https://cwe.mitre.org/data/definitions/540.html"},{"id":"CWE-611","guid":"1afbae66-ea29-2d59-aaa2-134e3ae2e85a","name":"Improper Restriction of XML External Entity Reference","shortDescription":{"text":"Improper Restriction of XML External Entity Reference"},"helpUri":"https://cwe.mitre.org/data/definitions/611.html"},{"id":"CWE-668","guid":"e2cb99db-6d24-b056-b0d0-885a733ec403","name":"Exposure of Resource to Wrong Sphere","shortDescription":{"text":"Exposure of Resource to Wrong Sphere"},"helpUri":"https://cwe.mitre.org/data/definitions/668.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":"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-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"}]}],"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":60,"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."]}]}