{"$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":"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":"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":"D11","name":"Test Reliability","shortDescription":{"text":"Test Reliability"},"helpUri":"https://codehealth.canine.dev/dimensions/D11"},{"id":"D13","name":"Secret Scanning","shortDescription":{"text":"Secret Scanning"},"helpUri":"https://codehealth.canine.dev/dimensions/D13","relationships":[{"target":{"id":"CWE-798","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},"kinds":["relevant"]},{"target":{"id":"CWE-259","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},"kinds":["relevant"]}],"properties":{"cwe":["CWE-798","CWE-259"]}},{"id":"D14","name":"License Compliance","shortDescription":{"text":"License Compliance"},"helpUri":"https://codehealth.canine.dev/dimensions/D14"},{"id":"D15","name":"Churn \u00D7 Complexity Hotspots","shortDescription":{"text":"Churn \u00D7 Complexity Hotspots"},"helpUri":"https://codehealth.canine.dev/dimensions/D15"},{"id":"D16","name":"Bus Factor","shortDescription":{"text":"Bus Factor"},"helpUri":"https://codehealth.canine.dev/dimensions/D16"},{"id":"D17","name":"Explicit Debt","shortDescription":{"text":"Explicit Debt"},"helpUri":"https://codehealth.canine.dev/dimensions/D17"},{"id":"D19","name":"Documentation Quality","shortDescription":{"text":"Documentation Quality"},"helpUri":"https://codehealth.canine.dev/dimensions/D19"},{"id":"D20","name":"ADR Quality","shortDescription":{"text":"ADR Quality"},"helpUri":"https://codehealth.canine.dev/dimensions/D20"},{"id":"D21","name":"Naming Consistency","shortDescription":{"text":"Naming Consistency"},"helpUri":"https://codehealth.canine.dev/dimensions/D21"},{"id":"D23","name":"Boundary Type-Coupling","shortDescription":{"text":"Boundary Type-Coupling"},"helpUri":"https://codehealth.canine.dev/dimensions/D23"},{"id":"D24","name":"Comment Value","shortDescription":{"text":"Comment Value"},"helpUri":"https://codehealth.canine.dev/dimensions/D24"},{"id":"D25","name":"ADR Conformance","shortDescription":{"text":"ADR Conformance"},"helpUri":"https://codehealth.canine.dev/dimensions/D25"},{"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"]}],"properties":{"cwe":["CWE-798","CWE-259"]}},{"id":"D29","name":"Static Analysis (SAST)","shortDescription":{"text":"Static Analysis (SAST)"},"helpUri":"https://codehealth.canine.dev/dimensions/D29","relationships":[{"target":{"id":"CWE-79","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},"kinds":["relevant"]},{"target":{"id":"CWE-89","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},"kinds":["relevant"]},{"target":{"id":"CWE-78","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},"kinds":["relevant"]},{"target":{"id":"CWE-94","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},"kinds":["relevant"]},{"target":{"id":"CWE-77","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},"kinds":["relevant"]}],"properties":{"cwe":["CWE-79","CWE-89","CWE-78","CWE-94","CWE-77"]}},{"id":"D30","name":"Dependency Vulnerabilities","shortDescription":{"text":"Dependency Vulnerabilities"},"helpUri":"https://codehealth.canine.dev/dimensions/D30","relationships":[{"target":{"id":"CWE-1395","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},"kinds":["relevant"]},{"target":{"id":"CWE-937","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},"kinds":["relevant"]}],"properties":{"cwe":["CWE-1395","CWE-937"]}},{"id":"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"]}],"properties":{"cwe":["CWE-1032","CWE-732","CWE-16"]}},{"id":"D33","name":"JS/npm Dependency Vulnerabilities","shortDescription":{"text":"JS/npm Dependency Vulnerabilities"},"helpUri":"https://codehealth.canine.dev/dimensions/D33","relationships":[{"target":{"id":"CWE-1395","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},"kinds":["relevant"]},{"target":{"id":"CWE-937","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},"kinds":["relevant"]}],"properties":{"cwe":["CWE-1395","CWE-937"]}},{"id":"D34","name":"Knowledge Freshness","shortDescription":{"text":"Knowledge Freshness"},"helpUri":"https://codehealth.canine.dev/dimensions/D34"},{"id":"D35","name":"Change Coupling","shortDescription":{"text":"Change Coupling"},"helpUri":"https://codehealth.canine.dev/dimensions/D35"},{"id":"D36","name":"Supply-chain Provenance \u0026 Signing","shortDescription":{"text":"Supply-chain Provenance \u0026 Signing"},"helpUri":"https://codehealth.canine.dev/dimensions/D36","relationships":[{"target":{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},"kinds":["relevant"]},{"target":{"id":"CWE-494","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},"kinds":["relevant"]}],"properties":{"cwe":["CWE-1357","CWE-494"]}},{"id":"D38","name":"OSV Dependency Vulnerabilities","shortDescription":{"text":"OSV Dependency Vulnerabilities"},"helpUri":"https://codehealth.canine.dev/dimensions/D38","relationships":[{"target":{"id":"CWE-1395","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},"kinds":["relevant"]},{"target":{"id":"CWE-937","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},"kinds":["relevant"]}],"properties":{"cwe":["CWE-1395","CWE-937"]}},{"id":"D40","name":"Network Egress Confinement","shortDescription":{"text":"Network Egress Confinement"},"helpUri":"https://codehealth.canine.dev/dimensions/D40"},{"id":"D41","name":"Kernel \u0026 Syscall Confinement","shortDescription":{"text":"Kernel \u0026 Syscall Confinement"},"helpUri":"https://codehealth.canine.dev/dimensions/D41"}]}},"results":[{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (43 lines \u00D7 3): backend/src/Enduser/Enduser.Database/UnitOfWork.cs:55-97 | backend/src/Master/Master.Database/UnitOfWork.cs:55-97 | backend/src/Partner/Partner.Database/UnitOfWork.cs:55-97 \u2014 the copies span different directories, so extracting a shared function means choosing where it lives: put it somewhere all 3 call sites can already reach \u2014 a location they all depend on today, or a new shared one if there is none \u2014 and call it from each site; until then, every change has to be made 3 times. Read the line range as the matched WINDOW rather than a finished unit: at \u0060backend/src/Enduser/Enduser.Database/UnitOfWork.cs:55\u0060 it begins part-way through the construct above it, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/src/Enduser/Enduser.Database/UnitOfWork.cs"},"region":{"startLine":55}}}],"partialFingerprints":{"codehealthFindingId/v1":"ba4acd5df21c92145e9ded32f45f29eb0134dc39929c5e3fff55aed39f883251"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (31 lines \u00D7 2): backend/src/Enduser/Features/Sync/GetSyncStatus/Feature.cs:53-83 | backend/src/Partner/Features/Sync/GetSyncStatus/Feature.cs:55-86 \u2014 the copies span different directories, so extracting a shared function means choosing where it lives: put it somewhere both call sites can already reach \u2014 a location they all depend on today, or a new shared one if there is none \u2014 and call it from each site; until then, every change has to be made twice. Read the line range as the matched WINDOW rather than a finished unit: at \u0060backend/src/Enduser/Features/Sync/GetSyncStatus/Feature.cs:53\u0060 it begins part-way through the construct above it, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/src/Enduser/Features/Sync/GetSyncStatus/Feature.cs"},"region":{"startLine":53}}}],"partialFingerprints":{"codehealthFindingId/v1":"69a85e1aaa450a4e683db6218bd5dd5dcbfb44751a5771ab9236e6262658fd50"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (25 lines \u00D7 2): backend/src/Enduser/Enduser.Api/Extensions/SecretHelper.cs:31-55 | backend/src/Partner/Partner.Api/Extensions/SecretHelper.cs:31-55 \u2014 the copies span different directories, so extracting a shared function means choosing where it lives: put it somewhere both call sites can already reach \u2014 a location they all depend on today, or a new shared one if there is none \u2014 and call it from each site; until then, every change has to be made twice. Read the line range as the matched WINDOW rather than a finished unit: at \u0060backend/src/Enduser/Enduser.Api/Extensions/SecretHelper.cs:31\u0060 it begins part-way through the construct above it, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/src/Enduser/Enduser.Api/Extensions/SecretHelper.cs"},"region":{"startLine":31}}}],"partialFingerprints":{"codehealthFindingId/v1":"32d576f137c90955f3cffd7308c537e6346782a48383e975a9876001ad09fae6"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (25 lines \u00D7 2): backend/src/Enduser/Enduser.Api/Services/SupportTicketPushHandler.cs:71-95 | backend/src/Partner/Partner.Api/Services/SupportTicketPushHandler.cs:60-84 \u2014 before extracting anything, compare \u0060backend/src/Enduser/Enduser.Api/Services/SupportTicketPushHandler.cs\u0060 and \u0060backend/src/Partner/Partner.Api/Services/SupportTicketPushHandler.cs\u0060 as WHOLE FILES: this scan already matched 3 separate duplicated blocks between them, totalling at least 60 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. Read the line range as the matched WINDOW rather than a finished unit: at \u0060backend/src/Enduser/Enduser.Api/Services/SupportTicketPushHandler.cs:71\u0060 it begins part-way through the construct above it, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/src/Enduser/Enduser.Api/Services/SupportTicketPushHandler.cs"},"region":{"startLine":71}}}],"partialFingerprints":{"codehealthFindingId/v1":"2436e4e80015979bae75895356fc53bd784adec317b7f661ba138ebb0aec4a24"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (25 lines \u00D7 2): backend/src/Master/Features/Tags/GetTagsForApplications/Feature.cs:37-61 | backend/src/Partner/Features/Tags/GetTagsForApplications/Feature.cs:31-55 \u2014 the copies span different directories, so extracting a shared function means choosing where it lives: put it somewhere both call sites can already reach \u2014 a location they all depend on today, or a new shared one if there is none \u2014 and call it from each site; until then, every change has to be made twice. Read the line range as the matched WINDOW rather than a finished unit: at \u0060backend/src/Master/Features/Tags/GetTagsForApplications/Feature.cs:37\u0060 it begins part-way through the construct above it, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/src/Master/Features/Tags/GetTagsForApplications/Feature.cs"},"region":{"startLine":37}}}],"partialFingerprints":{"codehealthFindingId/v1":"535c0b8743b858dae6ca19d1c55070e93b7ca5b5d06ec359818d4a1ae59cf822"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (25 lines \u00D7 2): backend/src/Master/Features/Tags/GetTagsForDataContexts/Feature.cs:37-61 | backend/src/Partner/Features/Tags/GetTagsForDataContexts/Feature.cs:31-55 \u2014 the copies span different directories, so extracting a shared function means choosing where it lives: put it somewhere both call sites can already reach \u2014 a location they all depend on today, or a new shared one if there is none \u2014 and call it from each site; until then, every change has to be made twice. Read the line range as the matched WINDOW rather than a finished unit: at \u0060backend/src/Master/Features/Tags/GetTagsForDataContexts/Feature.cs:37\u0060 it begins part-way through the construct above it, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/src/Master/Features/Tags/GetTagsForDataContexts/Feature.cs"},"region":{"startLine":37}}}],"partialFingerprints":{"codehealthFindingId/v1":"3601cedaa6f3e1a5941f8ae8a7175f4762e2bd2af796fe8dd70231fbf8600538"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (25 lines \u00D7 2): backend/src/Master/Features/Tags/GetTagsForUsers/Feature.cs:37-61 | backend/src/Partner/Features/Tags/GetTagsForUsers/Feature.cs:31-55 \u2014 the copies span different directories, so extracting a shared function means choosing where it lives: put it somewhere both call sites can already reach \u2014 a location they all depend on today, or a new shared one if there is none \u2014 and call it from each site; until then, every change has to be made twice. Read the line range as the matched WINDOW rather than a finished unit: at \u0060backend/src/Master/Features/Tags/GetTagsForUsers/Feature.cs:37\u0060 it begins part-way through the construct above it, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/src/Master/Features/Tags/GetTagsForUsers/Feature.cs"},"region":{"startLine":37}}}],"partialFingerprints":{"codehealthFindingId/v1":"6fddbb3996c0824ed40c891fd3ef28470e766bcabc34dd9efc21345f6c1b3cb9"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (23 lines \u00D7 2): backend/src/Enduser/Enduser.Api/Middleware/ContentTypeValidationMiddleware.cs:59-81 | backend/src/Partner/Partner.Api/Middleware/ContentTypeValidationMiddleware.cs:59-81 \u2014 before extracting anything, compare \u0060backend/src/Enduser/Enduser.Api/Middleware/ContentTypeValidationMiddleware.cs\u0060 and \u0060backend/src/Partner/Partner.Api/Middleware/ContentTypeValidationMiddleware.cs\u0060 as WHOLE FILES: this scan already matched 3 separate duplicated blocks between them, totalling at least 49 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. Read the line range as the matched WINDOW rather than a finished unit: at \u0060backend/src/Enduser/Enduser.Api/Middleware/ContentTypeValidationMiddleware.cs:59\u0060 it begins part-way through the construct above it, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/src/Enduser/Enduser.Api/Middleware/ContentTypeValidationMiddleware.cs"},"region":{"startLine":59}}}],"partialFingerprints":{"codehealthFindingId/v1":"3a388075d317e0fc5d2f178b911ff4e51d0135cb7c66679849ed9aa0142a937b"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (21 lines \u00D7 2): backend/src/Enduser/Enduser.Api/Adapters/Subscriptions/SubscriptionDispatcher.cs:88-108 | backend/src/Partner/Partner.Api/Adapters/Subscriptions/SubscriptionDispatcher.cs:88-108 \u2014 the copies span different directories, so extracting a shared function means choosing where it lives: put it somewhere both call sites can already reach \u2014 a location they all depend on today, or a new shared one if there is none \u2014 and call it from each site; until then, every change has to be made twice. Read the line range as the matched WINDOW rather than a finished unit: at \u0060backend/src/Enduser/Enduser.Api/Adapters/Subscriptions/SubscriptionDispatcher.cs:88\u0060 it begins part-way through the construct above it, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/src/Enduser/Enduser.Api/Adapters/Subscriptions/SubscriptionDispatcher.cs"},"region":{"startLine":88}}}],"partialFingerprints":{"codehealthFindingId/v1":"c14e758664ecf44e3350cabe2f0ab2d68be467aaca6faab351ee9f6d84c27269"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (21 lines \u00D7 2): backend/src/Enduser/Enduser.Api/Services/SupportTicketPushHandler.cs:138-158 | backend/src/Partner/Partner.Api/Services/SupportTicketPushHandler.cs:118-138 \u2014 before extracting anything, compare \u0060backend/src/Enduser/Enduser.Api/Services/SupportTicketPushHandler.cs\u0060 and \u0060backend/src/Partner/Partner.Api/Services/SupportTicketPushHandler.cs\u0060 as WHOLE FILES: this scan already matched 3 separate duplicated blocks between them, totalling at least 60 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. Read the line range as the matched WINDOW rather than a finished unit: at \u0060backend/src/Enduser/Enduser.Api/Services/SupportTicketPushHandler.cs:138\u0060 it begins part-way through the construct above it, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/src/Enduser/Enduser.Api/Services/SupportTicketPushHandler.cs"},"region":{"startLine":138}}}],"partialFingerprints":{"codehealthFindingId/v1":"8be663c03cf8916073c9fed4779ef7456bf1cd8329199e619f5d9a76ac7336c5"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (21 lines \u00D7 2): backend/src/Master/Features/Units/UpdateUnitGroup/Feature.cs:109-129 | backend/src/Master/Features/Units/UpdateUnits/Feature.cs:108-130 \u2014 the copies span different directories, so extracting a shared function means choosing where it lives: put it somewhere both call sites can already reach \u2014 a location they all depend on today, or a new shared one if there is none \u2014 and call it from each site; until then, every change has to be made twice."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/src/Master/Features/Units/UpdateUnitGroup/Feature.cs"},"region":{"startLine":109}}}],"partialFingerprints":{"codehealthFindingId/v1":"917e748477859a6d512f4056aac19ebce490ad1f649d15b1420730a4088f1304"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (19 lines \u00D7 2): backend/src/Enduser/Enduser.Api/Adapters/Subscriptions/InMemoryConnectionManager.cs:97-115 | backend/src/Partner/Partner.Api/Adapters/Subscriptions/InMemoryConnectionManager.cs:97-115 \u2014 the copies span different directories, so extracting a shared function means choosing where it lives: put it somewhere both call sites can already reach \u2014 a location they all depend on today, or a new shared one if there is none \u2014 and call it from each site; until then, every change has to be made twice. Read the line range as the matched WINDOW rather than a finished unit: at \u0060backend/src/Enduser/Enduser.Api/Adapters/Subscriptions/InMemoryConnectionManager.cs:97\u0060 it begins part-way through the construct above it, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/src/Enduser/Enduser.Api/Adapters/Subscriptions/InMemoryConnectionManager.cs"},"region":{"startLine":97}}}],"partialFingerprints":{"codehealthFindingId/v1":"ab7a84d4f32ba13bc956213e85f91716df72a1c57cda2a4830fbeaba78b88cb8"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (19 lines \u00D7 2): backend/src/Enduser/Enduser.Api/Services/SyncService.cs:88-106 | backend/src/Partner/Partner.Api/Services/SyncService.cs:78-97 \u2014 the copies span different directories, so extracting a shared function means choosing where it lives: put it somewhere both call sites can already reach \u2014 a location they all depend on today, or a new shared one if there is none \u2014 and call it from each site; until then, every change has to be made twice. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/src/Enduser/Enduser.Api/Services/SyncService.cs"},"region":{"startLine":88}}}],"partialFingerprints":{"codehealthFindingId/v1":"a9455a96ecd13551724c052ae6a3ce6ea2841628daa1c5317e9ad809ccedb30d"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (18 lines \u00D7 3): backend/src/Enduser/Enduser.Api/Adapters/Subscriptions/InMemoryConnectionManager.cs:45-62 | backend/src/Master/Master.Api/Adapters/Subscriptions/InMemoryConnectionManager.cs:44-61 | backend/src/Partner/Partner.Api/Adapters/Subscriptions/InMemoryConnectionManager.cs:45-62 \u2014 the copies span different directories, so extracting a shared function means choosing where it lives: put it somewhere all 3 call sites can already reach \u2014 a location they all depend on today, or a new shared one if there is none \u2014 and call it from each site; until then, every change has to be made 3 times. Read the line range as the matched WINDOW rather than a finished unit: at \u0060backend/src/Enduser/Enduser.Api/Adapters/Subscriptions/InMemoryConnectionManager.cs:45\u0060 it begins part-way through the construct above it, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/src/Enduser/Enduser.Api/Adapters/Subscriptions/InMemoryConnectionManager.cs"},"region":{"startLine":45}}}],"partialFingerprints":{"codehealthFindingId/v1":"80586ada91b5322c86eeede552b74322119b31a25fba04fa734e17affeab41b3"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (18 lines \u00D7 2): backend/src/Enduser/Enduser.Api/Services/SupportSyncService.cs:89-106 | backend/src/Partner/Partner.Api/Services/SupportSyncService.cs:89-106 \u2014 the copies span different directories, so extracting a shared function means choosing where it lives: put it somewhere both call sites can already reach \u2014 a location they all depend on today, or a new shared one if there is none \u2014 and call it from each site; until then, every change has to be made twice."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/src/Enduser/Enduser.Api/Services/SupportSyncService.cs"},"region":{"startLine":89}}}],"partialFingerprints":{"codehealthFindingId/v1":"74104569ec8e2bd5ea3335942ce31613c548987030d8c51c5238d76d4ff43b22"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (18 lines \u00D7 2): backend/src/Master/Features/DataContexts/CreateDataContext/Feature.cs:212-229 | backend/src/Master/Features/DataContexts/UpdateDataContext/Feature.cs:233-250 \u2014 the copies span different directories, so extracting a shared function means choosing where it lives: put it somewhere both call sites can already reach \u2014 a location they all depend on today, or a new shared one if there is none \u2014 and call it from each site; until then, every change has to be made twice. Note that the copies do not run to the end of the range shown: their LAST lines are different code, not the same code under different names \u2014 the matched region ends inside that line. Extract the lines above it, and read the last line of each site separately."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/src/Master/Features/DataContexts/CreateDataContext/Feature.cs"},"region":{"startLine":212}}}],"partialFingerprints":{"codehealthFindingId/v1":"d74e4543394cafe23c00a38ab8dfd2e0aa6dcf52b05720ce4a19d3808e0a25ad"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (17 lines \u00D7 3): backend/src/Enduser/Enduser.Api/Middleware/RequestValidationMiddleware.cs:97-113 | backend/src/Master/Master.Api/Middleware/RequestValidationMiddleware.cs:97-113 | backend/src/Partner/Partner.Api/Middleware/RequestValidationMiddleware.cs:97-113 \u2014 the copies span different directories, so extracting a shared function means choosing where it lives: put it somewhere all 3 call sites can already reach \u2014 a location they all depend on today, or a new shared one if there is none \u2014 and call it from each site; until then, every change has to be made 3 times. Read the line range as the matched WINDOW rather than a finished unit: at \u0060backend/src/Enduser/Enduser.Api/Middleware/RequestValidationMiddleware.cs:97\u0060 it begins part-way through the construct above it, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/src/Enduser/Enduser.Api/Middleware/RequestValidationMiddleware.cs"},"region":{"startLine":97}}}],"partialFingerprints":{"codehealthFindingId/v1":"4d25a6974e1f8247059518aaf47e5aff22be68a6ab089b091eaa4f8916984353"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (17 lines \u00D7 2): backend/src/Partner/Features/Applications/CreateApplication/Contract/Request.cs:25-41 | backend/src/Partner/Features/Applications/UpdateApplication/Contract/Request.cs:26-42 \u2014 the copies span different directories, so extracting a shared function means choosing where it lives: put it somewhere both call sites can already reach \u2014 a location they all depend on today, or a new shared one if there is none \u2014 and call it from each site; until then, every change has to be made twice. Read the line range as the matched WINDOW rather than a finished unit: at \u0060backend/src/Partner/Features/Applications/CreateApplication/Contract/Request.cs:25\u0060 it begins part-way through the construct above it, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/src/Partner/Features/Applications/CreateApplication/Contract/Request.cs"},"region":{"startLine":25}}}],"partialFingerprints":{"codehealthFindingId/v1":"e836502906962a981c4bffd1477d953699c9af7c16b675733d9012f7825bc656"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (16 lines \u00D7 2): backend/src/Enduser/Enduser.Api/Services/SupportSyncService.cs:44-59 | backend/src/Partner/Partner.Api/Services/SupportSyncService.cs:44-59 \u2014 the copies span different directories, so extracting a shared function means choosing where it lives: put it somewhere both call sites can already reach \u2014 a location they all depend on today, or a new shared one if there is none \u2014 and call it from each site; until then, every change has to be made twice. Read the line range as the matched WINDOW rather than a finished unit: at \u0060backend/src/Enduser/Enduser.Api/Services/SupportSyncService.cs:44\u0060 it begins part-way through the construct above it, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/src/Enduser/Enduser.Api/Services/SupportSyncService.cs"},"region":{"startLine":44}}}],"partialFingerprints":{"codehealthFindingId/v1":"32f7a2565742201488ae59ecfbb112665d365a8752f615ba22e25ba2070e478d"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (16 lines \u00D7 2): backend/src/Master/Features/DataContexts/GetDataContextDetails/Feature.cs:138-153 | backend/src/Master/Features/Tags/GetTagDetails/Feature.cs:137-152 \u2014 the copies span different directories, so extracting a shared function means choosing where it lives: put it somewhere both call sites can already reach \u2014 a location they all depend on today, or a new shared one if there is none \u2014 and call it from each site; until then, every change has to be made twice. Read the line range as the matched WINDOW rather than a finished unit: at \u0060backend/src/Master/Features/DataContexts/GetDataContextDetails/Feature.cs:138\u0060 it begins part-way through the construct above it, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/src/Master/Features/DataContexts/GetDataContextDetails/Feature.cs"},"region":{"startLine":138}}}],"partialFingerprints":{"codehealthFindingId/v1":"dfb2ac6d5ffd5de9b2b2eaa9cb1191e41962e93ed2980bf5bff9809369da361e"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (15 lines \u00D7 3): backend/src/Enduser/Enduser.Api/Adapters/Subscriptions/InMemorySubscriptionStore.cs:39-53 | backend/src/Master/Master.Api/Adapters/Subscriptions/InMemorySubscriptionStore.cs:39-53 | backend/src/Partner/Partner.Api/Adapters/Subscriptions/InMemorySubscriptionStore.cs:39-53 \u2014 before extracting anything, compare \u0060backend/src/Enduser/Enduser.Api/Adapters/Subscriptions/InMemorySubscriptionStore.cs\u0060 and \u0060backend/src/Master/Master.Api/Adapters/Subscriptions/InMemorySubscriptionStore.cs\u0060 as WHOLE FILES: this scan already matched 4 separate duplicated blocks between them, totalling at least 51 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. Read the line range as the matched WINDOW rather than a finished unit: at \u0060backend/src/Enduser/Enduser.Api/Adapters/Subscriptions/InMemorySubscriptionStore.cs:39\u0060 it begins part-way through the construct above it, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/src/Enduser/Enduser.Api/Adapters/Subscriptions/InMemorySubscriptionStore.cs"},"region":{"startLine":39}}}],"partialFingerprints":{"codehealthFindingId/v1":"c9d4794dc9725e32e04353ea65fbee7cf753350a8026c80b1115859dbf7caabf"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (15 lines \u00D7 2): backend/src/Enduser/Enduser.Api/Endpoints/BootstrapEndpoints.cs:13-27 | backend/src/Partner/Partner.Api/Endpoints/BootstrapEndpoints.cs:17-42 \u2014 the copies span different directories, so extracting a shared function means choosing where it lives: put it somewhere both call sites can already reach \u2014 a location they all depend on today, or a new shared one if there is none \u2014 and call it from each site; until then, every change has to be made twice."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/src/Enduser/Enduser.Api/Endpoints/BootstrapEndpoints.cs"},"region":{"startLine":13}}}],"partialFingerprints":{"codehealthFindingId/v1":"0b2ca7dab9b90b944c53b06d41eb869f029874b7ae3a197090d83dd74c6115c6"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (15 lines \u00D7 2): backend/src/Master/Features/DataContexts/GetDataContexts/Feature.cs:55-69 | backend/src/Partner/Features/DataContexts/GetDataContexts/Feature.cs:49-68 \u2014 the copies span different directories, so extracting a shared function means choosing where it lives: put it somewhere both call sites can already reach \u2014 a location they all depend on today, or a new shared one if there is none \u2014 and call it from each site; until then, every change has to be made twice. Read the line range as the matched WINDOW rather than a finished unit: at \u0060backend/src/Master/Features/DataContexts/GetDataContexts/Feature.cs:55\u0060 it begins part-way through the construct above it, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that. Note that the copies do not run to the end of the range shown: their LAST lines are different code, not the same code under different names \u2014 the matched region ends inside that line. Extract the lines above it, and read the last line of each site separately."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/src/Master/Features/DataContexts/GetDataContexts/Feature.cs"},"region":{"startLine":55}}}],"partialFingerprints":{"codehealthFindingId/v1":"576bebb40a67589efc8f317e721cfb4c202533efb67c1331090f8e9b9c33c816"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (14 lines \u00D7 3): backend/src/Enduser/Enduser.Api/Adapters/Subscriptions/InMemorySubscriptionStore.cs:60-73 | backend/src/Master/Master.Api/Adapters/Subscriptions/InMemorySubscriptionStore.cs:60-73 | backend/src/Partner/Partner.Api/Adapters/Subscriptions/InMemorySubscriptionStore.cs:60-73 \u2014 before extracting anything, compare \u0060backend/src/Enduser/Enduser.Api/Adapters/Subscriptions/InMemorySubscriptionStore.cs\u0060 and \u0060backend/src/Master/Master.Api/Adapters/Subscriptions/InMemorySubscriptionStore.cs\u0060 as WHOLE FILES: this scan already matched 4 separate duplicated blocks between them, totalling at least 51 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. Read the line range as the matched WINDOW rather than a finished unit: at \u0060backend/src/Enduser/Enduser.Api/Adapters/Subscriptions/InMemorySubscriptionStore.cs:60\u0060 it begins part-way through the construct above it, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/src/Enduser/Enduser.Api/Adapters/Subscriptions/InMemorySubscriptionStore.cs"},"region":{"startLine":60}}}],"partialFingerprints":{"codehealthFindingId/v1":"0688b3774a7f33d41ef50ef4eee52e127e33782c5d8d9e52c866014f9182dc78"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (14 lines \u00D7 2): backend/src/Enduser/Enduser.Api/Services/SupportTicketPushHandler.cs:107-120 | backend/src/Partner/Partner.Api/Services/SupportTicketPushHandler.cs:100-113 \u2014 before extracting anything, compare \u0060backend/src/Enduser/Enduser.Api/Services/SupportTicketPushHandler.cs\u0060 and \u0060backend/src/Partner/Partner.Api/Services/SupportTicketPushHandler.cs\u0060 as WHOLE FILES: this scan already matched 3 separate duplicated blocks between them, totalling at least 60 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/src/Enduser/Enduser.Api/Services/SupportTicketPushHandler.cs"},"region":{"startLine":107}}}],"partialFingerprints":{"codehealthFindingId/v1":"36c23c7b6dc3bb5b2a53cf1e0a93b70b517cf79727ed6e3b4a2612c9bb67cb45"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (14 lines \u00D7 2): backend/src/Enduser/Enduser.Database/Services/TaskAssigneeResolver.cs:87-100 | backend/src/Enduser/Enduser.Database/Services/ValidatorResolver.cs:71-84 \u2014 the copies sit in sibling files of one directory: extract the block into a single shared function in that directory and call it from each site, so a change lands once. Read the line range as the matched WINDOW rather than a finished unit: at \u0060backend/src/Enduser/Enduser.Database/Services/TaskAssigneeResolver.cs:87\u0060 it begins part-way through the construct above it, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/src/Enduser/Enduser.Database/Services/TaskAssigneeResolver.cs"},"region":{"startLine":87}}}],"partialFingerprints":{"codehealthFindingId/v1":"de7a59233503a1247c5896938ab3e4ac5acee7e3130ea0c4ead3dc8ccdfeb95c"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (14 lines \u00D7 2): backend/src/SourceGenerators/Features.Generator/SymbolExtensions.cs:64-78 | backend/src/Tools/TypeScriptClientGenerator/Core/ClientGenerator.cs:725-738 \u2014 the copies span different directories, so extracting a shared function means choosing where it lives: put it somewhere both call sites can already reach \u2014 a location they all depend on today, or a new shared one if there is none \u2014 and call it from each site; until then, every change has to be made twice. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/src/SourceGenerators/Features.Generator/SymbolExtensions.cs"},"region":{"startLine":64}}}],"partialFingerprints":{"codehealthFindingId/v1":"24f1a5831c4b11f9a39e2bd3aa48f687420feabd6e5e6a147cc662df9d9c552a"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (13 lines \u00D7 3): backend/src/Enduser/Enduser.Api/Middleware/ContentTypeValidationMiddleware.cs:95-107 | backend/src/Master/Master.Api/Middleware/ContentTypeValidationMiddleware.cs:95-107 | backend/src/Partner/Partner.Api/Middleware/ContentTypeValidationMiddleware.cs:95-107 \u2014 before extracting anything, compare \u0060backend/src/Enduser/Enduser.Api/Middleware/ContentTypeValidationMiddleware.cs\u0060 and \u0060backend/src/Partner/Partner.Api/Middleware/ContentTypeValidationMiddleware.cs\u0060 as WHOLE FILES: this scan already matched 3 separate duplicated blocks between them, totalling at least 49 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. Read the line range as the matched WINDOW rather than a finished unit: at \u0060backend/src/Enduser/Enduser.Api/Middleware/ContentTypeValidationMiddleware.cs:95\u0060 it does not close everything it opens, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/src/Enduser/Enduser.Api/Middleware/ContentTypeValidationMiddleware.cs"},"region":{"startLine":95}}}],"partialFingerprints":{"codehealthFindingId/v1":"eb679408a23ab226e1442f3b381ff132f56df40e2a17674dd42d37b4a4015e46"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (13 lines \u00D7 3): backend/src/Enduser/Enduser.Api/Middleware/ContentTypeValidationMiddleware.cs:113-125 | backend/src/Master/Master.Api/Middleware/ContentTypeValidationMiddleware.cs:113-125 | backend/src/Partner/Partner.Api/Middleware/ContentTypeValidationMiddleware.cs:113-125 \u2014 before extracting anything, compare \u0060backend/src/Enduser/Enduser.Api/Middleware/ContentTypeValidationMiddleware.cs\u0060 and \u0060backend/src/Partner/Partner.Api/Middleware/ContentTypeValidationMiddleware.cs\u0060 as WHOLE FILES: this scan already matched 3 separate duplicated blocks between them, totalling at least 49 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. Read the line range as the matched WINDOW rather than a finished unit: at \u0060backend/src/Enduser/Enduser.Api/Middleware/ContentTypeValidationMiddleware.cs:113\u0060 it does not close everything it opens, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/src/Enduser/Enduser.Api/Middleware/ContentTypeValidationMiddleware.cs"},"region":{"startLine":113}}}],"partialFingerprints":{"codehealthFindingId/v1":"a78f77b43b34c573584108d4c15696bac71985a6776e4a163e60e80853e8384e"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (13 lines \u00D7 3): backend/src/Enduser/Enduser.Database/Extensions/DatabaseServiceExtensions.cs:19-31 | backend/src/Master/Master.Database/Extensions/DatabaseServiceExtensions.cs:18-30 | backend/src/Partner/Partner.Database/Extensions/DatabaseServiceExtensions.cs:18-30 \u2014 the copies span different directories, so extracting a shared function means choosing where it lives: put it somewhere all 3 call sites can already reach \u2014 a location they all depend on today, or a new shared one if there is none \u2014 and call it from each site; until then, every change has to be made 3 times."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/src/Enduser/Enduser.Database/Extensions/DatabaseServiceExtensions.cs"},"region":{"startLine":19}}}],"partialFingerprints":{"codehealthFindingId/v1":"88e6738e225f3d7610403a6fec682790e1d7f30fa36064616547ae6613231893"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (13 lines \u00D7 2): backend/src/Master/Features/DataContexts/CreateDataContext/Feature.cs:116-128 | backend/src/Master/Features/DataContexts/UpdateDataContext/Feature.cs:115-127 \u2014 the copies span different directories, so extracting a shared function means choosing where it lives: put it somewhere both call sites can already reach \u2014 a location they all depend on today, or a new shared one if there is none \u2014 and call it from each site; until then, every change has to be made twice. Read the line range as the matched WINDOW rather than a finished unit: at \u0060backend/src/Master/Features/DataContexts/CreateDataContext/Feature.cs:116\u0060 it begins part-way through the construct above it, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/src/Master/Features/DataContexts/CreateDataContext/Feature.cs"},"region":{"startLine":116}}}],"partialFingerprints":{"codehealthFindingId/v1":"c023e843457bd3b93bc077c599a5ed4f2cb0647a6a78919f924a5605e8d98a4c"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (12 lines \u00D7 3): backend/src/Enduser/Enduser.Api/Adapters/Subscriptions/InMemorySubscriptionStore.cs:82-93 | backend/src/Master/Master.Api/Adapters/Subscriptions/InMemorySubscriptionStore.cs:82-93 | backend/src/Partner/Partner.Api/Adapters/Subscriptions/InMemorySubscriptionStore.cs:82-93 \u2014 before extracting anything, compare \u0060backend/src/Enduser/Enduser.Api/Adapters/Subscriptions/InMemorySubscriptionStore.cs\u0060 and \u0060backend/src/Master/Master.Api/Adapters/Subscriptions/InMemorySubscriptionStore.cs\u0060 as WHOLE FILES: this scan already matched 4 separate duplicated blocks between them, totalling at least 51 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. Read the line range as the matched WINDOW rather than a finished unit: at \u0060backend/src/Enduser/Enduser.Api/Adapters/Subscriptions/InMemorySubscriptionStore.cs:82\u0060 it begins part-way through the construct above it, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/src/Enduser/Enduser.Api/Adapters/Subscriptions/InMemorySubscriptionStore.cs"},"region":{"startLine":82}}}],"partialFingerprints":{"codehealthFindingId/v1":"eed19dace9bc3875914b594d6a3e3b294b1511adaac70b405f37cd25a4dcf903"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (12 lines \u00D7 2): backend/src/Enduser/Enduser.Database/Extensions/DatabaseServiceExtensions.cs:52-63 | backend/src/Master/Master.Database/Extensions/DatabaseServiceExtensions.cs:48-59 \u2014 the copies span different directories, so extracting a shared function means choosing where it lives: put it somewhere both call sites can already reach \u2014 a location they all depend on today, or a new shared one if there is none \u2014 and call it from each site; until then, every change has to be made twice."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/src/Enduser/Enduser.Database/Extensions/DatabaseServiceExtensions.cs"},"region":{"startLine":52}}}],"partialFingerprints":{"codehealthFindingId/v1":"981fe3612cc8ed4c7c25c0e82e702d0c587db3026db2cf26e3556ab6f1955be1"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (12 lines \u00D7 2): backend/src/Enduser/Enduser.Database/Services/TaskAssigneeResolver.cs:58-69 | backend/src/Enduser/Enduser.Database/Services/ValidatorResolver.cs:42-53 \u2014 the copies sit in sibling files of one directory: extract the block into a single shared function in that directory and call it from each site, so a change lands once. Read the line range as the matched WINDOW rather than a finished unit: at \u0060backend/src/Enduser/Enduser.Database/Services/TaskAssigneeResolver.cs:58\u0060 it begins part-way through the construct above it, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/src/Enduser/Enduser.Database/Services/TaskAssigneeResolver.cs"},"region":{"startLine":58}}}],"partialFingerprints":{"codehealthFindingId/v1":"e536dbe566e84f281c341b4084a7653065deb711c7d8e37fb1f8b76bfb1a6816"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (12 lines \u00D7 2): backend/src/Shared/Features/Auth/GetCurrentUser/Feature.cs:69-82 | backend/src/Shared/Features/GetMe/Feature.cs:176-187 \u2014 the copies span different directories, so extracting a shared function means choosing where it lives: put it somewhere both call sites can already reach \u2014 a location they all depend on today, or a new shared one if there is none \u2014 and call it from each site; until then, every change has to be made twice. Read the line range as the matched WINDOW rather than a finished unit: at \u0060backend/src/Shared/Features/Auth/GetCurrentUser/Feature.cs:69\u0060 it begins part-way through the construct above it, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/src/Shared/Features/Auth/GetCurrentUser/Feature.cs"},"region":{"startLine":69}}}],"partialFingerprints":{"codehealthFindingId/v1":"527e9e6e27385c05bd812ccda3f90b242664e4319a1e47dc4f40c19ca19e41d6"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (12 lines \u00D7 2): backend/src/Shared/Features/MyTasks/GetTasksDashboard/Feature.cs:57-69 | backend/src/Shared/Features/MyTasks/GetTasksDashboard/Feature.cs:171-182 \u2014 both copies are in the same file, so extract the block into one function there and call it from each site \u2014 the copies drift apart the first time only one of them is edited. Read the line range as the matched WINDOW rather than a finished unit: at \u0060backend/src/Shared/Features/MyTasks/GetTasksDashboard/Feature.cs:57\u0060 it begins part-way through the construct above it, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/src/Shared/Features/MyTasks/GetTasksDashboard/Feature.cs"},"region":{"startLine":57}}}],"partialFingerprints":{"codehealthFindingId/v1":"134366eee8a13925fdb3ad73e56a863f8ac2eaa50771e76fddb0c8062bc99f91"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (11 lines \u00D7 3): backend/src/Partner/Partner.Api/Endpoints/SyncEndpoints.cs:753-763 | backend/src/Partner/Partner.Api/Services/SupportSyncService.cs:265-275 | backend/src/Partner/Partner.Api/Services/SupportTicketPushHandler.cs:146-156 \u2014 the copies span different directories, so extracting a shared function means choosing where it lives: put it somewhere all 3 call sites can already reach \u2014 a location they all depend on today, or a new shared one if there is none \u2014 and call it from each site; until then, every change has to be made 3 times. Read the line range as the matched WINDOW rather than a finished unit: at \u0060backend/src/Partner/Partner.Api/Endpoints/SyncEndpoints.cs:753\u0060 it begins part-way through the construct above it, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/src/Partner/Partner.Api/Endpoints/SyncEndpoints.cs"},"region":{"startLine":753}}}],"partialFingerprints":{"codehealthFindingId/v1":"8db90f63cd290e49d6292259c07b9f99f7678aa68f2fa50340a0f920c2e0f548"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (11 lines \u00D7 2): backend/src/Enduser/Enduser.Api/Services/SupportSyncService.cs:284-294 | backend/src/Enduser/Enduser.Api/Services/SupportTicketPushHandler.cs:166-176 \u2014 the copies sit in sibling files of one directory: extract the block into a single shared function in that directory and call it from each site, so a change lands once. Read the line range as the matched WINDOW rather than a finished unit: at \u0060backend/src/Enduser/Enduser.Api/Services/SupportSyncService.cs:284\u0060 it begins part-way through the construct above it, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/src/Enduser/Enduser.Api/Services/SupportSyncService.cs"},"region":{"startLine":284}}}],"partialFingerprints":{"codehealthFindingId/v1":"1cfebe52c82f2e18069cedf711e5961f50631a9c8ed10e9870654b90eaf144f9"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (11 lines \u00D7 2): backend/src/Enduser/Enduser.Database/Services/TagAncestry.cs:48-58 | backend/src/Partner/Partner.Database/Services/TagAncestry.cs:54-64 \u2014 the copies span different directories, so extracting a shared function means choosing where it lives: put it somewhere both call sites can already reach \u2014 a location they all depend on today, or a new shared one if there is none \u2014 and call it from each site; until then, every change has to be made twice. Read the line range as the matched WINDOW rather than a finished unit: at \u0060backend/src/Enduser/Enduser.Database/Services/TagAncestry.cs:48\u0060 it does not close everything it opens, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/src/Enduser/Enduser.Database/Services/TagAncestry.cs"},"region":{"startLine":48}}}],"partialFingerprints":{"codehealthFindingId/v1":"7e76756d82ab54906a7c2ba84393a6a371cb1e5e1dd18f368f72dc6e73634460"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (11 lines \u00D7 2): backend/src/Shared/Features/Applications/SubmitAnswer/Feature.cs:343-353 | backend/src/Shared/Features/Applications/ConfirmActionRecommendations/Feature.cs:106-116 \u2014 the copies span different directories, so extracting a shared function means choosing where it lives: put it somewhere both call sites can already reach \u2014 a location they all depend on today, or a new shared one if there is none \u2014 and call it from each site; until then, every change has to be made twice. Read the line range as the matched WINDOW rather than a finished unit: at \u0060backend/src/Shared/Features/Applications/SubmitAnswer/Feature.cs:343\u0060 it begins part-way through the construct above it, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/src/Shared/Features/Applications/SubmitAnswer/Feature.cs"},"region":{"startLine":343}}}],"partialFingerprints":{"codehealthFindingId/v1":"e9f061676423a7d30a9ad465a0cb9dd72733eea113b3247cd2e8f66009bd6d0b"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (11 lines \u00D7 2): backend/src/Shared/Features/Assignments/GrantAssignment/Feature.cs:182-192 | backend/src/Shared/Features/Assignments/RevokeAssignment/Feature.cs:121-131 \u2014 the copies span different directories, so extracting a shared function means choosing where it lives: put it somewhere both call sites can already reach \u2014 a location they all depend on today, or a new shared one if there is none \u2014 and call it from each site; until then, every change has to be made twice. Read the line range as the matched WINDOW rather than a finished unit: at \u0060backend/src/Shared/Features/Assignments/GrantAssignment/Feature.cs:182\u0060 it begins part-way through the construct above it, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/src/Shared/Features/Assignments/GrantAssignment/Feature.cs"},"region":{"startLine":182}}}],"partialFingerprints":{"codehealthFindingId/v1":"6fd53a72708ba844920956abd905f63ae61c8d2c20b739421891a598aa596115"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (11 lines \u00D7 2): backend/src/SourceGenerators/Features.Generator/FeatureRegistrationGenerator.cs:296-306 | backend/src/SourceGenerators/Features.Generator/FeatureRegistrationGenerator.cs:316-326 \u2014 both copies are in the same file, so extract the block into one function there and call it from each site \u2014 the copies drift apart the first time only one of them is edited. Read the line range as the matched WINDOW rather than a finished unit: at \u0060backend/src/SourceGenerators/Features.Generator/FeatureRegistrationGenerator.cs:296\u0060 it does not close everything it opens, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it. Note that the copies do not run to the end of the range shown: their LAST lines are different code, not the same code under different names \u2014 the matched region ends inside that line. Extract the lines above it, and read the last line of each site separately."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/src/SourceGenerators/Features.Generator/FeatureRegistrationGenerator.cs"},"region":{"startLine":296}}}],"partialFingerprints":{"codehealthFindingId/v1":"e0fa155924679a93cc89c1ddeea06e986eb8cb5aeae3a5959a3d77f81bc44a60"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (10 lines \u00D7 3): backend/src/Enduser/Enduser.Api/Adapters/Subscriptions/InMemorySubscriptionStore.cs:19-28 | backend/src/Master/Master.Api/Adapters/Subscriptions/InMemorySubscriptionStore.cs:19-28 | backend/src/Partner/Partner.Api/Adapters/Subscriptions/InMemorySubscriptionStore.cs:19-28 \u2014 before extracting anything, compare \u0060backend/src/Enduser/Enduser.Api/Adapters/Subscriptions/InMemorySubscriptionStore.cs\u0060 and \u0060backend/src/Master/Master.Api/Adapters/Subscriptions/InMemorySubscriptionStore.cs\u0060 as WHOLE FILES: this scan already matched 4 separate duplicated blocks between them, totalling at least 51 lines, which is the signature of one file having been copied from the other rather than of a helper waiting to be extracted. The two sit in different directories, so one cannot simply be deleted in favour of the other while both are reached separately: hoist the shared part into a location both already depend on and have each file call it, and retire whichever file turns out to have no caller of its own left. Extracting one helper per block leaves the fork in place. Read the line range as the matched WINDOW rather than a finished unit: at \u0060backend/src/Enduser/Enduser.Api/Adapters/Subscriptions/InMemorySubscriptionStore.cs:19\u0060 it does not close everything it opens, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/src/Enduser/Enduser.Api/Adapters/Subscriptions/InMemorySubscriptionStore.cs"},"region":{"startLine":19}}}],"partialFingerprints":{"codehealthFindingId/v1":"eb8e0da588e0032bdec1fcbecb8eeace97a72fefb28fe1fae67e7e2bc99ed2b5"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (10 lines \u00D7 3): backend/src/SourceGenerators/Features.Generator/FeatureRegistrationGenerator.cs:253-262 | backend/src/SourceGenerators/Features.Generator/FeatureRegistrationGenerator.cs:274-283 | backend/src/SourceGenerators/Features.Generator/FeatureRegistrationGenerator.cs:295-304 \u2014 all 3 copies are in the same file, so extract the block into one function there and call it from every one of those sites \u2014 resolving only two of them leaves the rest to drift apart the first time one is edited. Read the line range as the matched WINDOW rather than a finished unit: at \u0060backend/src/SourceGenerators/Features.Generator/FeatureRegistrationGenerator.cs:253\u0060 it does not close everything it opens, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/src/SourceGenerators/Features.Generator/FeatureRegistrationGenerator.cs"},"region":{"startLine":253}}}],"partialFingerprints":{"codehealthFindingId/v1":"d8ac46faf9a77d30f7fc95f2f0a6e5e60f1f79416c1e8736bfd352c75397d7b7"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (10 lines \u00D7 2): backend/src/Enduser/Enduser.Database/UserDisplayNameResolver.cs:24-33 | backend/src/Enduser/Enduser.Database/UserDisplayNameResolver.cs:73-82 \u2014 both copies are in the same file, so extract the block into one function there and call it from each site \u2014 the copies drift apart the first time only one of them is edited. Note that the copies do not run to the end of the range shown: their LAST lines are different code, not the same code under different names \u2014 the matched region ends inside that line. Extract the lines above it, and read the last line of each site separately."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/src/Enduser/Enduser.Database/UserDisplayNameResolver.cs"},"region":{"startLine":24}}}],"partialFingerprints":{"codehealthFindingId/v1":"fe0f26287db6f1692dd66f5b2d0b918aaaabcdf44b7c346961c7bfd24cd383af"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (10 lines \u00D7 2): backend/src/Master/Features/Partners/GetPartnerSupportRequests/Feature.cs:137-146 | backend/src/Partner/Features/Clients/GetClientSupportRequests/Feature.cs:137-146 \u2014 the copies span different directories, so extracting a shared function means choosing where it lives: put it somewhere both call sites can already reach \u2014 a location they all depend on today, or a new shared one if there is none \u2014 and call it from each site; until then, every change has to be made twice."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/src/Master/Features/Partners/GetPartnerSupportRequests/Feature.cs"},"region":{"startLine":137}}}],"partialFingerprints":{"codehealthFindingId/v1":"2c7262790a49c4f9abbfae600d03128bc95069a6bca085d67600daf2705dae1b"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (10 lines \u00D7 2): backend/src/Shared/Features/Features.Common/Validation/LocalizedTextValidation.cs:33-42 | backend/src/Shared/Features/Features.Common/Validation/LocalizedTextValidation.cs:62-71 \u2014 both copies are in the same file, so extract the block into one function there and call it from each site \u2014 the copies drift apart the first time only one of them is edited. Read the line range as the matched WINDOW rather than a finished unit: at \u0060backend/src/Shared/Features/Features.Common/Validation/LocalizedTextValidation.cs:33\u0060 it begins part-way through the construct above it, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/src/Shared/Features/Features.Common/Validation/LocalizedTextValidation.cs"},"region":{"startLine":33}}}],"partialFingerprints":{"codehealthFindingId/v1":"bed7810842a513f0ebb142204584c47995d3317951ff29eb3600cda9afaa4978"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9 lines \u00D7 2): backend/src/Enduser/Enduser.Database/Insight/DashboardDataEngine.cs:485-493 | backend/src/Enduser/Enduser.Database/Insight/DashboardDataEngine.cs:523-531 \u2014 both copies are in the same file, so extract the block into one function there and call it from each site \u2014 the copies drift apart the first time only one of them is edited. Read the line range as the matched WINDOW rather than a finished unit: at \u0060backend/src/Enduser/Enduser.Database/Insight/DashboardDataEngine.cs:485\u0060 it begins part-way through the construct above it, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/src/Enduser/Enduser.Database/Insight/DashboardDataEngine.cs"},"region":{"startLine":485}}}],"partialFingerprints":{"codehealthFindingId/v1":"c940edd1eba44d56841fe2061f0d9196a1532c7ab03211591f4af4b802de0243"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9 lines \u00D7 2): backend/src/Master/Features/Partners/GetResponsibleUsers/Feature.cs:98-106 | backend/src/Shared/Features/Company/GetOrganizationUsers/Feature.cs:100-108 \u2014 the copies span different directories, so extracting a shared function means choosing where it lives: put it somewhere both call sites can already reach \u2014 a location they all depend on today, or a new shared one if there is none \u2014 and call it from each site; until then, every change has to be made twice. Read the line range as the matched WINDOW rather than a finished unit: at \u0060backend/src/Master/Features/Partners/GetResponsibleUsers/Feature.cs:98\u0060 it does not close everything it opens, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/src/Master/Features/Partners/GetResponsibleUsers/Feature.cs"},"region":{"startLine":98}}}],"partialFingerprints":{"codehealthFindingId/v1":"cea1f7db9d3ec1fee25b9d6425dc9479bc3ec6820018b7b13dfb6461f77149ff"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9 lines \u00D7 2): backend/src/Partner/Partner.Database/Configurations/ApplicationConfiguration.cs:130-138 | backend/src/Partner/Partner.Database/Configurations/ApplicationConfiguration.cs:158-166 \u2014 both copies are in the same file, so extract the block into one function there and call it from each site \u2014 the copies drift apart the first time only one of them is edited. Read the line range as the matched WINDOW rather than a finished unit: at \u0060backend/src/Partner/Partner.Database/Configurations/ApplicationConfiguration.cs:130\u0060 it begins part-way through the construct above it, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/src/Partner/Partner.Database/Configurations/ApplicationConfiguration.cs"},"region":{"startLine":130}}}],"partialFingerprints":{"codehealthFindingId/v1":"ff60bf3e0de0f647ab68745bcc933cd533121ba55615d51e3c8bad786928558f"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9 lines \u00D7 2): backend/src/Partner/Partner.Database/Configurations/DataContextConfiguration.cs:43-51 | backend/src/Partner/Partner.Database/Configurations/DataContextConfiguration.cs:59-67 \u2014 both copies are in the same file, so extract the block into one function there and call it from each site \u2014 the copies drift apart the first time only one of them is edited. Read the line range as the matched WINDOW rather than a finished unit: at \u0060backend/src/Partner/Partner.Database/Configurations/DataContextConfiguration.cs:43\u0060 it begins part-way through the construct above it, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that. Note that the copies do not run to the end of the range shown: their LAST lines are different code, not the same code under different names \u2014 the matched region ends inside that line. Extract the lines above it, and read the last line of each site separately."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/src/Partner/Partner.Database/Configurations/DataContextConfiguration.cs"},"region":{"startLine":43}}}],"partialFingerprints":{"codehealthFindingId/v1":"813b26dbe08577dc9f74a6d9788444f3173bd2bc0a97e54d4934c754f9c2df06"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9 lines \u00D7 2): backend/src/Partner/Partner.Database/Configurations/TopicConfiguration.cs:79-87 | backend/src/Partner/Partner.Database/Configurations/TopicConfiguration.cs:107-115 \u2014 both copies are in the same file, so extract the block into one function there and call it from each site \u2014 the copies drift apart the first time only one of them is edited. Read the line range as the matched WINDOW rather than a finished unit: at \u0060backend/src/Partner/Partner.Database/Configurations/TopicConfiguration.cs:79\u0060 it begins part-way through the construct above it, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/src/Partner/Partner.Database/Configurations/TopicConfiguration.cs"},"region":{"startLine":79}}}],"partialFingerprints":{"codehealthFindingId/v1":"d67d2176af205220d1934a2a01365dc3828eeb10a1d325ddfc518df51cd5cb52"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (9 lines \u00D7 2): backend/src/Shared/Features/ActivityLog/GetActivityLogs/Feature.cs:97-106 | backend/src/Shared/Features/Notifications/GetMyNotifications/Feature.cs:85-93 \u2014 the copies span different directories, so extracting a shared function means choosing where it lives: put it somewhere both call sites can already reach \u2014 a location they all depend on today, or a new shared one if there is none \u2014 and call it from each site; until then, every change has to be made twice."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/src/Shared/Features/ActivityLog/GetActivityLogs/Feature.cs"},"region":{"startLine":97}}}],"partialFingerprints":{"codehealthFindingId/v1":"ea0714941c8e5dbe16ff26ef4e0848b5517dcd00efdcc3860d91793a47425079"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (8 lines \u00D7 3): backend/src/Enduser/Enduser.Api/Program.cs:569-576 | backend/src/Master/Master.Api/Program.cs:521-530 | backend/src/Partner/Partner.Api/Program.cs:552-561 \u2014 the copies span different directories, so extracting a shared function means choosing where it lives: put it somewhere all 3 call sites can already reach \u2014 a location they all depend on today, or a new shared one if there is none \u2014 and call it from each site; until then, every change has to be made 3 times. Read the line range as the matched WINDOW rather than a finished unit: at \u0060backend/src/Enduser/Enduser.Api/Program.cs:569\u0060 it does not close everything it opens, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/src/Enduser/Enduser.Api/Program.cs"},"region":{"startLine":569}}}],"partialFingerprints":{"codehealthFindingId/v1":"7d5d723d8eea44e2480a74c213039d0172d3f18c3d7ba6a96c19425865c9282d"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (8 lines \u00D7 3): backend/src/Shared/Features/Applications/GetActiveSurveyDispatches/Feature.cs:95-102 | backend/src/Shared/Features/Applications/GetSurveyByToken/Feature.cs:166-173 | backend/src/Shared/Features/Applications/GetSurveyResults/Feature.cs:162-169 \u2014 the copies span different directories, so extracting a shared function means choosing where it lives: put it somewhere all 3 call sites can already reach \u2014 a location they all depend on today, or a new shared one if there is none \u2014 and call it from each site; until then, every change has to be made 3 times. Read the line range as the matched WINDOW rather than a finished unit: at \u0060backend/src/Shared/Features/Applications/GetActiveSurveyDispatches/Feature.cs:95\u0060 it does not close everything it opens, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/src/Shared/Features/Applications/GetActiveSurveyDispatches/Feature.cs"},"region":{"startLine":95}}}],"partialFingerprints":{"codehealthFindingId/v1":"619ed2b32c53695efaec919b9f51535d45fef15fa1c3fd7ada9b63aa80ee6e9b"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (8 lines \u00D7 2): backend/src/Enduser/Enduser.Api/Services/SyncService.cs:116-123 | backend/src/Partner/Partner.Api/Services/SyncService.cs:108-115 \u2014 the copies span different directories, so extracting a shared function means choosing where it lives: put it somewhere both call sites can already reach \u2014 a location they all depend on today, or a new shared one if there is none \u2014 and call it from each site; until then, every change has to be made twice. Read the line range as the matched WINDOW rather than a finished unit: at \u0060backend/src/Enduser/Enduser.Api/Services/SyncService.cs:116\u0060 it begins part-way through the construct above it, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/src/Enduser/Enduser.Api/Services/SyncService.cs"},"region":{"startLine":116}}}],"partialFingerprints":{"codehealthFindingId/v1":"34ca9ff1ac441ef6f2da215831d3420fc3f4363e5842026ca5497b00ca22621a"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (8 lines \u00D7 2): backend/src/Partner/Partner.Database/Configurations/ClientConfiguration.cs:51-58 | backend/src/Partner/Partner.Database/Configurations/ClientConfiguration.cs:66-73 \u2014 both copies are in the same file, so extract the block into one function there and call it from each site \u2014 the copies drift apart the first time only one of them is edited. Read the line range as the matched WINDOW rather than a finished unit: at \u0060backend/src/Partner/Partner.Database/Configurations/ClientConfiguration.cs:51\u0060 it begins part-way through the construct above it, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/src/Partner/Partner.Database/Configurations/ClientConfiguration.cs"},"region":{"startLine":51}}}],"partialFingerprints":{"codehealthFindingId/v1":"c0a0a388cfbdf8c6833392d82b198ecdacc7726088f6a7cbc89dbf0735f6a55c"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 5): backend/src/Enduser/Enduser.Database/Configurations/KpiConfiguration.cs:48-54 | backend/src/Enduser/Enduser.Database/Configurations/KpiConfiguration.cs:64-70 | backend/src/Enduser/Enduser.Database/Configurations/KpiConfiguration.cs:93-99 | backend/src/Enduser/Enduser.Database/Configurations/KpiConfiguration.cs:107-113 | backend/src/Enduser/Enduser.Database/Configurations/KpiConfiguration.cs:155-162 \u2014 all 5 copies are in the same file, so extract the block into one function there and call it from every one of those sites \u2014 resolving only two of them leaves the rest to drift apart the first time one is edited. Read the line range as the matched WINDOW rather than a finished unit: at \u0060backend/src/Enduser/Enduser.Database/Configurations/KpiConfiguration.cs:48\u0060 it begins part-way through the construct above it, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that. Note that the copies do not run to the end of the range shown: their LAST lines are different code, not the same code under different names \u2014 the matched region ends inside that line. Extract the lines above it, and read the last line of each site separately."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/src/Enduser/Enduser.Database/Configurations/KpiConfiguration.cs"},"region":{"startLine":48}}}],"partialFingerprints":{"codehealthFindingId/v1":"0175d2f3bf73527ed315128191233a2190518febfdb215c4342e28437f85408d"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 3): backend/src/Enduser/Enduser.Database/Configurations/DataCollectionEntryConfiguration.cs:29-35 | backend/src/Enduser/Enduser.Database/Configurations/DataCollectionEntryConfiguration.cs:68-74 | backend/src/Enduser/Enduser.Database/Configurations/DataCollectionEntryConfiguration.cs:81-87 \u2014 all 3 copies are in the same file, so extract the block into one function there and call it from every one of those sites \u2014 resolving only two of them leaves the rest to drift apart the first time one is edited. Read the line range as the matched WINDOW rather than a finished unit: at \u0060backend/src/Enduser/Enduser.Database/Configurations/DataCollectionEntryConfiguration.cs:29\u0060 it begins part-way through the construct above it, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that. Note that the copies do not run to the end of the range shown: their LAST lines are different code, not the same code under different names \u2014 the matched region ends inside that line. Extract the lines above it, and read the last line of each site separately."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/src/Enduser/Enduser.Database/Configurations/DataCollectionEntryConfiguration.cs"},"region":{"startLine":29}}}],"partialFingerprints":{"codehealthFindingId/v1":"2c5369f5113c6e402027e5e4fa2c30f92fa29f89c09b5001d5f42811aee56939"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 2): backend/src/Enduser/Enduser.Database/Configurations/ElementInstanceConfiguration.cs:31-37 | backend/src/Enduser/Enduser.Database/Configurations/ElementInstanceConfiguration.cs:44-50 \u2014 both copies are in the same file, so extract the block into one function there and call it from each site \u2014 the copies drift apart the first time only one of them is edited. Read the line range as the matched WINDOW rather than a finished unit: at \u0060backend/src/Enduser/Enduser.Database/Configurations/ElementInstanceConfiguration.cs:31\u0060 it begins part-way through the construct above it, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that. Note that the copies do not run to the end of the range shown: their LAST lines are different code, not the same code under different names \u2014 the matched region ends inside that line. Extract the lines above it, and read the last line of each site separately."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/src/Enduser/Enduser.Database/Configurations/ElementInstanceConfiguration.cs"},"region":{"startLine":31}}}],"partialFingerprints":{"codehealthFindingId/v1":"f3fc00623e9943843f2df83a9293fddcdade7c4f1a28d9946915089d325f0ef4"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 2): backend/src/Enduser/Enduser.Database/Configurations/SyncedDataContextConfiguration.cs:60-66 | backend/src/Enduser/Enduser.Database/Configurations/SyncedDataContextConfiguration.cs:74-80 \u2014 both copies are in the same file, so extract the block into one function there and call it from each site \u2014 the copies drift apart the first time only one of them is edited. Read the line range as the matched WINDOW rather than a finished unit: at \u0060backend/src/Enduser/Enduser.Database/Configurations/SyncedDataContextConfiguration.cs:60\u0060 it begins part-way through the construct above it, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that. Note that the copies do not run to the end of the range shown: their LAST lines are different code, not the same code under different names \u2014 the matched region ends inside that line. Extract the lines above it, and read the last line of each site separately."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/src/Enduser/Enduser.Database/Configurations/SyncedDataContextConfiguration.cs"},"region":{"startLine":60}}}],"partialFingerprints":{"codehealthFindingId/v1":"c701563faf723bff422e044aaa8a59d66b21b0aa1980e66b7997ffa0b76de62a"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 2): backend/src/Enduser/Enduser.Database/Services/DataCollectionScheduler.cs:76-83 | backend/src/Enduser/Enduser.Database/Services/NotificationScheduler.cs:74-80 \u2014 the copies sit in sibling files of one directory: extract the block into a single shared function in that directory and call it from each site, so a change lands once."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/src/Enduser/Enduser.Database/Services/DataCollectionScheduler.cs"},"region":{"startLine":76}}}],"partialFingerprints":{"codehealthFindingId/v1":"7885afccb230cd5d07c185aade354b65340f281522df135a5a252de428868360"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 2): backend/src/Master/Master.Database/Configurations/PartnerConfiguration.cs:42-49 | backend/src/Master/Master.Database/Configurations/PartnerConfiguration.cs:57-63 \u2014 both copies are in the same file, so extract the block into one function there and call it from each site \u2014 the copies drift apart the first time only one of them is edited. Read the line range as the matched WINDOW rather than a finished unit: at \u0060backend/src/Master/Master.Database/Configurations/PartnerConfiguration.cs:42\u0060 it begins part-way through the construct above it, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/src/Master/Master.Database/Configurations/PartnerConfiguration.cs"},"region":{"startLine":42}}}],"partialFingerprints":{"codehealthFindingId/v1":"183e90345728dddb252b319c1af3b4d5de97f29f5d2b1a1fa697293c82273158"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 2): backend/src/Partner/Partner.Database/Configurations/InsightDashboardConfiguration.cs:50-56 | backend/src/Partner/Partner.Database/Configurations/InsightDashboardConfiguration.cs:63-69 \u2014 both copies are in the same file, so extract the block into one function there and call it from each site \u2014 the copies drift apart the first time only one of them is edited. Read the line range as the matched WINDOW rather than a finished unit: at \u0060backend/src/Partner/Partner.Database/Configurations/InsightDashboardConfiguration.cs:50\u0060 it begins part-way through the construct above it, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/src/Partner/Partner.Database/Configurations/InsightDashboardConfiguration.cs"},"region":{"startLine":50}}}],"partialFingerprints":{"codehealthFindingId/v1":"69a55e182377a313f794401250506d59ad628869994d83634a8ad06b4a03267c"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 2): backend/src/Partner/Features/Applications/GetApplications/Feature.cs:81-87 | backend/src/Partner/Features/Applications/GetApplications/Feature.cs:89-95 \u2014 both copies are in the same file, so extract the block into one function there and call it from each site \u2014 the copies drift apart the first time only one of them is edited. Read the line range as the matched WINDOW rather than a finished unit: at \u0060backend/src/Partner/Features/Applications/GetApplications/Feature.cs:81\u0060 it begins part-way through the construct above it, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/src/Partner/Features/Applications/GetApplications/Feature.cs"},"region":{"startLine":81}}}],"partialFingerprints":{"codehealthFindingId/v1":"65da0ff0ec087594ad22e8821a165d2049b9cb7b1da38c072f042755cb2b1f96"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 2): backend/src/Partner/Features/Applications/GetApplicationTopics/Feature.cs:98-104 | backend/src/Partner/Features/Applications/GetApplicationTopics/Feature.cs:106-112 \u2014 both copies are in the same file, so extract the block into one function there and call it from each site \u2014 the copies drift apart the first time only one of them is edited. Read the line range as the matched WINDOW rather than a finished unit: at \u0060backend/src/Partner/Features/Applications/GetApplicationTopics/Feature.cs:98\u0060 it begins part-way through the construct above it, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/src/Partner/Features/Applications/GetApplicationTopics/Feature.cs"},"region":{"startLine":98}}}],"partialFingerprints":{"codehealthFindingId/v1":"fc107f3b79ffed4ffffee58f880b9f49a80ebe8331dd89185b0e4d163c7b4ecd"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 2): backend/src/Partner/Features/Applications/GetTopicDetails/Feature.cs:130-136 | backend/src/Partner/Features/Applications/GetTopicDetails/Feature.cs:138-144 \u2014 both copies are in the same file, so extract the block into one function there and call it from each site \u2014 the copies drift apart the first time only one of them is edited. Read the line range as the matched WINDOW rather than a finished unit: at \u0060backend/src/Partner/Features/Applications/GetTopicDetails/Feature.cs:130\u0060 it begins part-way through the construct above it, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/src/Partner/Features/Applications/GetTopicDetails/Feature.cs"},"region":{"startLine":130}}}],"partialFingerprints":{"codehealthFindingId/v1":"367ca232a2a29fe30774fe7036fefa871a248a98b396f15a6a5ae52a2e5d32f3"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 2): backend/src/Partner/Features/Clients/GetClients/Feature.cs:59-65 | backend/src/Partner/Features/Clients/GetClients/Feature.cs:67-73 \u2014 both copies are in the same file, so extract the block into one function there and call it from each site \u2014 the copies drift apart the first time only one of them is edited. Read the line range as the matched WINDOW rather than a finished unit: at \u0060backend/src/Partner/Features/Clients/GetClients/Feature.cs:59\u0060 it begins part-way through the construct above it, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/src/Partner/Features/Clients/GetClients/Feature.cs"},"region":{"startLine":59}}}],"partialFingerprints":{"codehealthFindingId/v1":"853ac708c0a0d2c8910465bbd6b90062338a10011433b4e3173cb31a4052c14b"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (7 lines \u00D7 2): backend/src/Tools/TypeScriptClientGenerator/Core/ClientGenerator.cs:362-368 | backend/src/Tools/TypeScriptClientGenerator/Core/ClientGenerator.cs:378-384 \u2014 both copies are in the same file, so extract the block into one function there and call it from each site \u2014 the copies drift apart the first time only one of them is edited. Read the line range as the matched WINDOW rather than a finished unit: at \u0060backend/src/Tools/TypeScriptClientGenerator/Core/ClientGenerator.cs:362\u0060 it does not close everything it opens, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/src/Tools/TypeScriptClientGenerator/Core/ClientGenerator.cs"},"region":{"startLine":362}}}],"partialFingerprints":{"codehealthFindingId/v1":"916ad57f301b869f6d2e62c0ef593243714f4448ebeb28d019a58a4d781dbb7a"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2): backend/src/Enduser/Enduser.Database/Configurations/SyncedQuestionConfiguration.cs:33-40 | backend/src/Enduser/Enduser.Database/Configurations/SyncedQuestionConfiguration.cs:109-114 \u2014 both copies are in the same file, so extract the block into one function there and call it from each site \u2014 the copies drift apart the first time only one of them is edited. Read the line range as the matched WINDOW rather than a finished unit: at \u0060backend/src/Enduser/Enduser.Database/Configurations/SyncedQuestionConfiguration.cs:33\u0060 it begins part-way through the construct above it, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/src/Enduser/Enduser.Database/Configurations/SyncedQuestionConfiguration.cs"},"region":{"startLine":33}}}],"partialFingerprints":{"codehealthFindingId/v1":"40ca2eae7263402ef1ce4b30abd29cb7304bc88e7e72abd96139f8d79504f57f"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2): backend/src/Master/Master.Database/Configurations/DataContextConfiguration.cs:60-65 | backend/src/Master/Master.Database/Configurations/DataContextConfiguration.cs:80-85 \u2014 both copies are in the same file, so extract the block into one function there and call it from each site \u2014 the copies drift apart the first time only one of them is edited. Read the line range as the matched WINDOW rather than a finished unit: at \u0060backend/src/Master/Master.Database/Configurations/DataContextConfiguration.cs:60\u0060 it begins part-way through the construct above it, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/src/Master/Master.Database/Configurations/DataContextConfiguration.cs"},"region":{"startLine":60}}}],"partialFingerprints":{"codehealthFindingId/v1":"966ccb0cc37d72a378936dbf2d477b687f31b54274089a7f9ec49fbd07ff62f3"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2): backend/src/Partner/Partner.Database/Configurations/QuestionConfiguration.cs:103-108 | backend/src/Partner/Partner.Database/Configurations/QuestionConfiguration.cs:110-115 \u2014 both copies are in the same file, so extract the block into one function there and call it from each site \u2014 the copies drift apart the first time only one of them is edited. Read the line range as the matched WINDOW rather than a finished unit: at \u0060backend/src/Partner/Partner.Database/Configurations/QuestionConfiguration.cs:103\u0060 it begins part-way through the construct above it, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/src/Partner/Partner.Database/Configurations/QuestionConfiguration.cs"},"region":{"startLine":103}}}],"partialFingerprints":{"codehealthFindingId/v1":"e8bb6d8184f06f305273578c063a142dd54a984a1e616e1c8823fa6c6a4351d9"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2): backend/src/Shared/Features/Applications/SubmitAnswer/Feature.cs:394-399 | backend/src/Shared/Features/Applications/ConfirmActionRecommendations/Feature.cs:144-149 \u2014 the copies span different directories, so extracting a shared function means choosing where it lives: put it somewhere both call sites can already reach \u2014 a location they all depend on today, or a new shared one if there is none \u2014 and call it from each site; until then, every change has to be made twice. Read the line range as the matched WINDOW rather than a finished unit: at \u0060backend/src/Shared/Features/Applications/SubmitAnswer/Feature.cs:394\u0060 it does not close everything it opens, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/src/Shared/Features/Applications/SubmitAnswer/Feature.cs"},"region":{"startLine":394}}}],"partialFingerprints":{"codehealthFindingId/v1":"42313f0a731376eaab94649d70f1beb93605847e41c621ee4a1645255eafec9a"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2): backend/src/Shared/Features/MyTasks/GetPersonalTasks/Feature.cs:114-119 | backend/src/Shared/Features/MyTasks/GetPersonalTasks/Feature.cs:124-129 \u2014 both copies are in the same file, so extract the block into one function there and call it from each site \u2014 the copies drift apart the first time only one of them is edited. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/src/Shared/Features/MyTasks/GetPersonalTasks/Feature.cs"},"region":{"startLine":114}}}],"partialFingerprints":{"codehealthFindingId/v1":"fe177f479f9797cf54a348af24bfec6bd9026285a24aaf94add231b57ce61470"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2): backend/src/SourceGenerators/Features.Generator/Emitters/EndpointMappingEmitter.cs:90-95 | backend/src/SourceGenerators/Features.Generator/Emitters/EndpointMappingEmitter.cs:106-111 \u2014 both copies are in the same file, so extract the block into one function there and call it from each site \u2014 the copies drift apart the first time only one of them is edited. Read the line range as the matched WINDOW rather than a finished unit: at \u0060backend/src/SourceGenerators/Features.Generator/Emitters/EndpointMappingEmitter.cs:90\u0060 it does not close everything it opens, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/src/SourceGenerators/Features.Generator/Emitters/EndpointMappingEmitter.cs"},"region":{"startLine":90}}}],"partialFingerprints":{"codehealthFindingId/v1":"d0d00c7f772edc9a58235d20b8799991889bc0477bf850edf748b70b91c7eecb"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2): backend/src/Shared/Features/Applications/GetActionResults/Feature.cs:112-117 | backend/src/Shared/Features/Applications/GetActionResults/Feature.cs:118-123 \u2014 both copies are in the same file, so extract the block into one function there and call it from each site \u2014 the copies drift apart the first time only one of them is edited. Read the line range as the matched WINDOW rather than a finished unit: at \u0060backend/src/Shared/Features/Applications/GetActionResults/Feature.cs:112\u0060 it begins part-way through the construct above it, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/src/Shared/Features/Applications/GetActionResults/Feature.cs"},"region":{"startLine":112}}}],"partialFingerprints":{"codehealthFindingId/v1":"f046284621fdfce4e1d80bb21c3ee1d5cf884e65f8b722fe26288aeb580a2cec"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2): backend/src/Shared/Adapters/GitHub/GitHubClient.cs:91-96 | backend/src/Shared/Adapters/GitHub/GitHubClient.cs:104-109 \u2014 both copies are in the same file, so extract the block into one function there and call it from each site \u2014 the copies drift apart the first time only one of them is edited. Read the line range as the matched WINDOW rather than a finished unit: at \u0060backend/src/Shared/Adapters/GitHub/GitHubClient.cs:91\u0060 it does not close everything it opens, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that. The matched lines also transfer control out of the body holding them, which cannot survive a move into a called unit unchanged: have the extracted unit return that decision and let each site act on it."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/src/Shared/Adapters/GitHub/GitHubClient.cs"},"region":{"startLine":91}}}],"partialFingerprints":{"codehealthFindingId/v1":"90dbe861a898bc44c8ad09c702d5d0b11b4f91c8ab5b7e506d309ab65b3307f3"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (6 lines \u00D7 2): backend/src/Shared/Features/StrategicPlans/GetStrategicPlanStructure/Feature.cs:41-46 | backend/src/Shared/Features/StrategicPlans/GetStrategicPlanStructure/Feature.cs:48-53 \u2014 both copies are in the same file, so extract the block into one function there and call it from each site \u2014 the copies drift apart the first time only one of them is edited. Read the line range as the matched WINDOW rather than a finished unit: at \u0060backend/src/Shared/Features/StrategicPlans/GetStrategicPlanStructure/Feature.cs:41\u0060 it begins part-way through the construct above it, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/src/Shared/Features/StrategicPlans/GetStrategicPlanStructure/Feature.cs"},"region":{"startLine":41}}}],"partialFingerprints":{"codehealthFindingId/v1":"47f661ce648e828019ad6f5eaa61281cf874e31d4d53898c0c0adb33fce59906"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): backend/src/Enduser/Enduser.Database/Configurations/SyncedQuestionConfiguration.cs:51-55 | backend/src/Enduser/Enduser.Database/Configurations/SyncedQuestionConfiguration.cs:56-60 \u2014 both copies are in the same file, so extract the block into one function there and call it from each site \u2014 the copies drift apart the first time only one of them is edited. Read the line range as the matched WINDOW rather than a finished unit: at \u0060backend/src/Enduser/Enduser.Database/Configurations/SyncedQuestionConfiguration.cs:51\u0060 it begins part-way through the construct above it, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/src/Enduser/Enduser.Database/Configurations/SyncedQuestionConfiguration.cs"},"region":{"startLine":51}}}],"partialFingerprints":{"codehealthFindingId/v1":"b5f2d0770a9831a6c3089d656b5955fb7f16778b0031a27db5039109909316ac"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): backend/src/Enduser/Enduser.Database/Insight/TaskLoad.cs:359-363 | backend/src/Enduser/Enduser.Database/Insight/TaskLoad.cs:366-370 \u2014 both copies are in the same file, so extract the block into one function there and call it from each site \u2014 the copies drift apart the first time only one of them is edited. Read the line range as the matched WINDOW rather than a finished unit: at \u0060backend/src/Enduser/Enduser.Database/Insight/TaskLoad.cs:359\u0060 it begins part-way through the construct above it, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/src/Enduser/Enduser.Database/Insight/TaskLoad.cs"},"region":{"startLine":359}}}],"partialFingerprints":{"codehealthFindingId/v1":"5ed168109ecf7fb3bd7b5f31da589677f599ad217c562b43ac4d687e2502c8e9"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): backend/src/Shared/Features/MyTasks/GetApplicationTasks/Feature.cs:443-447 | backend/src/Shared/Features/MyTasks/GetApplicationTasks/Feature.cs:450-454 \u2014 both copies are in the same file, so extract the block into one function there and call it from each site \u2014 the copies drift apart the first time only one of them is edited. Read the line range as the matched WINDOW rather than a finished unit: at \u0060backend/src/Shared/Features/MyTasks/GetApplicationTasks/Feature.cs:443\u0060 it begins part-way through the construct above it, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/src/Shared/Features/MyTasks/GetApplicationTasks/Feature.cs"},"region":{"startLine":443}}}],"partialFingerprints":{"codehealthFindingId/v1":"178decbbd9112617ad416a1d8c825e01874a1a4cd6f73e94cadc2d4175d0f8d4"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): backend/src/Shared/Features/MyTasks/GetDataCollectionTasks/Feature.cs:122-126 | backend/src/Shared/Features/MyTasks/GetDataCollectionTasks/Feature.cs:132-136 \u2014 both copies are in the same file, so extract the block into one function there and call it from each site \u2014 the copies drift apart the first time only one of them is edited. Read the line range as the matched WINDOW rather than a finished unit: at \u0060backend/src/Shared/Features/MyTasks/GetDataCollectionTasks/Feature.cs:122\u0060 it begins part-way through the construct above it, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/src/Shared/Features/MyTasks/GetDataCollectionTasks/Feature.cs"},"region":{"startLine":122}}}],"partialFingerprints":{"codehealthFindingId/v1":"eeead87bdec46df51455a91ebe8d28ecab44785911b62347e0e2f6a0798d2ac9"}},{"ruleId":"D4","level":"warning","message":{"text":"Duplicated block (5 lines \u00D7 2): backend/src/Shared/Features/MyTasks/GetPersonalTasks/Feature.cs:47-51 | backend/src/Shared/Features/MyTasks/GetPersonalTasks/Feature.cs:58-62 \u2014 both copies are in the same file, so extract the block into one function there and call it from each site \u2014 the copies drift apart the first time only one of them is edited. Read the line range as the matched WINDOW rather than a finished unit: at \u0060backend/src/Shared/Features/MyTasks/GetPersonalTasks/Feature.cs:47\u0060 it begins part-way through the construct above it, so those exact lines cannot be lifted as they stand \u2014 widen the region to the smallest complete statement or declaration that contains it, and extract that."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/src/Shared/Features/MyTasks/GetPersonalTasks/Feature.cs"},"region":{"startLine":47}}}],"partialFingerprints":{"codehealthFindingId/v1":"4f7a0a41a26cbf30fbe1dfb18ee1f241ea2fd8d3701f8552d3c462512720a8d2"}},{"ruleId":"D5","level":"warning","message":{"text":"Off the main sequence: CsvParsing: CsvParsing: abstractness 0.00, instability 0.00, distance 1.00 \u2014 zone of pain \u2014 concrete and depended on by 6 project(s), so it\u0027s rigid to change."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"01b99ae3eef27a9d8b1aa03dc23eb0617fa2615ebaa6d8b5db39244b79318687"}},{"ruleId":"D5","level":"warning","message":{"text":"Off the main sequence: MessageBus: MessageBus: abstractness 0.00, instability 0.01, distance 0.99 \u2014 zone of pain \u2014 concrete and depended on by 237 project(s), so it\u0027s rigid to change."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"d69d1fa0f6ab5e7982846169aa60fe45ea139058af5e7980b41b938f60291215"}},{"ruleId":"D5","level":"warning","message":{"text":"Off the main sequence: Shared.Database.Configurations: Shared.Database.Configurations: abstractness 0.02, instability 0.01, distance 0.97 \u2014 the shape a shared-kernel / building-block library has BY DESIGN \u2014 concrete and widely depended-on is what makes it useful, and this dimension does not penalise it (the distance is reported for completeness, not as a defect). Worth a look only if it has grown past one coherent kernel into an everything-bucket."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"f432ede9cd476e7f5769bf9ac6ea7901a029138c1cb23ca41f749621d67ba09a"}},{"ruleId":"D5","level":"warning","message":{"text":"Off the main sequence: Enduser.Database: Enduser.Database: abstractness 0.00, instability 0.04, distance 0.96 \u2014 zone of pain \u2014 concrete and depended on by 128 project(s), so it\u0027s rigid to change."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"b04eecab7f10a0c88355500e6621633081ec2bb3546f70ce81912a7cb53eb20d"}},{"ruleId":"D5","level":"warning","message":{"text":"Off the main sequence: Enduser.Domains: Enduser.Domains: abstractness 0.06, instability 0.02, distance 0.93 \u2014 zone of pain \u2014 concrete and depended on by 129 project(s), so it\u0027s rigid to change."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"091c2c0a6728e2225600cd3fe60b2887e0ac4d49a40a305662420479465c0681"}},{"ruleId":"D5","level":"warning","message":{"text":"Off the main sequence: Partner.Database: Partner.Database: abstractness 0.00, instability 0.08, distance 0.92 \u2014 zone of pain \u2014 concrete and depended on by 70 project(s), so it\u0027s rigid to change."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"11bb59e856f2b8ff3c4620afe0cecd1f0ae39f52ef6e17383e415ae4e0bb5c5e"}},{"ruleId":"D5","level":"warning","message":{"text":"Off the main sequence: Master.Database: Master.Database: abstractness 0.00, instability 0.11, distance 0.89 \u2014 zone of pain \u2014 concrete and depended on by 47 project(s), so it\u0027s rigid to change."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"c3ac750b06ce7adf0418b155aceae33b68bcdf9430dd42e1be117d4e127f9e30"}},{"ruleId":"D5","level":"warning","message":{"text":"Off the main sequence: Authentication: Authentication: abstractness 0.00, instability 0.13, distance 0.88 \u2014 zone of pain \u2014 concrete and depended on by 7 project(s), so it\u0027s rigid to change."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"9a9cd4fdce696461c38509439592f38a54beda86f7e9665b270f68906bfc18f0"}},{"ruleId":"D5","level":"warning","message":{"text":"Off the main sequence: Email: Email: abstractness 0.00, instability 0.14, distance 0.86 \u2014 zone of pain \u2014 concrete and depended on by 6 project(s), so it\u0027s rigid to change."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"b062bd3280c1cd2551e0c3f2ed4f2246a09390921f30ab6bddf6c99c455787f9"}},{"ruleId":"D5","level":"warning","message":{"text":"Off the main sequence: Encryption: Encryption: abstractness 0.00, instability 0.14, distance 0.86 \u2014 zone of pain \u2014 concrete and depended on by 6 project(s), so it\u0027s rigid to change."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"6c3c892299315cef494c3401d8fc24000c27b3ffd44eb2b2c695d156500195f0"}},{"ruleId":"D5","level":"warning","message":{"text":"Off the main sequence: Middleware: Middleware: abstractness 0.00, instability 0.14, distance 0.86 \u2014 zone of pain \u2014 concrete and depended on by 6 project(s), so it\u0027s rigid to change."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"afad8b5e2693fd161130386ec4149cf0f3cf918d2e4ce347c9cb9648978e1a50"}},{"ruleId":"D5","level":"warning","message":{"text":"Off the main sequence: FileStorage: FileStorage: abstractness 0.00, instability 0.14, distance 0.86 \u2014 zone of pain \u2014 concrete and depended on by 6 project(s), so it\u0027s rigid to change."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"c79a97bbcbea122a9829148bb6ba6bb3452bf47943e7ee6898f369237841208e"}},{"ruleId":"D5","level":"warning","message":{"text":"Off the main sequence: Partner.Domains: Partner.Domains: abstractness 0.13, instability 0.03, distance 0.84 \u2014 zone of pain \u2014 concrete and depended on by 72 project(s), so it\u0027s rigid to change."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"ed48be37ba0c4cba4f5e687fff856bd43c10bb0b3606bd1dd306a22babe109cd"}},{"ruleId":"D5","level":"warning","message":{"text":"Off the main sequence: GitHub: GitHub: abstractness 0.17, instability 0.00, distance 0.83 \u2014 zone of pain \u2014 concrete and depended on by 7 project(s), so it\u0027s rigid to change."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"4e172d028e419c7381350d79de94a52f0b9d6302c2a41380af9dde1633027b78"}},{"ruleId":"D5","level":"warning","message":{"text":"Off the main sequence: Master.Domains: Master.Domains: abstractness 0.13, instability 0.04, distance 0.83 \u2014 zone of pain \u2014 concrete and depended on by 52 project(s), so it\u0027s rigid to change."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"490ad35577116502103c1037d7da603999eb09ed70d7a6098e54eb3d92075602"}},{"ruleId":"D5","level":"warning","message":{"text":"Off the main sequence: Partner.Features.Common: Partner.Features.Common: abstractness 0.00, instability 0.18, distance 0.82 \u2014 the shape a shared-kernel / building-block library has BY DESIGN \u2014 concrete and widely depended-on is what makes it useful, and this dimension does not penalise it (the distance is reported for completeness, not as a defect). Worth a look only if it has grown past one coherent kernel into an everything-bucket."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"1465cd5885994e43f74aed402f9bcb84bb792522809aa288781d9d4372663633"}},{"ruleId":"D5","level":"warning","message":{"text":"Off the main sequence: ParentSystem: ParentSystem: abstractness 0.00, instability 0.20, distance 0.80 \u2014 zone of pain \u2014 concrete and depended on by 4 project(s), so it\u0027s rigid to change."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"630ef78817c0c71ce6bdea01fe2981a918cffe65fc0f4c675501937c188644b2"}},{"ruleId":"D5","level":"warning","message":{"text":"Off the main sequence: Shared.Domains: Shared.Domains: abstractness 0.22, instability 0.00, distance 0.77 \u2014 the shape a shared-kernel / building-block library has BY DESIGN \u2014 concrete and widely depended-on is what makes it useful, and this dimension does not penalise it (the distance is reported for completeness, not as a defect). Worth a look only if it has grown past one coherent kernel into an everything-bucket."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"a674a95b4960ab83405862d79bb2ff15f3f9828bc1947c66d04d274f54678d53"}},{"ruleId":"D5","level":"warning","message":{"text":"Off the main sequence: Ports: Ports: abstractness 0.23, instability 0.00, distance 0.77 \u2014 zone of pain \u2014 concrete and depended on by 334 project(s), so it\u0027s rigid to change."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"dab403b4d2f7c029a547a67871659ec23e69186f800c0c237142c749ab72cae9"}},{"ruleId":"D10","level":"warning","message":{"text":"No assertions: ValidateUnitExists_accepts_unit_group_id_directly: Test method exercises code but verifies nothing \u2014 add an assertion."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/src/Master/Features/DataContexts/CreateDataContext/Tests.cs"},"region":{"startLine":442}}}],"partialFingerprints":{"codehealthFindingId/v1":"20378124e80c9aa0174485bba519a12ea13932cde2ee46cd4604e7a7ab5e2fbe"}},{"ruleId":"D10","level":"warning","message":{"text":"No assertions: ValidateUnitExists_accepts_member_unit_id: Test method exercises code but verifies nothing \u2014 add an assertion."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/src/Master/Features/DataContexts/CreateDataContext/Tests.cs"},"region":{"startLine":450}}}],"partialFingerprints":{"codehealthFindingId/v1":"8d24c5f3846bb9eee08548d4a5cc39c68f2c68c26bb675b6a3bfc36cc58381dd"}},{"ruleId":"D10","level":"warning","message":{"text":"No assertions: ValidateAndWire_allows_automated_root_action_without_parent: Test method exercises code but verifies nothing \u2014 add an assertion."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/src/Partner/Features/Questions/CreateQuestion/Tests.cs"},"region":{"startLine":408}}}],"partialFingerprints":{"codehealthFindingId/v1":"ba2321bd13ae22009c17ca7ac17875c20192437c840ded96613af648f0425784"}},{"ruleId":"D10","level":"warning","message":{"text":"No assertions: EnsureCanWriteAsync_is_no_op_when_resolver_allows: Test method exercises code but verifies nothing \u2014 add an assertion."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/test/Shared.Tests/ObjectAuthzTests.cs"},"region":{"startLine":41}}}],"partialFingerprints":{"codehealthFindingId/v1":"caf8a82a17e6f897c307eb92c7082a6b50778c978b08e512b4b098f5270ff9f8"}},{"ruleId":"D10","level":"warning","message":{"text":"No assertions: EnsureCanReadAsync_allows_when_user_has_read_grant: Test method exercises code but verifies nothing \u2014 add an assertion."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/test/Shared.Tests/ObjectAuthzTests.cs"},"region":{"startLine":93}}}],"partialFingerprints":{"codehealthFindingId/v1":"80eb4eb454e500748841dfc3e48323ca7c3181c47b4e6c8e30b264e75bce534a"}},{"ruleId":"D10","level":"warning","message":{"text":"No assertions: EnsureCanReadAsync_with_requestInfo_allows_when_user_has_read_grant: Test method exercises code but verifies nothing \u2014 add an assertion."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/test/Shared.Tests/ObjectAuthzTests.cs"},"region":{"startLine":141}}}],"partialFingerprints":{"codehealthFindingId/v1":"bf0eb4dc41a960ab1c0bf0096cc5ce05b207301c5a15fe1b14bc7d2c215a7aea"}},{"ruleId":"D10","level":"warning","message":{"text":"No assertions: Allows_demoting_admin_when_two_or_more_active_admins_exist: Test method exercises code but verifies nothing \u2014 add an assertion."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/test/Shared.Tests/LastAdminGuardTests.cs"},"region":{"startLine":50}}}],"partialFingerprints":{"codehealthFindingId/v1":"ad4042a8bc0ca45cf20ffbd6f128d0b24ba04c568ed265e86cce3d2a70cbf04f"}},{"ruleId":"D10","level":"warning","message":{"text":"No assertions: Non_admin_member_is_a_no_op: Test method exercises code but verifies nothing \u2014 add an assertion."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/test/Shared.Tests/LastAdminGuardTests.cs"},"region":{"startLine":108}}}],"partialFingerprints":{"codehealthFindingId/v1":"311ff23ab622529faa4819a1a400b0dcf1c3ceb9316ef0d830ff87618a53daed"}},{"ruleId":"D11","level":"warning","message":{"text":"Test reliability not measured \u2014 no test run produced results: Test reliability NOT MEASURED: the test run produced no results for any test tier, so no test ever ran and flakiness could not be exercised. The cause could not be attributed, so it is excluded from the score rather than read as an absence of tests."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"7d83a505f7fa19aeeece76141ae1e468d77e2a3fea2e88604b8140ebad47a6fe"}},{"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":"b6130a4f18637687944b88ecd5e5ef2eee95bcb4e7fc6485523f390cbbedf4de"},"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"}}]},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: frontend/apps/enduser/src/features/insight/insightAdapter.ts: frontend/apps/enduser/src/features/insight/insightAdapter.ts changed 31 times in last 90 days, max complexity 46. 1 of those changes was a fix/bug commit, and the other 30 changed it for other reasons \u2014 this file is under both repair and feature pressure. Before the next change lands here, cover the area it touches with tests, then split that area out of the file so the following change is smaller than this one \u2014 a file this often edited pays the complexity back every time."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"frontend/apps/enduser/src/features/insight/insightAdapter.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"98062e9035fe8b05718d57e510cc92fcc95d88db877129e073099463b726cc3b"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: frontend/apps/partner/src/features/insight/insight-dashboard-detail/components/ComponentConfigSheet.tsx: frontend/apps/partner/src/features/insight/insight-dashboard-detail/components/ComponentConfigSheet.tsx changed 49 times in last 90 days, max complexity 25. 8 of those changes were fix/bug commits, and the other 41 changed it for other reasons \u2014 this file is under both repair and feature pressure. Before the next change lands here, cover the area it touches with tests, then split that area out of the file so the following change is smaller than this one \u2014 a file this often edited pays the complexity back every time."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"frontend/apps/partner/src/features/insight/insight-dashboard-detail/components/ComponentConfigSheet.tsx"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"aa20f79f623725997221115cbe2f9b78d44aef60309c524b25f3182ec1da84d5"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: backend/src/Enduser/Enduser.Database/Insight/DashboardDataEngine.cs: backend/src/Enduser/Enduser.Database/Insight/DashboardDataEngine.cs changed 49 times in last 90 days, max complexity 21. 6 of those changes were fix/bug commits, and the other 43 changed it for other reasons \u2014 this file is under both repair and feature pressure. Before the next change lands here, cover the area it touches with tests, then split that area out of the file so the following change is smaller than this one \u2014 a file this often edited pays the complexity back every time."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/src/Enduser/Enduser.Database/Insight/DashboardDataEngine.cs"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"af41b7cb487ad725ef1ed80fdc74578457c4b196cf4a3777de145680d0e0d8a4"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: frontend/apps/partner/src/features/insight/insight-dashboard-detail/insightAdapter.ts: frontend/apps/partner/src/features/insight/insight-dashboard-detail/insightAdapter.ts changed 24 times in last 90 days, max complexity 25. 2 of those changes were fix/bug commits, and the other 22 changed it for other reasons \u2014 this file is under both repair and feature pressure. Before the next change lands here, cover the area it touches with tests, then split that area out of the file so the following change is smaller than this one \u2014 a file this often edited pays the complexity back every time."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"frontend/apps/partner/src/features/insight/insight-dashboard-detail/insightAdapter.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"7143cb2284c73bfc0a46e35d194e0ae401aef9b8a963bed6a1aef2687a1d932a"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: frontend/apps/enduser/src/features/insight/components/ComponentSettingsDrawer.tsx: frontend/apps/enduser/src/features/insight/components/ComponentSettingsDrawer.tsx changed 23 times in last 90 days, max complexity 23. 2 of those changes were fix/bug commits, and the other 21 changed it for other reasons \u2014 this file is under both repair and feature pressure. Before the next change lands here, cover the area it touches with tests, then split that area out of the file so the following change is smaller than this one \u2014 a file this often edited pays the complexity back every time."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"frontend/apps/enduser/src/features/insight/components/ComponentSettingsDrawer.tsx"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"b832fbd21a7bf6d3f4e17bcd97f95c02fe049389e8295dd0132d077746280bb3"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: frontend/apps/enduser/src/features/elements/element-type-details/components/ElementItemSheet.tsx: frontend/apps/enduser/src/features/elements/element-type-details/components/ElementItemSheet.tsx changed 24 times in last 90 days, max complexity 15. 8 of those changes were fix/bug commits, and the other 16 changed it for other reasons \u2014 this file is under both repair and feature pressure. Before the next change lands here, cover the area it touches with tests, then split that area out of the file so the following change is smaller than this one \u2014 a file this often edited pays the complexity back every time."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"frontend/apps/enduser/src/features/elements/element-type-details/components/ElementItemSheet.tsx"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"da1f99321d78a095eb6c0df50d06baa5d4b44f61c2bff3c6dadaf4d96e3c4005"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: frontend/apps/enduser/src/features/applications/run-application/components/steps/ResultStep.tsx: frontend/apps/enduser/src/features/applications/run-application/components/steps/ResultStep.tsx changed 21 times in last 90 days, max complexity 17. 4 of those changes were fix/bug commits, and the other 17 changed it for other reasons \u2014 this file is under both repair and feature pressure. Before the next change lands here, cover the area it touches with tests, then split that area out of the file so the following change is smaller than this one \u2014 a file this often edited pays the complexity back every time."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"frontend/apps/enduser/src/features/applications/run-application/components/steps/ResultStep.tsx"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"cbb9b9815670704b6d690fceb59fe5618d828a0bc168aa5b4e19d3fa56eae80b"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: frontend/apps/enduser/src/features/insight/components/InsightDashboardDetailView.tsx: frontend/apps/enduser/src/features/insight/components/InsightDashboardDetailView.tsx changed 19 times in last 90 days, max complexity 17. 2 of those changes were fix/bug commits, and the other 17 changed it for other reasons \u2014 this file is under both repair and feature pressure. Before the next change lands here, cover the area it touches with tests, then split that area out of the file so the following change is smaller than this one \u2014 a file this often edited pays the complexity back every time."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"frontend/apps/enduser/src/features/insight/components/InsightDashboardDetailView.tsx"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"0f9a8985fe926a2adab3adcecb794394b57d707b6efd8b23d8ca768fb4086a39"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: backend/src/Partner/Partner.Api/Endpoints/SyncEndpoints.cs: backend/src/Partner/Partner.Api/Endpoints/SyncEndpoints.cs changed 20 times in last 90 days, max complexity 15. 3 of those changes were fix/bug commits, and the other 17 changed it for other reasons \u2014 this file is under both repair and feature pressure. Before the next change lands here, cover the area it touches with tests, then split that area out of the file so the following change is smaller than this one \u2014 a file this often edited pays the complexity back every time."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/src/Partner/Partner.Api/Endpoints/SyncEndpoints.cs"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"63092f4a65630e84bb74eb13db31ff830d50865df97af4b8d8853396c1f3cc0a"}},{"ruleId":"D15","level":"warning","message":{"text":"Hotspot: frontend/apps/partner/src/features/applications/question-editor/question-actions/state.ts: frontend/apps/partner/src/features/applications/question-editor/question-actions/state.ts changed 6 times in last 90 days, max complexity 50. 2 of those changes were fix/bug commits, and the other 4 changed it for other reasons \u2014 this file is under both repair and feature pressure. Before the next change lands here, cover the area it touches with tests, then split that area out of the file so the following change is smaller than this one \u2014 a file this often edited pays the complexity back every time."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"frontend/apps/partner/src/features/applications/question-editor/question-actions/state.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"991cba9c98b246cb3749617d950ec57d18ac96d8f6b14753b2ee381c05f40599"}},{"ruleId":"D16","level":"note","message":{"text":"Off-boarding risk: anonymized user #1: If anonymized user #1 becomes unavailable, 41 significant file(s) lose their only recent owner: backend/src/Shared/Features/Auth/RedeemInvitation/Feature.cs, backend/src/Shared/Adapters/MessageBus/OutboxCleanupService.cs, backend/src/Partner/Features/Applications/GetApplicationTopics/Feature.cs, backend/src/Shared/Features/GetMe/Feature.cs, backend/src/Shared/Database/Shared.Database.Configurations/BaseDbContext.cs, backend/src/Shared/Database/Shared.Database.Configurations/UserLifecycleService.cs, backend/src/Master/Features/Tags/GetTagDetails/Feature.cs, backend/src/Shared/Adapters/MessageBus/PostgresNotificationBus.cs (\u002B33 more). Pair on, review, or document these before any departure."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"dab4da11658e43c14d5a1125771ae60812f9a9baa28fc94437859c210d60a9ba"}},{"ruleId":"D16","level":"note","message":{"text":"Off-boarding risk: anonymized user #2: If anonymized user #2 becomes unavailable, 14 significant file(s) lose their only recent owner: backend/src/Enduser/Enduser.Database/Insight/DashboardDataEngine.cs, backend/src/Enduser/Enduser.Database/Insight/TaskMetrics.cs, backend/src/Enduser/Enduser.Database/Insight/TaskLoad.cs, backend/src/Enduser/Enduser.Database/Insight/TaskScope.cs, backend/src/Shared/Features/Insight/GetMyDashboard/Feature.cs, backend/src/Enduser/Enduser.Domains/SyncedUnitGroups/UnitConversionService.cs, backend/src/Shared/Features/Insight/GetMyDashboards/Feature.cs, backend/src/Partner/Features/Insight/UpdateInsightDashboard/Feature.cs (\u002B6 more). Pair on, review, or document these before any departure."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"ff71e4e86cce54c19ab050eea0bae5f3b17ed4f581a558462ef5a411c8b8f8ff"}},{"ruleId":"D16","level":"note","message":{"text":"Off-boarding risk: anonymized user #3: If anonymized user #3 becomes unavailable, 13 significant file(s) lose their only recent owner: backend/src/Shared/Features/Imports/ElementImportProcessor/ElementImportProcessor.cs, backend/src/Shared/Features/ActivityLog/GetActivityLogs/Feature.cs, backend/src/Master/Features/Sync/SyncEndpoints.Support.cs, backend/src/Shared/Features/Applications/GetSurveyByToken/Feature.cs, backend/src/Shared/Adapters/Encryption/AesGcmEncryptionService.cs, backend/src/Shared/Features/Kpis/GetKpiDetails/CronHumanizer.cs, backend/src/Partner/Features/Clients/AcceptClientInvitation/Feature.cs, backend/src/Partner/Features/Clients/AcceptInvitation/Feature.cs (\u002B5 more). Pair on, review, or document these before any departure."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"016d607a9d0310334e68bdf955318232ab8d7fb2eb53984ac5bdab7782df3666"}},{"ruleId":"D17","level":"error","message":{"text":"NoWarnInCsproj: CS1591 \u2014 this warning is switched off for the WHOLE project, in every file it builds, including code written years from now: nothing at the call site records that the rule was ever silenced, so the next reader has no reason to look here. Fix what the rule is reporting and drop the code from the list, or \u2014 if some occurrences really are legitimate \u2014 narrow the suppression to those sites and give each one its reason, so the rule keeps protecting the rest of the project."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/Directory.Build.props"},"region":{"startLine":23}}}],"partialFingerprints":{"codehealthFindingId/v1":"3c8d3e6a1b6677a6435da73abab86ca2f2643c34ff17dc71e1674ef0ab0ff68f"}},{"ruleId":"D17","level":"error","message":{"text":"NoWarnInCsproj: CS1573 \u2014 this warning is switched off for the WHOLE project, in every file it builds, including code written years from now: nothing at the call site records that the rule was ever silenced, so the next reader has no reason to look here. Fix what the rule is reporting and drop the code from the list, or \u2014 if some occurrences really are legitimate \u2014 narrow the suppression to those sites and give each one its reason, so the rule keeps protecting the rest of the project."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/Directory.Build.props"},"region":{"startLine":23}}}],"partialFingerprints":{"codehealthFindingId/v1":"991c0681dd1d523c09cc7cd90adde9bcd671040e8634e5a52c80a3edf39de3ec"}},{"ruleId":"D17","level":"error","message":{"text":"NoWarnInCsproj: CS1570 \u2014 this warning is switched off for the WHOLE project, in every file it builds, including code written years from now: nothing at the call site records that the rule was ever silenced, so the next reader has no reason to look here. Fix what the rule is reporting and drop the code from the list, or \u2014 if some occurrences really are legitimate \u2014 narrow the suppression to those sites and give each one its reason, so the rule keeps protecting the rest of the project."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/Directory.Build.props"},"region":{"startLine":23}}}],"partialFingerprints":{"codehealthFindingId/v1":"f53f7fdd94f9eb935dba2bd93529a80f79e6303d6193dc9c9042e12a7821ee0b"}},{"ruleId":"D17","level":"error","message":{"text":"NoWarnInCsproj: CS1587 \u2014 this warning is switched off for the WHOLE project, in every file it builds, including code written years from now: nothing at the call site records that the rule was ever silenced, so the next reader has no reason to look here. Fix what the rule is reporting and drop the code from the list, or \u2014 if some occurrences really are legitimate \u2014 narrow the suppression to those sites and give each one its reason, so the rule keeps protecting the rest of the project."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/Directory.Build.props"},"region":{"startLine":23}}}],"partialFingerprints":{"codehealthFindingId/v1":"47819c815334272b5c44c3ea74a85de4cefefce921056ca5fdf78364fa2ff40f"}},{"ruleId":"D17","level":"error","message":{"text":"NoWarnInCsproj: CS1574 \u2014 this warning is switched off for the WHOLE project, in every file it builds, including code written years from now: nothing at the call site records that the rule was ever silenced, so the next reader has no reason to look here. Fix what the rule is reporting and drop the code from the list, or \u2014 if some occurrences really are legitimate \u2014 narrow the suppression to those sites and give each one its reason, so the rule keeps protecting the rest of the project."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/Directory.Build.props"},"region":{"startLine":23}}}],"partialFingerprints":{"codehealthFindingId/v1":"ab930f45ef8913b44f39a318b20f666bef588732c9eb062a4b57de66709e0c2a"}},{"ruleId":"D19","level":"note","message":{"text":"The three-tier table lists Master, Partner, Enduser but does not explain how the Partner connects to Master or what happens after invitation sync.: Add a brief \u0027Sync flow\u0027 section describing the invitation-code connection and data dictionary synchronization between Master and Partner."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/architecture/three-systems.md"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"fc9a1d1e7159f81f8159c98fe3dbcab2c8616cc5c0961c5e45ad621fdcd22fcc"}},{"ruleId":"D19","level":"note","message":{"text":"The three-tier table does not mention the data-modeling layer (Master\u0027s Data Collection \u0026 Taxonomy) or how it is consumed by Partner and Enduser.: Add a sentence noting that Master defines the data model, which both Partner and Enduser consume."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"docs/architecture/three-systems.md"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"20a154f96d2f78d9c8bb647dec58c7fbed4af08b37102e03c4241f212f7aee1e"}},{"ruleId":"D19","level":"note","message":{"text":"The body of this README is a deployment diagram with no description of the Everdue application itself (features, data models, endpoints).: Add an overview section covering the main features and the data structures that drive them."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"README.md"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"093cceff376fed1dae4eb22f4bd3b40659ea7342868a58823405f29c25a28f06"}},{"ruleId":"D19","level":"note","message":{"text":"No architecture or API documentation for the core Everdue application.: Document the primary endpoints, request/response shapes, and any shared models used by the system."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"README.md"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"7991f6ec518bba4e1169832f0be648725e0309dc69f10343c8a6712d0c4ef8b4"}},{"ruleId":"D19","level":"note","message":{"text":"The feature-store example uses interface MyFeatureState with an initial value, but no guidance on deriving the default from the type.: Add a sentence explaining how to set the default value in the createStore initializer based on the type."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"apps/master/src/shared/store/README.md"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"533849e3d737c59b66b10ce8a477a02239422c8d3d2b4570ed65aab4ab271d4b"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type DataContextMessage (Master \u2192 Partner): DataContextMessage (context Master) is exposed in Partner\u0027s public surface via Feature.Handle \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"9ed3decea93c3bfb0c83195813b8ea44892fd0b3649f256334f55381bb36aecc"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type ElementMessage (Master \u2192 Partner): ElementMessage (context Master) is exposed in Partner\u0027s public surface via Feature.Handle \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"c8e6b9c8b601e8e42b33881f33c19db9fb4e8e795bcfeedb072910ed70b6e2ca"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type TagMessage (Master \u2192 Partner): TagMessage (context Master) is exposed in Partner\u0027s public surface via Feature.Handle \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"b585fa3526e5b443ca63de8ea852fa6b6a880b60cf4dd9925955a6cd0150987b"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type PartnerBrandingChangedMessage (Partner \u2192 Shared): PartnerBrandingChangedMessage (context Partner) is exposed in Shared\u0027s public surface via Feature.Handle \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"da2c7144b67293ab70aecbe3b791c07485baa86aa4c8be5069478217c4ffc897"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type ApplicationAssignmentChangedMessage (Enduser \u2192 Shared): ApplicationAssignmentChangedMessage (context Enduser) is exposed in Shared\u0027s public surface via Feature.Handle \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"8bbc1193580b833496775d5d40de4de3865901da2bea3f8b4e41c49fe191c1f1"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type SurveyInvitationConsumedMessage (Enduser \u2192 Shared): SurveyInvitationConsumedMessage (context Enduser) is exposed in Shared\u0027s public surface via Feature.Handle \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"fbee98ae66ccc483bd34b71873910ae8f0e62769555d12302b0bb014a642b7b3"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type PartnerBrandingChangedMessage (Enduser \u2192 Shared): PartnerBrandingChangedMessage (context Enduser) is exposed in Shared\u0027s public surface via Feature.Handle \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"8bcc1ba4a623c6f6c5075396897ee95aef45452951822aba89dccd3bb387a853"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type ElementInstanceMessage (Enduser \u2192 Shared): ElementInstanceMessage (context Enduser) is exposed in Shared\u0027s public surface via Feature.Handle \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"d61b5929e41d6311c102c2eb3c6517ba36410f1cfab1a56ac4e8da1f348e3c66"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type ElementOwnershipChangedMessage (Enduser \u2192 Shared): ElementOwnershipChangedMessage (context Enduser) is exposed in Shared\u0027s public surface via Feature.Handle \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"372a05ad61b7baa2293f1a4bc66ecb11e0dac59a95c2311e1ebe18a3d4455abc"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type ImportOptions (Enduser \u2192 Shared): ImportOptions (context Enduser) is exposed in Shared\u0027s public surface via Request.Options \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"5a75a72e90124cfb50c7b233bcd2045dc87bf1c5f9ad288b612562584ce97d8d"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type ImportMapping (Enduser \u2192 Shared): ImportMapping (context Enduser) is exposed in Shared\u0027s public surface via ImportProfileDto.Mapping \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"f6334c98045881be6b1c8603cf509f92e7e0b12e1bbe61bc944d75bd41f2996b"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type ImportMapping (Enduser \u2192 Shared): ImportMapping (context Enduser) is exposed in Shared\u0027s public surface via Request.Mapping \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"82eddef032000eb96767305c6ced72d09d6cd3fe98e42d31a877837202625aac"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type OperationalEntityUpdatedMessage (Enduser \u2192 Shared): OperationalEntityUpdatedMessage (context Enduser) is exposed in Shared\u0027s public surface via Feature.Handle \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"b1d1edcc5cbc104efcd5588a9712b1968dd3d574f0359d7d7e0260cc10db8f27"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type DataCollectionEntryMessage (Enduser \u2192 Shared): DataCollectionEntryMessage (context Enduser) is exposed in Shared\u0027s public surface via Feature.Handle \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"eef7b1fd89dc9bee98debe030f71c807474b245998214fcc629f9e18e702ad9c"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type OperationalTaskUpdatedMessage (Enduser \u2192 Shared): OperationalTaskUpdatedMessage (context Enduser) is exposed in Shared\u0027s public surface via Feature.Handle \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"f9438feb2adb7e3a28bce2972fe59fcd8c63df98f0fcef06659e425379ee44b2"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type PersonalTaskMessage (Enduser \u2192 Shared): PersonalTaskMessage (context Enduser) is exposed in Shared\u0027s public surface via Feature.Handle \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"19aed988184b380ee58da4453a23a1734cee03ff1444d12469fe1209208ed4d1"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type NotificationPreferencesChangedMessage (Enduser \u2192 Shared): NotificationPreferencesChangedMessage (context Enduser) is exposed in Shared\u0027s public surface via Feature.Handle \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"fddb4dfe8e6289e2e76cd755d866c48f1c11d9a012d995f59d257716dd181cbf"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type NotificationMessage (Enduser \u2192 Shared): NotificationMessage (context Enduser) is exposed in Shared\u0027s public surface via Feature.Handle \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"d5544a9eb3bd301ed4f556df677a0b92e55f9283b274860d45ed4833e5e7bca1"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type ImportRowResult (Enduser \u2192 Shared): ImportRowResult (context Enduser) is exposed in Shared\u0027s public surface via DryRunOutcome..ctor \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"a0fb354e1a63792d55df6f670bc5c0a113b24c2085a616786fa685cfcadba1ab"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type ImportRowResult (Enduser \u2192 Shared): ImportRowResult (context Enduser) is exposed in Shared\u0027s public surface via DryRunOutcome.Results \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"eb6af5182a6d793505352b7bcb25d7577fa0a19a885bfa8396345637a642387a"}},{"ruleId":"D23","level":"warning","message":{"text":"Cross-context type ImportRowResult (Enduser \u2192 Shared): ImportRowResult (context Enduser) is exposed in Shared\u0027s public surface via DryRunOutcome.Deconstruct \u2014 couples the contexts."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"eabfe5e157e6af2f37dd73919a01cdd89659e3646ebdb9d21ac1c50b86d5c04a"}},{"ruleId":"D26","level":"note","message":{"text":"Split Enduser.Domains: Generic \u0027Domains\u0027 name with 46 namespaces is a sprawling grab-bag that should be split by concern. Suggested: by namespace: Enduser.Catalog, Enduser.Inventory, Enduser.Orders"},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"792aebd457a7432b9cb7fc853a4fa68fc3efa449d7006e761619f738ae30fca9"}},{"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":"41dab7ff614f4a06d29603bc4afb7720ac43d5358c4ead3fc6facdc751cf0501"}},{"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":"d5b8f11381d61a58459ffc7c595fd52d09c03c711894a63a9578043d2338412b"},"taxa":[{"id":"CWE-829","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"8741d64f348ab4ee677b78d2fc97de70b51ff97c4cb17f08c32178684f00ac6f"},"taxa":[{"id":"CWE-78","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"aa808ba30726e348beea0ac849bd67008fd3155c0f557244e02c65ff142aaf39"},"taxa":[{"id":"CWE-78","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"e84d2d19946ef02ef03bc1a63539cec2d7caf89c5862658eb7eb10585ee64363"},"taxa":[{"id":"CWE-78","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"28847bfb68128ad6c95eb6a19a3df3a0787d1bdadcf090baba24802b8a233364"},"taxa":[{"id":"CWE-732","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"7fc8dc0913cb528c07574d569df734b2a98cc3e482d7dc08c013c70f41b4054e"},"taxa":[{"id":"CWE-732","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"40eacf4c9661dde5370cef87da9c1e9ecbd3e4c37321ed6a3eee0061349745e5"},"taxa":[{"id":"CWE-78","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"7468c19daf204c26657ac4b30d36152ef37708535648662ace5c7e9be0701507"},"taxa":[{"id":"CWE-78","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"27f914b41c341c632b055152b8714c1735f93320ea3dbebb34da43e85ea82a4b"},"taxa":[{"id":"CWE-1357","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}},{"id":"CWE-353","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"0e1629f4dfe0bc23cf95a738590d356e1b34fdc809edee6992bad0064901bc2a"},"taxa":[{"id":"CWE-78","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"9838f9710342f875aa7ac47b108abcbb84ea20a89550d3cee1e68532b2ceb8a7"},"taxa":[{"id":"CWE-78","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"4717c49721d25fe4886727ac0e86973fb65657b6c5a1fa85d2b1b4bd797ba454"},"taxa":[{"id":"CWE-78","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"bf16937f441728305729bf3afb2b725b53d4405ae5ccbce3437be66277ae5a96"},"taxa":[{"id":"CWE-78","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"f1b966c70d2e5f6ab697ac6d268d54938c60e802d8ea58ea6ff9cb7e10a35f70"},"taxa":[{"id":"CWE-78","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"warning","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"574d389800f4af9187bfb9f67415b7ddecd768372e82125f76ace7fce11217bd"},"taxa":[{"id":"CWE-345","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"warning","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"fd9c2e57ed19b9a9304e80645ed61fb60e9f71cf2aa789d78e9b482021b1ecf4"},"taxa":[{"id":"CWE-345","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"warning","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"572743c8c85cb6eba0719a356749a2f4d60bb476b962187807e03530bdf1de42"},"taxa":[{"id":"CWE-345","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"note","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"dd52c4698b6730a148590949176ad8667b3ced2ef7aa13df46d8f0d50bd8cfde"},"taxa":[{"id":"CWE-290","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"note","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"ad328b12b61d437f53a3683a3704ce6913703526565e1316f9e9d59f95f66a6e"},"taxa":[{"id":"CWE-290","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"note","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"12efb5a5bb35e22ac003a5954298d749812f9d9ae49e2972e2e0f7a2a9a05654"},"taxa":[{"id":"CWE-290","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"note","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"b0b57f81063fbd5f74d0f599193f761c31d78591317644cd2ecec62e483419eb"},"taxa":[{"id":"CWE-290","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"note","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"294041a70c918bef4e5626bc2c940a55839ac8ccdbe455c2605613a5caa541ea"},"taxa":[{"id":"CWE-290","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"note","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"fdb4647b47185e56f2395eae14eb321fb50245613955e6026b0b14c8d1c00710"},"taxa":[{"id":"CWE-290","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"note","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"d028e7631e9b6044b95a7ce0941899f8d309c21f0c5fd1170e6bda2caf90f3d7"},"taxa":[{"id":"CWE-290","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"note","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"8c4965c1b61364651dd3e67a229810ab26a5caa49ed5579a7ae5ed6c69f87c9a"},"taxa":[{"id":"CWE-290","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"note","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"0f4c8df40e36e8493e00eaeae58b816211dd116fbee32c76941d7eb0d6dca131"},"taxa":[{"id":"CWE-290","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"note","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"b290183051c4833a6a2f0990e32a43aadee4353d4f9d597fa7795830300be3b1"},"taxa":[{"id":"CWE-290","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"note","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"cf1a17d4d9275d8a3053dd746921e8de26f3a9c6b47add229feda1e8f86b0afb"},"taxa":[{"id":"CWE-290","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"note","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"11dd7a5cccf3bbad071ad48640257a35cac2826d0e7a7c71064acacfdca77414"},"taxa":[{"id":"CWE-290","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"note","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"72f0495c6174f1ec95be2ef1f4e7afb182a1dbf5712a8b53367d2ec3d4babc78"},"taxa":[{"id":"CWE-290","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"note","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"e2bc821c82c0f0c1bd69081bc2d27edde582f23c32ff06d64dba262e0fc19732"},"taxa":[{"id":"CWE-290","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"note","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"cd50a0a1a5fceeb9c9d8017e5ffd982cfaef7d52b4a41146a1e59293bd6558a1"},"taxa":[{"id":"CWE-290","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"note","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"f239709cf6a4e8d15f2b957df106e835e4e9ce69e8da79f8e452e1544ee9eaaa"},"taxa":[{"id":"CWE-290","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"note","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"6090a185e5b54a99aadec23b842586cf6996637991c2b0ae670b6de60f900c7f"},"taxa":[{"id":"CWE-290","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"note","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"d627afa8170c60930e4c7c730f1694336b2a254d528e06edda9d7ba68467619f"},"taxa":[{"id":"CWE-290","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"note","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"0ad1e072376f058e1f5de84858ada20c8b302a613a4b5d4d22538f13e7e48d18"},"taxa":[{"id":"CWE-290","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"note","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"e2515d7ac1a627d6ea1a16246b5eb3c689e32fa2d76aa04c8377401480cfdd31"},"taxa":[{"id":"CWE-290","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"note","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"7f267d848132955e1813ec7d674189a4860c44322ad8820d0fb99a0fd9c7986e"},"taxa":[{"id":"CWE-290","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"note","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"8774b8c61b3d3140fc7ea8a9899570dd3820e973c82de461a218b3c60e8eca25"},"taxa":[{"id":"CWE-290","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"note","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"53a0315a67bfd7163fcb4080911929975518350a1668b406d431a3820ab40cb6"},"taxa":[{"id":"CWE-290","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"note","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"dc9e2066182021fae0755e2b36fdc33c7b165d03cc641ca4fa2a2c4a51c3ddbd"},"taxa":[{"id":"CWE-290","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"note","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"e2fc196c67313a97c7d9f89f250be0f5e06a3827c9a3093b5a69e0eed162a11b"},"taxa":[{"id":"CWE-290","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"note","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"7d56c92d2a1f5220cb433c8a497361c5cb9e71a530610217706aae79c9fe27c4"},"taxa":[{"id":"CWE-290","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"note","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"c12a98e5f66e50733ca239dc56410fea17ea3ff8679e5d2b01201005765ac25c"},"taxa":[{"id":"CWE-290","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"note","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"668135ce725ec6123d9a5b647247f77c206c77d4d4c2e3742a41343d5fe5a6ae"},"taxa":[{"id":"CWE-290","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"note","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"e121237d0a053fa9bffea8eb481ccb7293e72541cd6d714a08e1b3a542fa2ffd"},"taxa":[{"id":"CWE-290","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"note","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"4b142450c322332bcc332fafbdf4fc6c0861d2cae359d0ca0809c7a5b897edbc"},"taxa":[{"id":"CWE-290","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"ruleId":"D29","level":"note","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"2eacf4171ff7b41be662a78d987906fbd9aa661e27757c248b00c4816f3bc6be"},"taxa":[{"id":"CWE-290","toolComponent":{"name":"CWE","guid":"c3a2b1d0-7f3e-4b2a-9c1d-5e6f7a8b9c0d"}}]},{"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":"fef82dcff69c9a5c14e95c36ce20b753e5b455a1a3e8a9e5ebf0f48263fa2696"}},{"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":"826c79fbbb07eb23331f62872d71d58fdb04d4ca70e9ca9d829e55dc4d968d33"}},{"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":"e3e027c85d9d77671a880f21966f13981a9d18ee71ca39a173310fa851127096"}},{"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":"4cd6c36d9a0102f452c4000496387c4bd2b902357cc5a36acd64e26a0790afe8"}},{"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":"ce081dd1ead27e3c4f11ff3ec3bb3d08f2c223b311819dbb1cbad9432fe18d11"}},{"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":"f5f8e2fa874860b964760843ab31a872f2cfe6282b66ebee906c74a4e3d8d0fc"}},{"ruleId":"D31","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":"51ec67c5e9d5ab8a05ca0b1e9b01516fccfe16f7fcafb038065a23c405bf37b5"}},{"ruleId":"D31","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":"b3050eff82b8bce229ce9a12797c26b9af5fdfb97a74f9e81bb0a774dd83a922"}},{"ruleId":"D31","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":"9e8b4341daba04f1a0e3890c66e20ea6fab597c52ee1129c58ca15e99906bc5b"}},{"ruleId":"D35","level":"error","message":{"text":"Boundary-crossing change coupling: insightAdapter.ts \u2194 insightAdapter.ts: \u0060frontend/apps/enduser/src/features/insight/insightAdapter.ts\u0060 (context enduser) and \u0060frontend/apps/partner/src/features/insight/insight-dashboard-detail/insightAdapter.ts\u0060 (context partner) sit in DIFFERENT parts of the tree yet change together 74% of the time (14 of the 19 commits that touched whichever of the two files changed less often, counting a file under its earlier names as well) \u2014 the bounded-context boundary may be in the wrong place, or one context is leaking into the other. This is the behavioural boundary violation a static scan can\u0027t see."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"frontend/apps/enduser/src/features/insight/insightAdapter.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"388581b1f7d836f085ec13c9db5e43d393823c2ac7fbfbf3245cf1cbd23cf3ee"}},{"ruleId":"D35","level":"error","message":{"text":"Boundary-crossing change coupling: insightAdapter.ts \u2194 componentConfig.ts: \u0060frontend/apps/enduser/src/features/insight/insightAdapter.ts\u0060 (context enduser) and \u0060frontend/apps/partner/src/features/insight/insight-dashboard-detail/componentConfig.ts\u0060 (context partner) sit in DIFFERENT parts of the tree yet change together 70% of the time (16 of the 23 commits that touched whichever of the two files changed less often, counting a file under its earlier names as well) \u2014 the bounded-context boundary may be in the wrong place, or one context is leaking into the other. This is the behavioural boundary violation a static scan can\u0027t see."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"frontend/apps/enduser/src/features/insight/insightAdapter.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"147112868f68850a46c1379b92ddc68d2bd467d9b75e5cc512a3f1833180a4d1"}},{"ruleId":"D35","level":"error","message":{"text":"Boundary-crossing change coupling: insightAdapter.ts \u2194 ComponentConfigSheet.tsx: \u0060frontend/apps/enduser/src/features/insight/insightAdapter.ts\u0060 (context enduser) and \u0060frontend/apps/partner/src/features/insight/insight-dashboard-detail/components/ComponentConfigSheet.tsx\u0060 (context partner) sit in DIFFERENT parts of the tree yet change together 63% of the time (17 of the 27 commits that touched whichever of the two files changed less often, counting a file under its earlier names as well) \u2014 the bounded-context boundary may be in the wrong place, or one context is leaking into the other. This is the behavioural boundary violation a static scan can\u0027t see."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"frontend/apps/enduser/src/features/insight/insightAdapter.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"dc1c87295adb78e8ab1658a9311e59858bd3a371239362fd2e1ed610298a8edc"}},{"ruleId":"D35","level":"error","message":{"text":"Boundary-crossing change coupling: Program.cs \u2194 Program.cs: \u0060backend/src/Enduser/Enduser.Api/Program.cs\u0060 (context Enduser) and \u0060backend/src/Partner/Partner.Api/Program.cs\u0060 (context Partner) sit in DIFFERENT parts of the tree yet change together 60% of the time (6 of the 10 commits that touched whichever of the two files changed less often, counting a file under its earlier names as well) \u2014 the bounded-context boundary may be in the wrong place, or one context is leaking into the other. This is the behavioural boundary violation a static scan can\u0027t see."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/src/Enduser/Enduser.Api/Program.cs"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"db633a6a0659875d8d9865c3548b4cc9cfba8794714649896fe3449c46e88796"}},{"ruleId":"D35","level":"error","message":{"text":"Boundary-crossing change coupling: ComponentSettingsDrawer.tsx \u2194 componentConfig.ts: \u0060frontend/apps/enduser/src/features/insight/components/ComponentSettingsDrawer.tsx\u0060 (context enduser) and \u0060frontend/apps/partner/src/features/insight/insight-dashboard-detail/componentConfig.ts\u0060 (context partner) sit in DIFFERENT parts of the tree yet change together 58% of the time (11 of the 19 commits that touched whichever of the two files changed less often, counting a file under its earlier names as well) \u2014 the bounded-context boundary may be in the wrong place, or one context is leaking into the other. This is the behavioural boundary violation a static scan can\u0027t see."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"frontend/apps/enduser/src/features/insight/components/ComponentSettingsDrawer.tsx"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"f0d8a0bbdce8ed5bbc227eaf35015afffbd015855774e2a3238c0506c050cefb"}},{"ruleId":"D35","level":"error","message":{"text":"Boundary-crossing change coupling: ComponentSettingsDrawer.tsx \u2194 ComponentConfigSheet.tsx: \u0060frontend/apps/enduser/src/features/insight/components/ComponentSettingsDrawer.tsx\u0060 (context enduser) and \u0060frontend/apps/partner/src/features/insight/insight-dashboard-detail/components/ComponentConfigSheet.tsx\u0060 (context partner) sit in DIFFERENT parts of the tree yet change together 58% of the time (11 of the 19 commits that touched whichever of the two files changed less often, counting a file under its earlier names as well) \u2014 the bounded-context boundary may be in the wrong place, or one context is leaking into the other. This is the behavioural boundary violation a static scan can\u0027t see."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"frontend/apps/enduser/src/features/insight/components/ComponentSettingsDrawer.tsx"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"5e9b571998817f293645d94bd772a18228f711c4df4446fdc827982e42586ff7"}},{"ruleId":"D35","level":"error","message":{"text":"Boundary-crossing change coupling: insightAdapter.ts \u2194 sampleDataEngine.ts: \u0060frontend/apps/enduser/src/features/insight/insightAdapter.ts\u0060 (context enduser) and \u0060frontend/apps/partner/src/features/insight/insight-dashboard-detail/sampleDataEngine.ts\u0060 (context partner) sit in DIFFERENT parts of the tree yet change together 53% of the time (8 of the 15 commits that touched whichever of the two files changed less often, counting a file under its earlier names as well) \u2014 the bounded-context boundary may be in the wrong place, or one context is leaking into the other. This is the behavioural boundary violation a static scan can\u0027t see."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"frontend/apps/enduser/src/features/insight/insightAdapter.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"d75ef2c30b018cccd764c34b9c99f992c9cccc6b67a2999237e5766092deba1d"}},{"ruleId":"D35","level":"error","message":{"text":"Boundary-crossing change coupling: Program.cs \u2194 Program.cs: \u0060backend/src/Enduser/Enduser.Api/Program.cs\u0060 (context Enduser) and \u0060backend/src/Master/Master.Api/Program.cs\u0060 (context Master) sit in DIFFERENT parts of the tree yet change together 50% of the time (5 of the 10 commits that touched whichever of the two files changed less often, counting a file under its earlier names as well) \u2014 the bounded-context boundary may be in the wrong place, or one context is leaking into the other. This is the behavioural boundary violation a static scan can\u0027t see."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/src/Enduser/Enduser.Api/Program.cs"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"ed951a4837fc73857b14384bba57c0d0b7c9a5e4f6a0f0d64641af45411a737c"}},{"ruleId":"D35","level":"error","message":{"text":"Boundary-crossing change coupling: SyncEndpoints.cs \u2194 Feature.cs: \u0060backend/src/Partner/Partner.Api/Endpoints/SyncEndpoints.cs\u0060 (context Partner) and \u0060backend/src/Shared/Features/Applications/SubmitAnswer/Feature.cs\u0060 (context Shared) sit in DIFFERENT parts of the tree yet change together 50% of the time (5 of the 10 commits that touched whichever of the two files changed less often, counting a file under its earlier names as well) \u2014 the bounded-context boundary may be in the wrong place, or one context is leaking into the other. This is the behavioural boundary violation a static scan can\u0027t see."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"backend/src/Partner/Partner.Api/Endpoints/SyncEndpoints.cs"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"70df2cb6fcb3837051d84e46f9e4492194bb883b04ea03dcda4f6d3e7c083d2f"}},{"ruleId":"D35","level":"warning","message":{"text":"Change coupling: en.ts \u2194 types.ts: \u0060frontend/packages/utils/src/i18n/translations/en.ts\u0060 and \u0060frontend/packages/utils/src/insight/types.ts\u0060 change together 86% of the time (12 of the 14 commits that touched whichever of the two files changed less often, counting a file under its earlier names as well) with no explicit dependency \u2014 the edge is real but nothing declares it. Read the pair before acting: if one registers itself into the other through a hook or an initialiser, the missing dependency is DELIBERATE \u2014 the registration is the link, and it is meant not to be an import \u2014 and the thing to add is a comment on each side naming the other, not a merge; if they simply belong together, co-locate them; if neither holds, the coupling is hidden and worth breaking."},"locations":[{"physicalLocation":{"artifactLocation":{"uri":"frontend/packages/utils/src/i18n/translations/en.ts"},"region":{"startLine":1}}}],"partialFingerprints":{"codehealthFindingId/v1":"a85e673389c8e9279480dc5b22dbed55c004dd5119e4d95d3087d18fdf29b32d"}},{"ruleId":"D36","level":"note","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"1b213f6eedd4b140d0bc37bdf1496f72811a643f34064f12518b32e9e83bcfc7"}},{"ruleId":"D36","level":"note","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"0e17f71490e4d120a48b2b2881ab866c93b272bef2febb673a3e8e42b2c288ab"}},{"ruleId":"D36","level":"warning","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"90f83b4fa27db32740afe9540c905f3c0499caed87f61049a8a903ecc95b41c3"}},{"ruleId":"D38","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"5dbc10f3e168c1e828fcf6ea6ed0091a848f15d198bf3338403da411c3e0eb96"}},{"ruleId":"D38","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"ab8213f78e401a9a49a8484b0e6c5998de7ffd61250b8ccc273f85ac7e1a600d"}},{"ruleId":"D38","level":"error","message":{"text":"A security finding was recorded here. Its details are withheld on the public artifact \u2014 ask the repository owner for the full report."},"partialFingerprints":{"codehealthFindingId/v1":"63806150cea50fe328bc3405c8184207952a0ed4de9591909b5634aaf1187b60"}},{"ruleId":"D38","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":"12bd12a384a3d431645b1c9f9a38fdb26dd0719229a89051bf549313d3726185"}},{"ruleId":"D38","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":"7667459d2f904342a96297f4058a235d8aa76cb2235868dafa28669cac90551b"}},{"ruleId":"D38","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":"d416cf5dfe2b548e6b3aef4ded74cd6cfe28e14bb34ba7641bf0eb3374100a33"}},{"ruleId":"D38","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":"bf81e88c4ae3e3301fcb0f2ceaefd1e1c925643561c33f735a72dddddd19ac52"}},{"ruleId":"D41","level":"note","message":{"text":"No AppArmor/SELinux confinement: Workloads declare no AppArmor or SELinux profile. A mandatory-access-control profile confines what a compromised container can touch on the host, complementing seccomp\u0027s syscall filter."},"locations":[],"partialFingerprints":{"codehealthFindingId/v1":"e83fbc31033373d6c51983ed230eb4ba61f7775ed02afb30f5fc1840bde01d4f"}}],"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-1357","guid":"e4d2e772-757e-0a5c-bd7d-77052949d866","name":"Reliance on Insufficiently Trustworthy Component","shortDescription":{"text":"Reliance on Insufficiently Trustworthy Component"},"helpUri":"https://cwe.mitre.org/data/definitions/1357.html"},{"id":"CWE-1395","guid":"800e09e7-c11a-8654-9fa6-86f398995fed","name":"Dependency on Vulnerable Third-Party Component","shortDescription":{"text":"Dependency on Vulnerable Third-Party Component"},"helpUri":"https://cwe.mitre.org/data/definitions/1395.html"},{"id":"CWE-16","guid":"659db3ea-affc-8453-8add-c1218fbfcb92","name":"Configuration","shortDescription":{"text":"Configuration"},"helpUri":"https://cwe.mitre.org/data/definitions/16.html"},{"id":"CWE-259","guid":"ae9ad959-fbb6-9d5e-892d-3dca66da0b69","name":"Use of Hard-coded Password","shortDescription":{"text":"Use of Hard-coded Password"},"helpUri":"https://cwe.mitre.org/data/definitions/259.html"},{"id":"CWE-290","guid":"379b1e66-a292-7b59-aa1e-a5bb4a6a99e9","name":"CWE-290","shortDescription":{"text":"CWE-290"},"helpUri":"https://cwe.mitre.org/data/definitions/290.html"},{"id":"CWE-345","guid":"d80d4b65-bbbe-b65d-958e-7ac466af18f9","name":"CWE-345","shortDescription":{"text":"CWE-345"},"helpUri":"https://cwe.mitre.org/data/definitions/345.html"},{"id":"CWE-353","guid":"09d7e902-d4ee-f05d-ae6c-0a1554d0c18f","name":"CWE-353","shortDescription":{"text":"CWE-353"},"helpUri":"https://cwe.mitre.org/data/definitions/353.html"},{"id":"CWE-494","guid":"b8a65e0d-e459-4a55-a931-fc1136482375","name":"Download of Code Without Integrity Check","shortDescription":{"text":"Download of Code Without Integrity Check"},"helpUri":"https://cwe.mitre.org/data/definitions/494.html"},{"id":"CWE-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":"Command Injection","shortDescription":{"text":"Command Injection"},"helpUri":"https://cwe.mitre.org/data/definitions/77.html"},{"id":"CWE-78","guid":"2e31ceaf-c7ae-2e5e-9661-cfb1362789cf","name":"OS Command Injection","shortDescription":{"text":"OS Command Injection"},"helpUri":"https://cwe.mitre.org/data/definitions/78.html"},{"id":"CWE-79","guid":"fd45580b-e8c4-fc5e-8c2f-aa8fab0b4dbf","name":"Cross-site Scripting (XSS)","shortDescription":{"text":"Cross-site Scripting (XSS)"},"helpUri":"https://cwe.mitre.org/data/definitions/79.html"},{"id":"CWE-798","guid":"5e8f057d-fee3-995a-a0cb-9fc5b0d174d1","name":"Use of Hard-coded Credentials","shortDescription":{"text":"Use of Hard-coded Credentials"},"helpUri":"https://cwe.mitre.org/data/definitions/798.html"},{"id":"CWE-829","guid":"13c33925-97fb-5a5e-b40c-56d328b8a4d7","name":"CWE-829","shortDescription":{"text":"CWE-829"},"helpUri":"https://cwe.mitre.org/data/definitions/829.html"},{"id":"CWE-89","guid":"6d08fdad-37eb-c150-bbf0-d7d946863407","name":"SQL Injection","shortDescription":{"text":"SQL Injection"},"helpUri":"https://cwe.mitre.org/data/definitions/89.html"},{"id":"CWE-937","guid":"16f316ae-415c-b354-a59b-1f7905f756e9","name":"Using Components with Known Vulnerabilities","shortDescription":{"text":"Using Components with Known Vulnerabilities"},"helpUri":"https://cwe.mitre.org/data/definitions/937.html"},{"id":"CWE-94","guid":"75e7f50c-6c2f-dd52-bf40-bf6c52b861fd","name":"Code Injection","shortDescription":{"text":"Code Injection"},"helpUri":"https://cwe.mitre.org/data/definitions/94.html"}]}],"properties":{"codehealthPublication":{"public":true,"notice":"This is the PUBLIC form of this artifact. Findings are listed in full, but the details of SECURITY findings \u2014 which rule fired, in which file, on which line, and how to fix it \u2014 are deliberately withheld, and any secret-scanner results are excluded entirely. Where detail is absent here it was REMOVED FOR PUBLICATION; it is not missing from the analysis. The complete artifact is available from the repository owner.","securityFindingsRedacted":70,"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."]}]}