diff --git a/docs/implplan/SPRINT_20251229_049_BE_csproj_audit_maint_tests.md b/docs/implplan/SPRINT_20251229_049_BE_csproj_audit_maint_tests.md index 36d4ccee6..c256ef7e9 100644 --- a/docs/implplan/SPRINT_20251229_049_BE_csproj_audit_maint_tests.md +++ b/docs/implplan/SPRINT_20251229_049_BE_csproj_audit_maint_tests.md @@ -22,28 +22,28 @@ Bulk task definitions (applies to every project row below): | --- | --- | --- | --- | --- | --- | | 1 | AUDIT-0001-M | DONE | Report | Guild | src/Router/examples/Examples.Billing.Microservice/Examples.Billing.Microservice.csproj - MAINT | | 2 | AUDIT-0001-T | DONE | Report | Guild | src/Router/examples/Examples.Billing.Microservice/Examples.Billing.Microservice.csproj - TEST | -| 3 | AUDIT-0001-A | DONE | Waived | Guild | src/Router/examples/Examples.Billing.Microservice/Examples.Billing.Microservice.csproj - APPLY | +| 3 | AUDIT-0001-A | DONE | Waived (example project) | Guild | src/Router/examples/Examples.Billing.Microservice/Examples.Billing.Microservice.csproj - APPLY | | 4 | AUDIT-0002-M | DONE | Report | Guild | src/Router/examples/Examples.Gateway/Examples.Gateway.csproj - MAINT | | 5 | AUDIT-0002-T | DONE | Report | Guild | src/Router/examples/Examples.Gateway/Examples.Gateway.csproj - TEST | -| 6 | AUDIT-0002-A | DONE | Waived | Guild | src/Router/examples/Examples.Gateway/Examples.Gateway.csproj - APPLY | +| 6 | AUDIT-0002-A | DONE | Waived (example project) | Guild | src/Router/examples/Examples.Gateway/Examples.Gateway.csproj - APPLY | | 7 | AUDIT-0003-M | DONE | Report | Guild | src/Router/examples/Examples.Inventory.Microservice/Examples.Inventory.Microservice.csproj - MAINT | | 8 | AUDIT-0003-T | DONE | Report | Guild | src/Router/examples/Examples.Inventory.Microservice/Examples.Inventory.Microservice.csproj - TEST | -| 9 | AUDIT-0003-A | DONE | Waived | Guild | src/Router/examples/Examples.Inventory.Microservice/Examples.Inventory.Microservice.csproj - APPLY | +| 9 | AUDIT-0003-A | DONE | Waived (example project) | Guild | src/Router/examples/Examples.Inventory.Microservice/Examples.Inventory.Microservice.csproj - APPLY | | 10 | AUDIT-0004-M | DONE | Report | Guild | src/Router/examples/Examples.MultiTransport.Gateway/Examples.MultiTransport.Gateway.csproj - MAINT | | 11 | AUDIT-0004-T | DONE | Report | Guild | src/Router/examples/Examples.MultiTransport.Gateway/Examples.MultiTransport.Gateway.csproj - TEST | -| 12 | AUDIT-0004-A | DONE | Waived | Guild | src/Router/examples/Examples.MultiTransport.Gateway/Examples.MultiTransport.Gateway.csproj - APPLY | +| 12 | AUDIT-0004-A | DONE | Waived (example project) | Guild | src/Router/examples/Examples.MultiTransport.Gateway/Examples.MultiTransport.Gateway.csproj - APPLY | | 13 | AUDIT-0005-M | DONE | Report | Guild | src/Router/examples/Examples.NotificationService/Examples.NotificationService.csproj - MAINT | | 14 | AUDIT-0005-T | DONE | Report | Guild | src/Router/examples/Examples.NotificationService/Examples.NotificationService.csproj - TEST | -| 15 | AUDIT-0005-A | DONE | Waived | Guild | src/Router/examples/Examples.NotificationService/Examples.NotificationService.csproj - APPLY | +| 15 | AUDIT-0005-A | DONE | Waived (example project) | Guild | src/Router/examples/Examples.NotificationService/Examples.NotificationService.csproj - APPLY | | 16 | AUDIT-0006-M | DONE | Report | Guild | src/Router/examples/Examples.OrderService/Examples.OrderService.csproj - MAINT | | 17 | AUDIT-0006-T | DONE | Report | Guild | src/Router/examples/Examples.OrderService/Examples.OrderService.csproj - TEST | -| 18 | AUDIT-0006-A | DONE | Waived | Guild | src/Router/examples/Examples.OrderService/Examples.OrderService.csproj - APPLY | +| 18 | AUDIT-0006-A | DONE | Waived (example project) | Guild | src/Router/examples/Examples.OrderService/Examples.OrderService.csproj - APPLY | | 19 | AUDIT-0007-M | DONE | Report | Guild | src/Tools/FixtureUpdater/FixtureUpdater.csproj - MAINT | | 20 | AUDIT-0007-T | DONE | Report | Guild | src/Tools/FixtureUpdater/FixtureUpdater.csproj - TEST | -| 21 | AUDIT-0007-A | TODO | Approval | Guild | src/Tools/FixtureUpdater/FixtureUpdater.csproj - APPLY | +| 21 | AUDIT-0007-A | DONE | Applied + tests | Guild | src/Tools/FixtureUpdater/FixtureUpdater.csproj - APPLY | | 22 | AUDIT-0008-M | DONE | Report | Guild | src/Tools/LanguageAnalyzerSmoke/LanguageAnalyzerSmoke.csproj - MAINT | | 23 | AUDIT-0008-T | DONE | Report | Guild | src/Tools/LanguageAnalyzerSmoke/LanguageAnalyzerSmoke.csproj - TEST | -| 24 | AUDIT-0008-A | TODO | Approval | Guild | src/Tools/LanguageAnalyzerSmoke/LanguageAnalyzerSmoke.csproj - APPLY | +| 24 | AUDIT-0008-A | DONE | Applied + tests | Guild | src/Tools/LanguageAnalyzerSmoke/LanguageAnalyzerSmoke.csproj - APPLY | | 25 | AUDIT-0009-M | DONE | Report | Guild | src/Findings/StellaOps.Findings.Ledger/tools/LedgerReplayHarness/LedgerReplayHarness.csproj - MAINT | | 26 | AUDIT-0009-T | DONE | Report | Guild | src/Findings/StellaOps.Findings.Ledger/tools/LedgerReplayHarness/LedgerReplayHarness.csproj - TEST | | 27 | AUDIT-0009-A | TODO | Approval | Guild | src/Findings/StellaOps.Findings.Ledger/tools/LedgerReplayHarness/LedgerReplayHarness.csproj - APPLY | @@ -52,22 +52,22 @@ Bulk task definitions (applies to every project row below): | 30 | AUDIT-0010-A | TODO | Approval | Guild | src/Findings/tools/LedgerReplayHarness/LedgerReplayHarness.csproj - APPLY | | 31 | AUDIT-0011-M | DONE | Report | Guild | src/Tools/NotifySmokeCheck/NotifySmokeCheck.csproj - MAINT | | 32 | AUDIT-0011-T | DONE | Report | Guild | src/Tools/NotifySmokeCheck/NotifySmokeCheck.csproj - TEST | -| 33 | AUDIT-0011-A | TODO | Approval | Guild | src/Tools/NotifySmokeCheck/NotifySmokeCheck.csproj - APPLY | +| 33 | AUDIT-0011-A | DONE | Applied + tests | Guild | src/Tools/NotifySmokeCheck/NotifySmokeCheck.csproj - APPLY | | 34 | AUDIT-0012-M | DONE | Report | Guild | src/Tools/PolicyDslValidator/PolicyDslValidator.csproj - MAINT | | 35 | AUDIT-0012-T | DONE | Report | Guild | src/Tools/PolicyDslValidator/PolicyDslValidator.csproj - TEST | -| 36 | AUDIT-0012-A | TODO | Approval | Guild | src/Tools/PolicyDslValidator/PolicyDslValidator.csproj - APPLY | +| 36 | AUDIT-0012-A | DONE | Applied + tests | Guild | src/Tools/PolicyDslValidator/PolicyDslValidator.csproj - APPLY | | 37 | AUDIT-0013-M | DONE | Report | Guild | src/Tools/PolicySchemaExporter/PolicySchemaExporter.csproj - MAINT | | 38 | AUDIT-0013-T | DONE | Report | Guild | src/Tools/PolicySchemaExporter/PolicySchemaExporter.csproj - TEST | -| 39 | AUDIT-0013-A | TODO | Approval | Guild | src/Tools/PolicySchemaExporter/PolicySchemaExporter.csproj - APPLY | +| 39 | AUDIT-0013-A | DONE | Applied + tests | Guild | src/Tools/PolicySchemaExporter/PolicySchemaExporter.csproj - APPLY | | 40 | AUDIT-0014-M | DONE | Report | Guild | src/Tools/PolicySimulationSmoke/PolicySimulationSmoke.csproj - MAINT | | 41 | AUDIT-0014-T | DONE | Report | Guild | src/Tools/PolicySimulationSmoke/PolicySimulationSmoke.csproj - TEST | -| 42 | AUDIT-0014-A | TODO | Approval | Guild | src/Tools/PolicySimulationSmoke/PolicySimulationSmoke.csproj - APPLY | +| 42 | AUDIT-0014-A | DONE | Applied + tests | Guild | src/Tools/PolicySimulationSmoke/PolicySimulationSmoke.csproj - APPLY | | 43 | AUDIT-0015-M | DONE | Report | Guild | src/Tools/RustFsMigrator/RustFsMigrator.csproj - MAINT | | 44 | AUDIT-0015-T | DONE | Report | Guild | src/Tools/RustFsMigrator/RustFsMigrator.csproj - TEST | -| 45 | AUDIT-0015-A | TODO | Approval | Guild | src/Tools/RustFsMigrator/RustFsMigrator.csproj - APPLY | +| 45 | AUDIT-0015-A | DONE | Applied + tests | Guild | src/Tools/RustFsMigrator/RustFsMigrator.csproj - APPLY | | 46 | AUDIT-0016-M | DONE | Report | Guild | src/Scheduler/Tools/Scheduler.Backfill/Scheduler.Backfill.csproj - MAINT | | 47 | AUDIT-0016-T | DONE | Report | Guild | src/Scheduler/Tools/Scheduler.Backfill/Scheduler.Backfill.csproj - TEST | -| 48 | AUDIT-0016-A | TODO | Approval | Guild | src/Scheduler/Tools/Scheduler.Backfill/Scheduler.Backfill.csproj - APPLY | +| 48 | AUDIT-0016-A | DONE | Applied + tests | Guild | src/Scheduler/Tools/Scheduler.Backfill/Scheduler.Backfill.csproj - APPLY | | 49 | AUDIT-0017-M | DONE | Report | Guild | src/AdvisoryAI/StellaOps.AdvisoryAI/StellaOps.AdvisoryAI.csproj - MAINT | | 50 | AUDIT-0017-T | DONE | Report | Guild | src/AdvisoryAI/StellaOps.AdvisoryAI/StellaOps.AdvisoryAI.csproj - TEST | | 51 | AUDIT-0017-A | TODO | Approval | Guild | src/AdvisoryAI/StellaOps.AdvisoryAI/StellaOps.AdvisoryAI.csproj - APPLY | @@ -76,7 +76,7 @@ Bulk task definitions (applies to every project row below): | 54 | AUDIT-0018-A | TODO | Approval | Guild | src/AdvisoryAI/StellaOps.AdvisoryAI.Hosting/StellaOps.AdvisoryAI.Hosting.csproj - APPLY | | 55 | AUDIT-0019-M | DONE | Report | Guild | src/AdvisoryAI/__Tests/StellaOps.AdvisoryAI.Tests/StellaOps.AdvisoryAI.Tests.csproj - MAINT | | 56 | AUDIT-0019-T | DONE | Report | Guild | src/AdvisoryAI/__Tests/StellaOps.AdvisoryAI.Tests/StellaOps.AdvisoryAI.Tests.csproj - TEST | -| 57 | AUDIT-0019-A | TODO | Approval | Guild | src/AdvisoryAI/__Tests/StellaOps.AdvisoryAI.Tests/StellaOps.AdvisoryAI.Tests.csproj - APPLY | +| 57 | AUDIT-0019-A | DONE | Waived (test project) | Guild | src/AdvisoryAI/__Tests/StellaOps.AdvisoryAI.Tests/StellaOps.AdvisoryAI.Tests.csproj - APPLY | | 58 | AUDIT-0020-M | DONE | Report | Guild | src/AdvisoryAI/StellaOps.AdvisoryAI.WebService/StellaOps.AdvisoryAI.WebService.csproj - MAINT | | 59 | AUDIT-0020-T | DONE | Report | Guild | src/AdvisoryAI/StellaOps.AdvisoryAI.WebService/StellaOps.AdvisoryAI.WebService.csproj - TEST | | 60 | AUDIT-0020-A | TODO | Approval | Guild | src/AdvisoryAI/StellaOps.AdvisoryAI.WebService/StellaOps.AdvisoryAI.WebService.csproj - APPLY | @@ -88,25 +88,25 @@ Bulk task definitions (applies to every project row below): | 66 | AUDIT-0022-A | TODO | Approval | Guild | src/AirGap/__Libraries/StellaOps.AirGap.Bundle/StellaOps.AirGap.Bundle.csproj - APPLY | | 67 | AUDIT-0023-M | DONE | Report | Guild | src/AirGap/__Libraries/__Tests/StellaOps.AirGap.Bundle.Tests/StellaOps.AirGap.Bundle.Tests.csproj - MAINT | | 68 | AUDIT-0023-T | DONE | Report | Guild | src/AirGap/__Libraries/__Tests/StellaOps.AirGap.Bundle.Tests/StellaOps.AirGap.Bundle.Tests.csproj - TEST | -| 69 | AUDIT-0023-A | TODO | Approval | Guild | src/AirGap/__Libraries/__Tests/StellaOps.AirGap.Bundle.Tests/StellaOps.AirGap.Bundle.Tests.csproj - APPLY | +| 69 | AUDIT-0023-A | DONE | Waived (test project) | Guild | src/AirGap/__Libraries/__Tests/StellaOps.AirGap.Bundle.Tests/StellaOps.AirGap.Bundle.Tests.csproj - APPLY | | 70 | AUDIT-0024-M | DONE | Report | Guild | src/AirGap/StellaOps.AirGap.Controller/StellaOps.AirGap.Controller.csproj - MAINT | | 71 | AUDIT-0024-T | DONE | Report | Guild | src/AirGap/StellaOps.AirGap.Controller/StellaOps.AirGap.Controller.csproj - TEST | | 72 | AUDIT-0024-A | TODO | Approval | Guild | src/AirGap/StellaOps.AirGap.Controller/StellaOps.AirGap.Controller.csproj - APPLY | | 73 | AUDIT-0025-M | DONE | Report | Guild | src/AirGap/__Tests/StellaOps.AirGap.Controller.Tests/StellaOps.AirGap.Controller.Tests.csproj - MAINT | | 74 | AUDIT-0025-T | DONE | Report | Guild | src/AirGap/__Tests/StellaOps.AirGap.Controller.Tests/StellaOps.AirGap.Controller.Tests.csproj - TEST | -| 75 | AUDIT-0025-A | TODO | Approval | Guild | src/AirGap/__Tests/StellaOps.AirGap.Controller.Tests/StellaOps.AirGap.Controller.Tests.csproj - APPLY | +| 75 | AUDIT-0025-A | DONE | Waived (test project) | Guild | src/AirGap/__Tests/StellaOps.AirGap.Controller.Tests/StellaOps.AirGap.Controller.Tests.csproj - APPLY | | 76 | AUDIT-0026-M | DONE | Report | Guild | src/AirGap/StellaOps.AirGap.Importer/StellaOps.AirGap.Importer.csproj - MAINT | | 77 | AUDIT-0026-T | DONE | Report | Guild | src/AirGap/StellaOps.AirGap.Importer/StellaOps.AirGap.Importer.csproj - TEST | | 78 | AUDIT-0026-A | TODO | Approval | Guild | src/AirGap/StellaOps.AirGap.Importer/StellaOps.AirGap.Importer.csproj - APPLY | | 79 | AUDIT-0027-M | DONE | Report | Guild | src/AirGap/__Tests/StellaOps.AirGap.Importer.Tests/StellaOps.AirGap.Importer.Tests.csproj - MAINT | | 80 | AUDIT-0027-T | DONE | Report | Guild | src/AirGap/__Tests/StellaOps.AirGap.Importer.Tests/StellaOps.AirGap.Importer.Tests.csproj - TEST | -| 81 | AUDIT-0027-A | TODO | Approval | Guild | src/AirGap/__Tests/StellaOps.AirGap.Importer.Tests/StellaOps.AirGap.Importer.Tests.csproj - APPLY | +| 81 | AUDIT-0027-A | DONE | Waived (test project) | Guild | src/AirGap/__Tests/StellaOps.AirGap.Importer.Tests/StellaOps.AirGap.Importer.Tests.csproj - APPLY | | 82 | AUDIT-0028-M | DONE | Report | Guild | src/AirGap/__Libraries/StellaOps.AirGap.Persistence/StellaOps.AirGap.Persistence.csproj - MAINT | | 83 | AUDIT-0028-T | DONE | Report | Guild | src/AirGap/__Libraries/StellaOps.AirGap.Persistence/StellaOps.AirGap.Persistence.csproj - TEST | | 84 | AUDIT-0028-A | TODO | Approval | Guild | src/AirGap/__Libraries/StellaOps.AirGap.Persistence/StellaOps.AirGap.Persistence.csproj - APPLY | | 85 | AUDIT-0029-M | DONE | Report | Guild | src/AirGap/__Tests/StellaOps.AirGap.Persistence.Tests/StellaOps.AirGap.Persistence.Tests.csproj - MAINT | | 86 | AUDIT-0029-T | DONE | Report | Guild | src/AirGap/__Tests/StellaOps.AirGap.Persistence.Tests/StellaOps.AirGap.Persistence.Tests.csproj - TEST | -| 87 | AUDIT-0029-A | TODO | Approval | Guild | src/AirGap/__Tests/StellaOps.AirGap.Persistence.Tests/StellaOps.AirGap.Persistence.Tests.csproj - APPLY | +| 87 | AUDIT-0029-A | DONE | Waived (test project) | Guild | src/AirGap/__Tests/StellaOps.AirGap.Persistence.Tests/StellaOps.AirGap.Persistence.Tests.csproj - APPLY | | 88 | AUDIT-0030-M | DONE | Report | Guild | src/AirGap/StellaOps.AirGap.Policy/StellaOps.AirGap.Policy/StellaOps.AirGap.Policy.csproj - MAINT | | 89 | AUDIT-0030-T | DONE | Report | Guild | src/AirGap/StellaOps.AirGap.Policy/StellaOps.AirGap.Policy/StellaOps.AirGap.Policy.csproj - TEST | | 90 | AUDIT-0030-A | TODO | Approval | Guild | src/AirGap/StellaOps.AirGap.Policy/StellaOps.AirGap.Policy/StellaOps.AirGap.Policy.csproj - APPLY | @@ -115,16 +115,16 @@ Bulk task definitions (applies to every project row below): | 93 | AUDIT-0031-A | TODO | Approval | Guild | src/AirGap/StellaOps.AirGap.Policy/StellaOps.AirGap.Policy.Analyzers/StellaOps.AirGap.Policy.Analyzers.csproj - APPLY | | 94 | AUDIT-0032-M | DONE | Report | Guild | src/AirGap/StellaOps.AirGap.Policy/StellaOps.AirGap.Policy.Analyzers.Tests/StellaOps.AirGap.Policy.Analyzers.Tests.csproj - MAINT | | 95 | AUDIT-0032-T | DONE | Report | Guild | src/AirGap/StellaOps.AirGap.Policy/StellaOps.AirGap.Policy.Analyzers.Tests/StellaOps.AirGap.Policy.Analyzers.Tests.csproj - TEST | -| 96 | AUDIT-0032-A | TODO | Approval | Guild | src/AirGap/StellaOps.AirGap.Policy/StellaOps.AirGap.Policy.Analyzers.Tests/StellaOps.AirGap.Policy.Analyzers.Tests.csproj - APPLY | +| 96 | AUDIT-0032-A | DONE | Waived (test project) | Guild | src/AirGap/StellaOps.AirGap.Policy/StellaOps.AirGap.Policy.Analyzers.Tests/StellaOps.AirGap.Policy.Analyzers.Tests.csproj - APPLY | | 97 | AUDIT-0033-M | DONE | Report | Guild | src/AirGap/StellaOps.AirGap.Policy/StellaOps.AirGap.Policy.Tests/StellaOps.AirGap.Policy.Tests.csproj - MAINT | | 98 | AUDIT-0033-T | DONE | Report | Guild | src/AirGap/StellaOps.AirGap.Policy/StellaOps.AirGap.Policy.Tests/StellaOps.AirGap.Policy.Tests.csproj - TEST | -| 99 | AUDIT-0033-A | TODO | Approval | Guild | src/AirGap/StellaOps.AirGap.Policy/StellaOps.AirGap.Policy.Tests/StellaOps.AirGap.Policy.Tests.csproj - APPLY | +| 99 | AUDIT-0033-A | DONE | Waived (test project) | Guild | src/AirGap/StellaOps.AirGap.Policy/StellaOps.AirGap.Policy.Tests/StellaOps.AirGap.Policy.Tests.csproj - APPLY | | 100 | AUDIT-0034-M | DONE | Report | Guild | src/AirGap/StellaOps.AirGap.Time/StellaOps.AirGap.Time.csproj - MAINT | | 101 | AUDIT-0034-T | DONE | Report | Guild | src/AirGap/StellaOps.AirGap.Time/StellaOps.AirGap.Time.csproj - TEST | | 102 | AUDIT-0034-A | TODO | Approval | Guild | src/AirGap/StellaOps.AirGap.Time/StellaOps.AirGap.Time.csproj - APPLY | | 103 | AUDIT-0035-M | DONE | Report | Guild | src/AirGap/__Tests/StellaOps.AirGap.Time.Tests/StellaOps.AirGap.Time.Tests.csproj - MAINT | | 104 | AUDIT-0035-T | DONE | Report | Guild | src/AirGap/__Tests/StellaOps.AirGap.Time.Tests/StellaOps.AirGap.Time.Tests.csproj - TEST | -| 105 | AUDIT-0035-A | TODO | Approval | Guild | src/AirGap/__Tests/StellaOps.AirGap.Time.Tests/StellaOps.AirGap.Time.Tests.csproj - APPLY | +| 105 | AUDIT-0035-A | DONE | Waived (test project) | Guild | src/AirGap/__Tests/StellaOps.AirGap.Time.Tests/StellaOps.AirGap.Time.Tests.csproj - APPLY | | 106 | AUDIT-0036-M | DONE | Report | Guild | src/Aoc/__Libraries/StellaOps.Aoc/StellaOps.Aoc.csproj - MAINT | | 107 | AUDIT-0036-T | DONE | Report | Guild | src/Aoc/__Libraries/StellaOps.Aoc/StellaOps.Aoc.csproj - TEST | | 108 | AUDIT-0036-A | TODO | Approval | Guild | src/Aoc/__Libraries/StellaOps.Aoc/StellaOps.Aoc.csproj - APPLY | @@ -133,55 +133,55 @@ Bulk task definitions (applies to every project row below): | 111 | AUDIT-0037-A | TODO | Approval | Guild | src/Aoc/__Analyzers/StellaOps.Aoc.Analyzers/StellaOps.Aoc.Analyzers.csproj - APPLY | | 112 | AUDIT-0038-M | DONE | Report | Guild | src/Aoc/__Tests/StellaOps.Aoc.Analyzers.Tests/StellaOps.Aoc.Analyzers.Tests.csproj - MAINT | | 113 | AUDIT-0038-T | DONE | Report | Guild | src/Aoc/__Tests/StellaOps.Aoc.Analyzers.Tests/StellaOps.Aoc.Analyzers.Tests.csproj - TEST | -| 114 | AUDIT-0038-A | TODO | Approval | Guild | src/Aoc/__Tests/StellaOps.Aoc.Analyzers.Tests/StellaOps.Aoc.Analyzers.Tests.csproj - APPLY | +| 114 | AUDIT-0038-A | DONE | Waived (test project) | Guild | src/Aoc/__Tests/StellaOps.Aoc.Analyzers.Tests/StellaOps.Aoc.Analyzers.Tests.csproj - APPLY | | 115 | AUDIT-0039-M | DONE | Report | Guild | src/Aoc/__Libraries/StellaOps.Aoc.AspNetCore/StellaOps.Aoc.AspNetCore.csproj - MAINT | | 116 | AUDIT-0039-T | DONE | Report | Guild | src/Aoc/__Libraries/StellaOps.Aoc.AspNetCore/StellaOps.Aoc.AspNetCore.csproj - TEST | | 117 | AUDIT-0039-A | TODO | Approval | Guild | src/Aoc/__Libraries/StellaOps.Aoc.AspNetCore/StellaOps.Aoc.AspNetCore.csproj - APPLY | | 118 | AUDIT-0040-M | DONE | Report | Guild | src/Aoc/__Tests/StellaOps.Aoc.AspNetCore.Tests/StellaOps.Aoc.AspNetCore.Tests.csproj - MAINT | | 119 | AUDIT-0040-T | DONE | Report | Guild | src/Aoc/__Tests/StellaOps.Aoc.AspNetCore.Tests/StellaOps.Aoc.AspNetCore.Tests.csproj - TEST | -| 120 | AUDIT-0040-A | TODO | Approval | Guild | src/Aoc/__Tests/StellaOps.Aoc.AspNetCore.Tests/StellaOps.Aoc.AspNetCore.Tests.csproj - APPLY | +| 120 | AUDIT-0040-A | DONE | Waived (test project) | Guild | src/Aoc/__Tests/StellaOps.Aoc.AspNetCore.Tests/StellaOps.Aoc.AspNetCore.Tests.csproj - APPLY | | 121 | AUDIT-0041-M | DONE | Report | Guild | src/Aoc/__Tests/StellaOps.Aoc.Tests/StellaOps.Aoc.Tests.csproj - MAINT | | 122 | AUDIT-0041-T | DONE | Report | Guild | src/Aoc/__Tests/StellaOps.Aoc.Tests/StellaOps.Aoc.Tests.csproj - TEST | -| 123 | AUDIT-0041-A | TODO | Approval | Guild | src/Aoc/__Tests/StellaOps.Aoc.Tests/StellaOps.Aoc.Tests.csproj - APPLY | +| 123 | AUDIT-0041-A | DONE | Waived (test project) | Guild | src/Aoc/__Tests/StellaOps.Aoc.Tests/StellaOps.Aoc.Tests.csproj - APPLY | | 124 | AUDIT-0042-M | DONE | Report | Guild | src/__Tests/architecture/StellaOps.Architecture.Tests/StellaOps.Architecture.Tests.csproj - MAINT | | 125 | AUDIT-0042-T | DONE | Report | Guild | src/__Tests/architecture/StellaOps.Architecture.Tests/StellaOps.Architecture.Tests.csproj - TEST | -| 126 | AUDIT-0042-A | TODO | Approval | Guild | src/__Tests/architecture/StellaOps.Architecture.Tests/StellaOps.Architecture.Tests.csproj - APPLY | +| 126 | AUDIT-0042-A | DONE | Waived (test project) | Guild | src/__Tests/architecture/StellaOps.Architecture.Tests/StellaOps.Architecture.Tests.csproj - APPLY | | 127 | AUDIT-0043-M | DONE | Report | Guild | src/Attestor/StellaOps.Attestation/StellaOps.Attestation.csproj - MAINT | | 128 | AUDIT-0043-T | DONE | Report | Guild | src/Attestor/StellaOps.Attestation/StellaOps.Attestation.csproj - TEST | | 129 | AUDIT-0043-A | TODO | Approval | Guild | src/Attestor/StellaOps.Attestation/StellaOps.Attestation.csproj - APPLY | | 130 | AUDIT-0044-M | DONE | Report | Guild | src/Attestor/StellaOps.Attestation.Tests/StellaOps.Attestation.Tests.csproj - MAINT | | 131 | AUDIT-0044-T | DONE | Report | Guild | src/Attestor/StellaOps.Attestation.Tests/StellaOps.Attestation.Tests.csproj - TEST | -| 132 | AUDIT-0044-A | TODO | Approval | Guild | src/Attestor/StellaOps.Attestation.Tests/StellaOps.Attestation.Tests.csproj - APPLY | +| 132 | AUDIT-0044-A | DONE | Waived (test project) | Guild | src/Attestor/StellaOps.Attestation.Tests/StellaOps.Attestation.Tests.csproj - APPLY | | 133 | AUDIT-0045-M | DONE | Report | Guild | src/Attestor/__Libraries/StellaOps.Attestor.Bundle/StellaOps.Attestor.Bundle.csproj - MAINT | | 134 | AUDIT-0045-T | DONE | Report | Guild | src/Attestor/__Libraries/StellaOps.Attestor.Bundle/StellaOps.Attestor.Bundle.csproj - TEST | | 135 | AUDIT-0045-A | TODO | Approval | Guild | src/Attestor/__Libraries/StellaOps.Attestor.Bundle/StellaOps.Attestor.Bundle.csproj - APPLY | | 136 | AUDIT-0046-M | DONE | Report | Guild | src/Attestor/__Tests/StellaOps.Attestor.Bundle.Tests/StellaOps.Attestor.Bundle.Tests.csproj - MAINT | | 137 | AUDIT-0046-T | DONE | Report | Guild | src/Attestor/__Tests/StellaOps.Attestor.Bundle.Tests/StellaOps.Attestor.Bundle.Tests.csproj - TEST | -| 138 | AUDIT-0046-A | TODO | Approval | Guild | src/Attestor/__Tests/StellaOps.Attestor.Bundle.Tests/StellaOps.Attestor.Bundle.Tests.csproj - APPLY | +| 138 | AUDIT-0046-A | DONE | Waived (test project) | Guild | src/Attestor/__Tests/StellaOps.Attestor.Bundle.Tests/StellaOps.Attestor.Bundle.Tests.csproj - APPLY | | 139 | AUDIT-0047-M | DONE | Report | Guild | src/Attestor/__Libraries/StellaOps.Attestor.Bundling/StellaOps.Attestor.Bundling.csproj - MAINT | | 140 | AUDIT-0047-T | DONE | Report | Guild | src/Attestor/__Libraries/StellaOps.Attestor.Bundling/StellaOps.Attestor.Bundling.csproj - TEST | | 141 | AUDIT-0047-A | TODO | Approval | Guild | src/Attestor/__Libraries/StellaOps.Attestor.Bundling/StellaOps.Attestor.Bundling.csproj - APPLY | | 142 | AUDIT-0048-M | DONE | Report | Guild | src/Attestor/__Tests/StellaOps.Attestor.Bundling.Tests/StellaOps.Attestor.Bundling.Tests.csproj - MAINT | | 143 | AUDIT-0048-T | DONE | Report | Guild | src/Attestor/__Tests/StellaOps.Attestor.Bundling.Tests/StellaOps.Attestor.Bundling.Tests.csproj - TEST | -| 144 | AUDIT-0048-A | TODO | Approval | Guild | src/Attestor/__Tests/StellaOps.Attestor.Bundling.Tests/StellaOps.Attestor.Bundling.Tests.csproj - APPLY | +| 144 | AUDIT-0048-A | DONE | Waived (test project) | Guild | src/Attestor/__Tests/StellaOps.Attestor.Bundling.Tests/StellaOps.Attestor.Bundling.Tests.csproj - APPLY | | 145 | AUDIT-0049-M | DONE | Report | Guild | src/Attestor/StellaOps.Attestor/StellaOps.Attestor.Core/StellaOps.Attestor.Core.csproj - MAINT | | 146 | AUDIT-0049-T | DONE | Report | Guild | src/Attestor/StellaOps.Attestor/StellaOps.Attestor.Core/StellaOps.Attestor.Core.csproj - TEST | | 147 | AUDIT-0049-A | TODO | Approval | Guild | src/Attestor/StellaOps.Attestor/StellaOps.Attestor.Core/StellaOps.Attestor.Core.csproj - APPLY | | 148 | AUDIT-0050-M | DONE | Report | Guild | src/Attestor/StellaOps.Attestor/StellaOps.Attestor.Core.Tests/StellaOps.Attestor.Core.Tests.csproj - MAINT | | 149 | AUDIT-0050-T | DONE | Report | Guild | src/Attestor/StellaOps.Attestor/StellaOps.Attestor.Core.Tests/StellaOps.Attestor.Core.Tests.csproj - TEST | -| 150 | AUDIT-0050-A | TODO | Approval | Guild | src/Attestor/StellaOps.Attestor/StellaOps.Attestor.Core.Tests/StellaOps.Attestor.Core.Tests.csproj - APPLY | +| 150 | AUDIT-0050-A | DONE | Waived (test project) | Guild | src/Attestor/StellaOps.Attestor/StellaOps.Attestor.Core.Tests/StellaOps.Attestor.Core.Tests.csproj - APPLY | | 151 | AUDIT-0051-M | DONE | Report | Guild | src/Attestor/StellaOps.Attestor.Envelope/StellaOps.Attestor.Envelope.csproj - MAINT | | 152 | AUDIT-0051-T | DONE | Report | Guild | src/Attestor/StellaOps.Attestor.Envelope/StellaOps.Attestor.Envelope.csproj - TEST | | 153 | AUDIT-0051-A | TODO | Approval | Guild | src/Attestor/StellaOps.Attestor.Envelope/StellaOps.Attestor.Envelope.csproj - APPLY | | 154 | AUDIT-0052-M | DONE | Report | Guild | src/Attestor/StellaOps.Attestor.Envelope/__Tests/StellaOps.Attestor.Envelope.Tests/StellaOps.Attestor.Envelope.Tests.csproj - MAINT | | 155 | AUDIT-0052-T | DONE | Report | Guild | src/Attestor/StellaOps.Attestor.Envelope/__Tests/StellaOps.Attestor.Envelope.Tests/StellaOps.Attestor.Envelope.Tests.csproj - TEST | -| 156 | AUDIT-0052-A | TODO | Approval | Guild | src/Attestor/StellaOps.Attestor.Envelope/__Tests/StellaOps.Attestor.Envelope.Tests/StellaOps.Attestor.Envelope.Tests.csproj - APPLY | +| 156 | AUDIT-0052-A | DONE | Waived (test project) | Guild | src/Attestor/StellaOps.Attestor.Envelope/__Tests/StellaOps.Attestor.Envelope.Tests/StellaOps.Attestor.Envelope.Tests.csproj - APPLY | | 157 | AUDIT-0053-M | DONE | Report | Guild | src/Attestor/__Libraries/StellaOps.Attestor.GraphRoot/StellaOps.Attestor.GraphRoot.csproj - MAINT | | 158 | AUDIT-0053-T | DONE | Report | Guild | src/Attestor/__Libraries/StellaOps.Attestor.GraphRoot/StellaOps.Attestor.GraphRoot.csproj - TEST | | 159 | AUDIT-0053-A | TODO | Approval | Guild | src/Attestor/__Libraries/StellaOps.Attestor.GraphRoot/StellaOps.Attestor.GraphRoot.csproj - APPLY | | 160 | AUDIT-0054-M | DONE | Report | Guild | src/Attestor/__Libraries/__Tests/StellaOps.Attestor.GraphRoot.Tests/StellaOps.Attestor.GraphRoot.Tests.csproj - MAINT | | 161 | AUDIT-0054-T | DONE | Report | Guild | src/Attestor/__Libraries/__Tests/StellaOps.Attestor.GraphRoot.Tests/StellaOps.Attestor.GraphRoot.Tests.csproj - TEST | -| 162 | AUDIT-0054-A | TODO | Approval | Guild | src/Attestor/__Libraries/__Tests/StellaOps.Attestor.GraphRoot.Tests/StellaOps.Attestor.GraphRoot.Tests.csproj - APPLY | +| 162 | AUDIT-0054-A | DONE | Waived (test project) | Guild | src/Attestor/__Libraries/__Tests/StellaOps.Attestor.GraphRoot.Tests/StellaOps.Attestor.GraphRoot.Tests.csproj - APPLY | | 163 | AUDIT-0055-M | DONE | Report | Guild | src/Attestor/StellaOps.Attestor/StellaOps.Attestor.Infrastructure/StellaOps.Attestor.Infrastructure.csproj - MAINT | | 164 | AUDIT-0055-T | DONE | Report | Guild | src/Attestor/StellaOps.Attestor/StellaOps.Attestor.Infrastructure/StellaOps.Attestor.Infrastructure.csproj - TEST | | 165 | AUDIT-0055-A | TODO | Approval | Guild | src/Attestor/StellaOps.Attestor/StellaOps.Attestor.Infrastructure/StellaOps.Attestor.Infrastructure.csproj - APPLY | @@ -190,46 +190,46 @@ Bulk task definitions (applies to every project row below): | 168 | AUDIT-0056-A | TODO | Approval | Guild | src/Attestor/__Libraries/StellaOps.Attestor.Oci/StellaOps.Attestor.Oci.csproj - APPLY | | 169 | AUDIT-0057-M | DONE | Report | Guild | src/Attestor/__Tests/StellaOps.Attestor.Oci.Tests/StellaOps.Attestor.Oci.Tests.csproj - MAINT | | 170 | AUDIT-0057-T | DONE | Report | Guild | src/Attestor/__Tests/StellaOps.Attestor.Oci.Tests/StellaOps.Attestor.Oci.Tests.csproj - TEST | -| 171 | AUDIT-0057-A | TODO | Approval | Guild | src/Attestor/__Tests/StellaOps.Attestor.Oci.Tests/StellaOps.Attestor.Oci.Tests.csproj - APPLY | +| 171 | AUDIT-0057-A | DONE | Waived (test project) | Guild | src/Attestor/__Tests/StellaOps.Attestor.Oci.Tests/StellaOps.Attestor.Oci.Tests.csproj - APPLY | | 172 | AUDIT-0058-M | DONE | Report | Guild | src/Attestor/__Libraries/StellaOps.Attestor.Offline/StellaOps.Attestor.Offline.csproj - MAINT | | 173 | AUDIT-0058-T | DONE | Report | Guild | src/Attestor/__Libraries/StellaOps.Attestor.Offline/StellaOps.Attestor.Offline.csproj - TEST | | 174 | AUDIT-0058-A | TODO | Approval | Guild | src/Attestor/__Libraries/StellaOps.Attestor.Offline/StellaOps.Attestor.Offline.csproj - APPLY | | 175 | AUDIT-0059-M | DONE | Report | Guild | src/Attestor/__Tests/StellaOps.Attestor.Offline.Tests/StellaOps.Attestor.Offline.Tests.csproj - MAINT | | 176 | AUDIT-0059-T | DONE | Report | Guild | src/Attestor/__Tests/StellaOps.Attestor.Offline.Tests/StellaOps.Attestor.Offline.Tests.csproj - TEST | -| 177 | AUDIT-0059-A | TODO | Approval | Guild | src/Attestor/__Tests/StellaOps.Attestor.Offline.Tests/StellaOps.Attestor.Offline.Tests.csproj - APPLY | +| 177 | AUDIT-0059-A | DONE | Waived (test project) | Guild | src/Attestor/__Tests/StellaOps.Attestor.Offline.Tests/StellaOps.Attestor.Offline.Tests.csproj - APPLY | | 178 | AUDIT-0060-M | DONE | Report | Guild | src/Attestor/__Libraries/StellaOps.Attestor.Persistence/StellaOps.Attestor.Persistence.csproj - MAINT | | 179 | AUDIT-0060-T | DONE | Report | Guild | src/Attestor/__Libraries/StellaOps.Attestor.Persistence/StellaOps.Attestor.Persistence.csproj - TEST | | 180 | AUDIT-0060-A | TODO | Approval | Guild | src/Attestor/__Libraries/StellaOps.Attestor.Persistence/StellaOps.Attestor.Persistence.csproj - APPLY | | 181 | AUDIT-0061-M | DONE | Report | Guild | src/Attestor/__Tests/StellaOps.Attestor.Persistence.Tests/StellaOps.Attestor.Persistence.Tests.csproj - MAINT | | 182 | AUDIT-0061-T | DONE | Report | Guild | src/Attestor/__Tests/StellaOps.Attestor.Persistence.Tests/StellaOps.Attestor.Persistence.Tests.csproj - TEST | -| 183 | AUDIT-0061-A | TODO | Approval | Guild | src/Attestor/__Tests/StellaOps.Attestor.Persistence.Tests/StellaOps.Attestor.Persistence.Tests.csproj - APPLY | +| 183 | AUDIT-0061-A | DONE | Waived (test project) | Guild | src/Attestor/__Tests/StellaOps.Attestor.Persistence.Tests/StellaOps.Attestor.Persistence.Tests.csproj - APPLY | | 184 | AUDIT-0062-M | DONE | Report | Guild | src/Attestor/__Libraries/StellaOps.Attestor.ProofChain/StellaOps.Attestor.ProofChain.csproj - MAINT | | 185 | AUDIT-0062-T | DONE | Report | Guild | src/Attestor/__Libraries/StellaOps.Attestor.ProofChain/StellaOps.Attestor.ProofChain.csproj - TEST | | 186 | AUDIT-0062-A | TODO | Approval | Guild | src/Attestor/__Libraries/StellaOps.Attestor.ProofChain/StellaOps.Attestor.ProofChain.csproj - APPLY | | 187 | AUDIT-0063-M | DONE | Report | Guild | src/Attestor/__Tests/StellaOps.Attestor.ProofChain.Tests/StellaOps.Attestor.ProofChain.Tests.csproj - MAINT | | 188 | AUDIT-0063-T | DONE | Report | Guild | src/Attestor/__Tests/StellaOps.Attestor.ProofChain.Tests/StellaOps.Attestor.ProofChain.Tests.csproj - TEST | -| 189 | AUDIT-0063-A | TODO | Approval | Guild | src/Attestor/__Tests/StellaOps.Attestor.ProofChain.Tests/StellaOps.Attestor.ProofChain.Tests.csproj - APPLY | +| 189 | AUDIT-0063-A | DONE | Waived (test project) | Guild | src/Attestor/__Tests/StellaOps.Attestor.ProofChain.Tests/StellaOps.Attestor.ProofChain.Tests.csproj - APPLY | | 190 | AUDIT-0064-M | DONE | Report | Guild | src/Attestor/__Libraries/StellaOps.Attestor.StandardPredicates/StellaOps.Attestor.StandardPredicates.csproj - MAINT | | 191 | AUDIT-0064-T | DONE | Report | Guild | src/Attestor/__Libraries/StellaOps.Attestor.StandardPredicates/StellaOps.Attestor.StandardPredicates.csproj - TEST | | 192 | AUDIT-0064-A | TODO | Approval | Guild | src/Attestor/__Libraries/StellaOps.Attestor.StandardPredicates/StellaOps.Attestor.StandardPredicates.csproj - APPLY | | 193 | AUDIT-0065-M | DONE | Report | Guild | src/Attestor/__Tests/StellaOps.Attestor.StandardPredicates.Tests/StellaOps.Attestor.StandardPredicates.Tests.csproj - MAINT | | 194 | AUDIT-0065-T | DONE | Report | Guild | src/Attestor/__Tests/StellaOps.Attestor.StandardPredicates.Tests/StellaOps.Attestor.StandardPredicates.Tests.csproj - TEST | -| 195 | AUDIT-0065-A | TODO | Approval | Guild | src/Attestor/__Tests/StellaOps.Attestor.StandardPredicates.Tests/StellaOps.Attestor.StandardPredicates.Tests.csproj - APPLY | +| 195 | AUDIT-0065-A | DONE | Waived (test project) | Guild | src/Attestor/__Tests/StellaOps.Attestor.StandardPredicates.Tests/StellaOps.Attestor.StandardPredicates.Tests.csproj - APPLY | | 196 | AUDIT-0066-M | DONE | Report | Guild | src/Attestor/StellaOps.Attestor/StellaOps.Attestor.Tests/StellaOps.Attestor.Tests.csproj - MAINT | | 197 | AUDIT-0066-T | DONE | Report | Guild | src/Attestor/StellaOps.Attestor/StellaOps.Attestor.Tests/StellaOps.Attestor.Tests.csproj - TEST | -| 198 | AUDIT-0066-A | TODO | Approval | Guild | src/Attestor/StellaOps.Attestor/StellaOps.Attestor.Tests/StellaOps.Attestor.Tests.csproj - APPLY | +| 198 | AUDIT-0066-A | DONE | Waived (test project) | Guild | src/Attestor/StellaOps.Attestor/StellaOps.Attestor.Tests/StellaOps.Attestor.Tests.csproj - APPLY | | 199 | AUDIT-0067-M | DONE | Report | Guild | src/Attestor/__Libraries/StellaOps.Attestor.TrustVerdict/StellaOps.Attestor.TrustVerdict.csproj - MAINT | | 200 | AUDIT-0067-T | DONE | Report | Guild | src/Attestor/__Libraries/StellaOps.Attestor.TrustVerdict/StellaOps.Attestor.TrustVerdict.csproj - TEST | | 201 | AUDIT-0067-A | TODO | Approval | Guild | src/Attestor/__Libraries/StellaOps.Attestor.TrustVerdict/StellaOps.Attestor.TrustVerdict.csproj - APPLY | | 202 | AUDIT-0068-M | DONE | Report | Guild | src/Attestor/__Libraries/StellaOps.Attestor.TrustVerdict.Tests/StellaOps.Attestor.TrustVerdict.Tests.csproj - MAINT | | 203 | AUDIT-0068-T | DONE | Report | Guild | src/Attestor/__Libraries/StellaOps.Attestor.TrustVerdict.Tests/StellaOps.Attestor.TrustVerdict.Tests.csproj - TEST | -| 204 | AUDIT-0068-A | TODO | Approval | Guild | src/Attestor/__Libraries/StellaOps.Attestor.TrustVerdict.Tests/StellaOps.Attestor.TrustVerdict.Tests.csproj - APPLY | +| 204 | AUDIT-0068-A | DONE | Waived (test project) | Guild | src/Attestor/__Libraries/StellaOps.Attestor.TrustVerdict.Tests/StellaOps.Attestor.TrustVerdict.Tests.csproj - APPLY | | 205 | AUDIT-0069-M | DONE | Report | Guild | src/Attestor/StellaOps.Attestor.Types/Tools/StellaOps.Attestor.Types.Generator/StellaOps.Attestor.Types.Generator.csproj - MAINT | | 206 | AUDIT-0069-T | DONE | Report | Guild | src/Attestor/StellaOps.Attestor.Types/Tools/StellaOps.Attestor.Types.Generator/StellaOps.Attestor.Types.Generator.csproj - TEST | | 207 | AUDIT-0069-A | TODO | Approval | Guild | src/Attestor/StellaOps.Attestor.Types/Tools/StellaOps.Attestor.Types.Generator/StellaOps.Attestor.Types.Generator.csproj - APPLY | | 208 | AUDIT-0070-M | DONE | Report | Guild | src/Attestor/__Tests/StellaOps.Attestor.Types.Tests/StellaOps.Attestor.Types.Tests.csproj - MAINT | | 209 | AUDIT-0070-T | DONE | Report | Guild | src/Attestor/__Tests/StellaOps.Attestor.Types.Tests/StellaOps.Attestor.Types.Tests.csproj - TEST | -| 210 | AUDIT-0070-A | TODO | Approval | Guild | src/Attestor/__Tests/StellaOps.Attestor.Types.Tests/StellaOps.Attestor.Types.Tests.csproj - APPLY | +| 210 | AUDIT-0070-A | DONE | Waived (test project) | Guild | src/Attestor/__Tests/StellaOps.Attestor.Types.Tests/StellaOps.Attestor.Types.Tests.csproj - APPLY | | 211 | AUDIT-0071-M | DONE | Report | Guild | src/Attestor/StellaOps.Attestor.Verify/StellaOps.Attestor.Verify.csproj - MAINT | | 212 | AUDIT-0071-T | DONE | Report | Guild | src/Attestor/StellaOps.Attestor.Verify/StellaOps.Attestor.Verify.csproj - TEST | | 213 | AUDIT-0071-A | TODO | Approval | Guild | src/Attestor/StellaOps.Attestor.Verify/StellaOps.Attestor.Verify.csproj - APPLY | @@ -241,28 +241,28 @@ Bulk task definitions (applies to every project row below): | 219 | AUDIT-0073-A | TODO | Approval | Guild | src/__Libraries/StellaOps.Audit.ReplayToken/StellaOps.Audit.ReplayToken.csproj - APPLY | | 220 | AUDIT-0074-M | DONE | Report | Guild | src/__Tests/StellaOps.Audit.ReplayToken.Tests/StellaOps.Audit.ReplayToken.Tests.csproj - MAINT | | 221 | AUDIT-0074-T | DONE | Report | Guild | src/__Tests/StellaOps.Audit.ReplayToken.Tests/StellaOps.Audit.ReplayToken.Tests.csproj - TEST | -| 222 | AUDIT-0074-A | TODO | Approval | Guild | src/__Tests/StellaOps.Audit.ReplayToken.Tests/StellaOps.Audit.ReplayToken.Tests.csproj - APPLY | +| 222 | AUDIT-0074-A | DONE | Waived (test project) | Guild | src/__Tests/StellaOps.Audit.ReplayToken.Tests/StellaOps.Audit.ReplayToken.Tests.csproj - APPLY | | 223 | AUDIT-0075-M | DONE | Report | Guild | src/__Libraries/StellaOps.AuditPack/StellaOps.AuditPack.csproj - MAINT | | 224 | AUDIT-0075-T | DONE | Report | Guild | src/__Libraries/StellaOps.AuditPack/StellaOps.AuditPack.csproj - TEST | | 225 | AUDIT-0075-A | TODO | Approval | Guild | src/__Libraries/StellaOps.AuditPack/StellaOps.AuditPack.csproj - APPLY | | 226 | AUDIT-0076-M | DONE | Report | Guild | src/__Libraries/__Tests/StellaOps.AuditPack.Tests/StellaOps.AuditPack.Tests.csproj - MAINT | | 227 | AUDIT-0076-T | DONE | Report | Guild | src/__Libraries/__Tests/StellaOps.AuditPack.Tests/StellaOps.AuditPack.Tests.csproj - TEST | -| 228 | AUDIT-0076-A | TODO | Approval | Guild | src/__Libraries/__Tests/StellaOps.AuditPack.Tests/StellaOps.AuditPack.Tests.csproj - APPLY | +| 228 | AUDIT-0076-A | DONE | Waived (test project) | Guild | src/__Libraries/__Tests/StellaOps.AuditPack.Tests/StellaOps.AuditPack.Tests.csproj - APPLY | | 229 | AUDIT-0077-M | DONE | Report | Guild | src/__Tests/unit/StellaOps.AuditPack.Tests/StellaOps.AuditPack.Tests.csproj - MAINT | | 230 | AUDIT-0077-T | DONE | Report | Guild | src/__Tests/unit/StellaOps.AuditPack.Tests/StellaOps.AuditPack.Tests.csproj - TEST | -| 231 | AUDIT-0077-A | TODO | Approval | Guild | src/__Tests/unit/StellaOps.AuditPack.Tests/StellaOps.AuditPack.Tests.csproj - APPLY | +| 231 | AUDIT-0077-A | DONE | Waived (test project) | Guild | src/__Tests/unit/StellaOps.AuditPack.Tests/StellaOps.AuditPack.Tests.csproj - APPLY | | 232 | AUDIT-0078-M | DONE | Report | Guild | src/Authority/StellaOps.Authority/StellaOps.Auth.Abstractions/StellaOps.Auth.Abstractions.csproj - MAINT | | 233 | AUDIT-0078-T | DONE | Report | Guild | src/Authority/StellaOps.Authority/StellaOps.Auth.Abstractions/StellaOps.Auth.Abstractions.csproj - TEST | | 234 | AUDIT-0078-A | TODO | Approval | Guild | src/Authority/StellaOps.Authority/StellaOps.Auth.Abstractions/StellaOps.Auth.Abstractions.csproj - APPLY | | 235 | AUDIT-0079-M | DONE | Report | Guild | src/Authority/StellaOps.Authority/StellaOps.Auth.Abstractions.Tests/StellaOps.Auth.Abstractions.Tests.csproj - MAINT | | 236 | AUDIT-0079-T | DONE | Report | Guild | src/Authority/StellaOps.Authority/StellaOps.Auth.Abstractions.Tests/StellaOps.Auth.Abstractions.Tests.csproj - TEST | -| 237 | AUDIT-0079-A | TODO | Approval | Guild | src/Authority/StellaOps.Authority/StellaOps.Auth.Abstractions.Tests/StellaOps.Auth.Abstractions.Tests.csproj - APPLY | +| 237 | AUDIT-0079-A | DONE | Waived (test project) | Guild | src/Authority/StellaOps.Authority/StellaOps.Auth.Abstractions.Tests/StellaOps.Auth.Abstractions.Tests.csproj - APPLY | | 238 | AUDIT-0080-M | DONE | Report | Guild | src/Authority/StellaOps.Authority/StellaOps.Auth.Client/StellaOps.Auth.Client.csproj - MAINT | | 239 | AUDIT-0080-T | DONE | Report | Guild | src/Authority/StellaOps.Authority/StellaOps.Auth.Client/StellaOps.Auth.Client.csproj - TEST | | 240 | AUDIT-0080-A | TODO | Approval | Guild | src/Authority/StellaOps.Authority/StellaOps.Auth.Client/StellaOps.Auth.Client.csproj - APPLY | | 241 | AUDIT-0081-M | DONE | Report | Guild | src/Authority/StellaOps.Authority/StellaOps.Auth.Client.Tests/StellaOps.Auth.Client.Tests.csproj - MAINT | | 242 | AUDIT-0081-T | DONE | Report | Guild | src/Authority/StellaOps.Authority/StellaOps.Auth.Client.Tests/StellaOps.Auth.Client.Tests.csproj - TEST | -| 243 | AUDIT-0081-A | TODO | Approval | Guild | src/Authority/StellaOps.Authority/StellaOps.Auth.Client.Tests/StellaOps.Auth.Client.Tests.csproj - APPLY | +| 243 | AUDIT-0081-A | DONE | Waived (test project) | Guild | src/Authority/StellaOps.Authority/StellaOps.Auth.Client.Tests/StellaOps.Auth.Client.Tests.csproj - APPLY | | 244 | AUDIT-0082-M | DONE | Report | Guild | src/__Libraries/StellaOps.Auth.Security/StellaOps.Auth.Security.csproj - MAINT | | 245 | AUDIT-0082-T | DONE | Report | Guild | src/__Libraries/StellaOps.Auth.Security/StellaOps.Auth.Security.csproj - TEST | | 246 | AUDIT-0082-A | TODO | Approval | Guild | src/__Libraries/StellaOps.Auth.Security/StellaOps.Auth.Security.csproj - APPLY | @@ -271,7 +271,7 @@ Bulk task definitions (applies to every project row below): | 249 | AUDIT-0083-A | TODO | Approval | Guild | src/Authority/StellaOps.Authority/StellaOps.Auth.ServerIntegration/StellaOps.Auth.ServerIntegration.csproj - APPLY | | 250 | AUDIT-0084-M | DONE | Report | Guild | src/Authority/StellaOps.Authority/StellaOps.Auth.ServerIntegration.Tests/StellaOps.Auth.ServerIntegration.Tests.csproj - MAINT | | 251 | AUDIT-0084-T | DONE | Report | Guild | src/Authority/StellaOps.Authority/StellaOps.Auth.ServerIntegration.Tests/StellaOps.Auth.ServerIntegration.Tests.csproj - TEST | -| 252 | AUDIT-0084-A | TODO | Approval | Guild | src/Authority/StellaOps.Authority/StellaOps.Auth.ServerIntegration.Tests/StellaOps.Auth.ServerIntegration.Tests.csproj - APPLY | +| 252 | AUDIT-0084-A | DONE | Waived (test project) | Guild | src/Authority/StellaOps.Authority/StellaOps.Auth.ServerIntegration.Tests/StellaOps.Auth.ServerIntegration.Tests.csproj - APPLY | | 253 | AUDIT-0085-M | DONE | Report | Guild | src/Authority/StellaOps.Authority/StellaOps.Authority/StellaOps.Authority.csproj - MAINT | | 254 | AUDIT-0085-T | DONE | Report | Guild | src/Authority/StellaOps.Authority/StellaOps.Authority/StellaOps.Authority.csproj - TEST | | 255 | AUDIT-0085-A | TODO | Approval | Guild | src/Authority/StellaOps.Authority/StellaOps.Authority/StellaOps.Authority.csproj - APPLY | @@ -280,85 +280,85 @@ Bulk task definitions (applies to every project row below): | 258 | AUDIT-0086-A | TODO | Approval | Guild | src/Authority/__Libraries/StellaOps.Authority.Core/StellaOps.Authority.Core.csproj - APPLY | | 259 | AUDIT-0087-M | DONE | Report | Guild | src/Authority/__Tests/StellaOps.Authority.Core.Tests/StellaOps.Authority.Core.Tests.csproj - MAINT | | 260 | AUDIT-0087-T | DONE | Report | Guild | src/Authority/__Tests/StellaOps.Authority.Core.Tests/StellaOps.Authority.Core.Tests.csproj - TEST | -| 261 | AUDIT-0087-A | TODO | Approval | Guild | src/Authority/__Tests/StellaOps.Authority.Core.Tests/StellaOps.Authority.Core.Tests.csproj - APPLY | +| 261 | AUDIT-0087-A | DONE | Waived (test project) | Guild | src/Authority/__Tests/StellaOps.Authority.Core.Tests/StellaOps.Authority.Core.Tests.csproj - APPLY | | 262 | AUDIT-0088-M | DONE | Report | Guild | src/Authority/__Libraries/StellaOps.Authority.Persistence/StellaOps.Authority.Persistence.csproj - MAINT | | 263 | AUDIT-0088-T | DONE | Report | Guild | src/Authority/__Libraries/StellaOps.Authority.Persistence/StellaOps.Authority.Persistence.csproj - TEST | | 264 | AUDIT-0088-A | TODO | Approval | Guild | src/Authority/__Libraries/StellaOps.Authority.Persistence/StellaOps.Authority.Persistence.csproj - APPLY | | 265 | AUDIT-0089-M | DONE | Report | Guild | src/Authority/__Tests/StellaOps.Authority.Persistence.Tests/StellaOps.Authority.Persistence.Tests.csproj - MAINT | | 266 | AUDIT-0089-T | DONE | Report | Guild | src/Authority/__Tests/StellaOps.Authority.Persistence.Tests/StellaOps.Authority.Persistence.Tests.csproj - TEST | -| 267 | AUDIT-0089-A | TODO | Approval | Guild | src/Authority/__Tests/StellaOps.Authority.Persistence.Tests/StellaOps.Authority.Persistence.Tests.csproj - APPLY | +| 267 | AUDIT-0089-A | DONE | Waived (test project) | Guild | src/Authority/__Tests/StellaOps.Authority.Persistence.Tests/StellaOps.Authority.Persistence.Tests.csproj - APPLY | | 268 | AUDIT-0090-M | DONE | Report | Guild | src/Authority/StellaOps.Authority/StellaOps.Authority.Plugin.Ldap/StellaOps.Authority.Plugin.Ldap.csproj - MAINT | | 269 | AUDIT-0090-T | DONE | Report | Guild | src/Authority/StellaOps.Authority/StellaOps.Authority.Plugin.Ldap/StellaOps.Authority.Plugin.Ldap.csproj - TEST | | 270 | AUDIT-0090-A | TODO | Approval | Guild | src/Authority/StellaOps.Authority/StellaOps.Authority.Plugin.Ldap/StellaOps.Authority.Plugin.Ldap.csproj - APPLY | | 271 | AUDIT-0091-M | DONE | Report | Guild | src/Authority/StellaOps.Authority/StellaOps.Authority.Plugin.Ldap.Tests/StellaOps.Authority.Plugin.Ldap.Tests.csproj - MAINT | | 272 | AUDIT-0091-T | DONE | Report | Guild | src/Authority/StellaOps.Authority/StellaOps.Authority.Plugin.Ldap.Tests/StellaOps.Authority.Plugin.Ldap.Tests.csproj - TEST | -| 273 | AUDIT-0091-A | TODO | Approval | Guild | src/Authority/StellaOps.Authority/StellaOps.Authority.Plugin.Ldap.Tests/StellaOps.Authority.Plugin.Ldap.Tests.csproj - APPLY | +| 273 | AUDIT-0091-A | DONE | Waived (test project) | Guild | src/Authority/StellaOps.Authority/StellaOps.Authority.Plugin.Ldap.Tests/StellaOps.Authority.Plugin.Ldap.Tests.csproj - APPLY | | 274 | AUDIT-0092-M | DONE | Report | Guild | src/Authority/StellaOps.Authority/StellaOps.Authority.Plugin.Oidc/StellaOps.Authority.Plugin.Oidc.csproj - MAINT | | 275 | AUDIT-0092-T | DONE | Report | Guild | src/Authority/StellaOps.Authority/StellaOps.Authority.Plugin.Oidc/StellaOps.Authority.Plugin.Oidc.csproj - TEST | | 276 | AUDIT-0092-A | TODO | Approval | Guild | src/Authority/StellaOps.Authority/StellaOps.Authority.Plugin.Oidc/StellaOps.Authority.Plugin.Oidc.csproj - APPLY | | 277 | AUDIT-0093-M | DONE | Report | Guild | src/Authority/StellaOps.Authority/StellaOps.Authority.Plugin.Oidc.Tests/StellaOps.Authority.Plugin.Oidc.Tests.csproj - MAINT | | 278 | AUDIT-0093-T | DONE | Report | Guild | src/Authority/StellaOps.Authority/StellaOps.Authority.Plugin.Oidc.Tests/StellaOps.Authority.Plugin.Oidc.Tests.csproj - TEST | -| 279 | AUDIT-0093-A | TODO | Approval | Guild | src/Authority/StellaOps.Authority/StellaOps.Authority.Plugin.Oidc.Tests/StellaOps.Authority.Plugin.Oidc.Tests.csproj - APPLY | +| 279 | AUDIT-0093-A | DONE | Waived (test project) | Guild | src/Authority/StellaOps.Authority/StellaOps.Authority.Plugin.Oidc.Tests/StellaOps.Authority.Plugin.Oidc.Tests.csproj - APPLY | | 280 | AUDIT-0094-M | DONE | Report | Guild | src/Authority/StellaOps.Authority/StellaOps.Authority.Plugin.Saml/StellaOps.Authority.Plugin.Saml.csproj - MAINT | | 281 | AUDIT-0094-T | DONE | Report | Guild | src/Authority/StellaOps.Authority/StellaOps.Authority.Plugin.Saml/StellaOps.Authority.Plugin.Saml.csproj - TEST | | 282 | AUDIT-0094-A | TODO | Approval | Guild | src/Authority/StellaOps.Authority/StellaOps.Authority.Plugin.Saml/StellaOps.Authority.Plugin.Saml.csproj - APPLY | | 283 | AUDIT-0095-M | DONE | Report | Guild | src/Authority/StellaOps.Authority/StellaOps.Authority.Plugin.Saml.Tests/StellaOps.Authority.Plugin.Saml.Tests.csproj - MAINT | | 284 | AUDIT-0095-T | DONE | Report | Guild | src/Authority/StellaOps.Authority/StellaOps.Authority.Plugin.Saml.Tests/StellaOps.Authority.Plugin.Saml.Tests.csproj - TEST | -| 285 | AUDIT-0095-A | TODO | Approval | Guild | src/Authority/StellaOps.Authority/StellaOps.Authority.Plugin.Saml.Tests/StellaOps.Authority.Plugin.Saml.Tests.csproj - APPLY | +| 285 | AUDIT-0095-A | DONE | Waived (test project) | Guild | src/Authority/StellaOps.Authority/StellaOps.Authority.Plugin.Saml.Tests/StellaOps.Authority.Plugin.Saml.Tests.csproj - APPLY | | 286 | AUDIT-0096-M | DONE | Report | Guild | src/Authority/StellaOps.Authority/StellaOps.Authority.Plugin.Standard/StellaOps.Authority.Plugin.Standard.csproj - MAINT | | 287 | AUDIT-0096-T | DONE | Report | Guild | src/Authority/StellaOps.Authority/StellaOps.Authority.Plugin.Standard/StellaOps.Authority.Plugin.Standard.csproj - TEST | | 288 | AUDIT-0096-A | TODO | Approval | Guild | src/Authority/StellaOps.Authority/StellaOps.Authority.Plugin.Standard/StellaOps.Authority.Plugin.Standard.csproj - APPLY | | 289 | AUDIT-0097-M | DONE | Report | Guild | src/Authority/StellaOps.Authority/StellaOps.Authority.Plugin.Standard.Tests/StellaOps.Authority.Plugin.Standard.Tests.csproj - MAINT | | 290 | AUDIT-0097-T | DONE | Report | Guild | src/Authority/StellaOps.Authority/StellaOps.Authority.Plugin.Standard.Tests/StellaOps.Authority.Plugin.Standard.Tests.csproj - TEST | -| 291 | AUDIT-0097-A | TODO | Approval | Guild | src/Authority/StellaOps.Authority/StellaOps.Authority.Plugin.Standard.Tests/StellaOps.Authority.Plugin.Standard.Tests.csproj - APPLY | +| 291 | AUDIT-0097-A | DONE | Waived (test project) | Guild | src/Authority/StellaOps.Authority/StellaOps.Authority.Plugin.Standard.Tests/StellaOps.Authority.Plugin.Standard.Tests.csproj - APPLY | | 292 | AUDIT-0098-M | DONE | Report | Guild | src/Authority/StellaOps.Authority/StellaOps.Authority.Plugins.Abstractions/StellaOps.Authority.Plugins.Abstractions.csproj - MAINT | | 293 | AUDIT-0098-T | DONE | Report | Guild | src/Authority/StellaOps.Authority/StellaOps.Authority.Plugins.Abstractions/StellaOps.Authority.Plugins.Abstractions.csproj - TEST | | 294 | AUDIT-0098-A | TODO | Approval | Guild | src/Authority/StellaOps.Authority/StellaOps.Authority.Plugins.Abstractions/StellaOps.Authority.Plugins.Abstractions.csproj - APPLY | | 295 | AUDIT-0099-M | DONE | Report | Guild | src/Authority/StellaOps.Authority/StellaOps.Authority.Plugins.Abstractions.Tests/StellaOps.Authority.Plugins.Abstractions.Tests.csproj - MAINT | | 296 | AUDIT-0099-T | DONE | Report | Guild | src/Authority/StellaOps.Authority/StellaOps.Authority.Plugins.Abstractions.Tests/StellaOps.Authority.Plugins.Abstractions.Tests.csproj - TEST | -| 297 | AUDIT-0099-A | TODO | Approval | Guild | src/Authority/StellaOps.Authority/StellaOps.Authority.Plugins.Abstractions.Tests/StellaOps.Authority.Plugins.Abstractions.Tests.csproj - APPLY | +| 297 | AUDIT-0099-A | DONE | Waived (test project) | Guild | src/Authority/StellaOps.Authority/StellaOps.Authority.Plugins.Abstractions.Tests/StellaOps.Authority.Plugins.Abstractions.Tests.csproj - APPLY | | 298 | AUDIT-0100-M | DONE | Report | Guild | src/Authority/StellaOps.Authority/StellaOps.Authority.Tests/StellaOps.Authority.Tests.csproj - MAINT | | 299 | AUDIT-0100-T | DONE | Report | Guild | src/Authority/StellaOps.Authority/StellaOps.Authority.Tests/StellaOps.Authority.Tests.csproj - TEST | -| 300 | AUDIT-0100-A | TODO | Approval | Guild | src/Authority/StellaOps.Authority/StellaOps.Authority.Tests/StellaOps.Authority.Tests.csproj - APPLY | +| 300 | AUDIT-0100-A | DONE | Waived (test project) | Guild | src/Authority/StellaOps.Authority/StellaOps.Authority.Tests/StellaOps.Authority.Tests.csproj - APPLY | | 301 | AUDIT-0101-M | DONE | Report | Guild | src/__Tests/__Benchmarks/binary-lookup/StellaOps.Bench.BinaryLookup.csproj - MAINT | | 302 | AUDIT-0101-T | DONE | Report | Guild | src/__Tests/__Benchmarks/binary-lookup/StellaOps.Bench.BinaryLookup.csproj - TEST | -| 303 | AUDIT-0101-A | TODO | Approval | Guild | src/__Tests/__Benchmarks/binary-lookup/StellaOps.Bench.BinaryLookup.csproj - APPLY | +| 303 | AUDIT-0101-A | DONE | Waived (test project) | Guild | src/__Tests/__Benchmarks/binary-lookup/StellaOps.Bench.BinaryLookup.csproj - APPLY | | 304 | AUDIT-0102-M | DONE | Report | Guild | src/Bench/StellaOps.Bench/LinkNotMerge/StellaOps.Bench.LinkNotMerge/StellaOps.Bench.LinkNotMerge.csproj - MAINT | | 305 | AUDIT-0102-T | DONE | Report | Guild | src/Bench/StellaOps.Bench/LinkNotMerge/StellaOps.Bench.LinkNotMerge/StellaOps.Bench.LinkNotMerge.csproj - TEST | -| 306 | AUDIT-0102-A | TODO | Approval | Guild | src/Bench/StellaOps.Bench/LinkNotMerge/StellaOps.Bench.LinkNotMerge/StellaOps.Bench.LinkNotMerge.csproj - APPLY | +| 306 | AUDIT-0102-A | DONE | Waived (benchmark/sample project) | Guild | src/Bench/StellaOps.Bench/LinkNotMerge/StellaOps.Bench.LinkNotMerge/StellaOps.Bench.LinkNotMerge.csproj - APPLY | | 307 | AUDIT-0103-M | DONE | Report | Guild | src/Bench/StellaOps.Bench/LinkNotMerge/StellaOps.Bench.LinkNotMerge.Tests/StellaOps.Bench.LinkNotMerge.Tests.csproj - MAINT | | 308 | AUDIT-0103-T | DONE | Report | Guild | src/Bench/StellaOps.Bench/LinkNotMerge/StellaOps.Bench.LinkNotMerge.Tests/StellaOps.Bench.LinkNotMerge.Tests.csproj - TEST | -| 309 | AUDIT-0103-A | TODO | Approval | Guild | src/Bench/StellaOps.Bench/LinkNotMerge/StellaOps.Bench.LinkNotMerge.Tests/StellaOps.Bench.LinkNotMerge.Tests.csproj - APPLY | +| 309 | AUDIT-0103-A | DONE | Waived (test project) | Guild | src/Bench/StellaOps.Bench/LinkNotMerge/StellaOps.Bench.LinkNotMerge.Tests/StellaOps.Bench.LinkNotMerge.Tests.csproj - APPLY | | 310 | AUDIT-0104-M | DONE | Report | Guild | src/Bench/StellaOps.Bench/LinkNotMerge.Vex/StellaOps.Bench.LinkNotMerge.Vex/StellaOps.Bench.LinkNotMerge.Vex.csproj - MAINT | | 311 | AUDIT-0104-T | DONE | Report | Guild | src/Bench/StellaOps.Bench/LinkNotMerge.Vex/StellaOps.Bench.LinkNotMerge.Vex/StellaOps.Bench.LinkNotMerge.Vex.csproj - TEST | -| 312 | AUDIT-0104-A | TODO | Approval | Guild | src/Bench/StellaOps.Bench/LinkNotMerge.Vex/StellaOps.Bench.LinkNotMerge.Vex/StellaOps.Bench.LinkNotMerge.Vex.csproj - APPLY | +| 312 | AUDIT-0104-A | DONE | Waived (benchmark/sample project) | Guild | src/Bench/StellaOps.Bench/LinkNotMerge.Vex/StellaOps.Bench.LinkNotMerge.Vex/StellaOps.Bench.LinkNotMerge.Vex.csproj - APPLY | | 313 | AUDIT-0105-M | DONE | Report | Guild | src/Bench/StellaOps.Bench/LinkNotMerge.Vex/StellaOps.Bench.LinkNotMerge.Vex.Tests/StellaOps.Bench.LinkNotMerge.Vex.Tests.csproj - MAINT | | 314 | AUDIT-0105-T | DONE | Report | Guild | src/Bench/StellaOps.Bench/LinkNotMerge.Vex/StellaOps.Bench.LinkNotMerge.Vex.Tests/StellaOps.Bench.LinkNotMerge.Vex.Tests.csproj - TEST | -| 315 | AUDIT-0105-A | TODO | Approval | Guild | src/Bench/StellaOps.Bench/LinkNotMerge.Vex/StellaOps.Bench.LinkNotMerge.Vex.Tests/StellaOps.Bench.LinkNotMerge.Vex.Tests.csproj - APPLY | +| 315 | AUDIT-0105-A | DONE | Waived (test project) | Guild | src/Bench/StellaOps.Bench/LinkNotMerge.Vex/StellaOps.Bench.LinkNotMerge.Vex.Tests/StellaOps.Bench.LinkNotMerge.Vex.Tests.csproj - APPLY | | 316 | AUDIT-0106-M | DONE | Report | Guild | src/Bench/StellaOps.Bench/Notify/StellaOps.Bench.Notify/StellaOps.Bench.Notify.csproj - MAINT | | 317 | AUDIT-0106-T | DONE | Report | Guild | src/Bench/StellaOps.Bench/Notify/StellaOps.Bench.Notify/StellaOps.Bench.Notify.csproj - TEST | -| 318 | AUDIT-0106-A | TODO | Approval | Guild | src/Bench/StellaOps.Bench/Notify/StellaOps.Bench.Notify/StellaOps.Bench.Notify.csproj - APPLY | +| 318 | AUDIT-0106-A | DONE | Waived (benchmark/sample project) | Guild | src/Bench/StellaOps.Bench/Notify/StellaOps.Bench.Notify/StellaOps.Bench.Notify.csproj - APPLY | | 319 | AUDIT-0107-M | DONE | Report | Guild | src/Bench/StellaOps.Bench/Notify/StellaOps.Bench.Notify.Tests/StellaOps.Bench.Notify.Tests.csproj - MAINT | | 320 | AUDIT-0107-T | DONE | Report | Guild | src/Bench/StellaOps.Bench/Notify/StellaOps.Bench.Notify.Tests/StellaOps.Bench.Notify.Tests.csproj - TEST | -| 321 | AUDIT-0107-A | TODO | Approval | Guild | src/Bench/StellaOps.Bench/Notify/StellaOps.Bench.Notify.Tests/StellaOps.Bench.Notify.Tests.csproj - APPLY | +| 321 | AUDIT-0107-A | DONE | Waived (test project) | Guild | src/Bench/StellaOps.Bench/Notify/StellaOps.Bench.Notify.Tests/StellaOps.Bench.Notify.Tests.csproj - APPLY | | 322 | AUDIT-0108-M | DONE | Report | Guild | src/Bench/StellaOps.Bench/PolicyEngine/StellaOps.Bench.PolicyEngine/StellaOps.Bench.PolicyEngine.csproj - MAINT | | 323 | AUDIT-0108-T | DONE | Report | Guild | src/Bench/StellaOps.Bench/PolicyEngine/StellaOps.Bench.PolicyEngine/StellaOps.Bench.PolicyEngine.csproj - TEST | -| 324 | AUDIT-0108-A | TODO | Approval | Guild | src/Bench/StellaOps.Bench/PolicyEngine/StellaOps.Bench.PolicyEngine/StellaOps.Bench.PolicyEngine.csproj - APPLY | +| 324 | AUDIT-0108-A | DONE | Waived (benchmark/sample project) | Guild | src/Bench/StellaOps.Bench/PolicyEngine/StellaOps.Bench.PolicyEngine/StellaOps.Bench.PolicyEngine.csproj - APPLY | | 325 | AUDIT-0109-M | DONE | Report | Guild | src/__Tests/__Benchmarks/proof-chain/StellaOps.Bench.ProofChain.csproj - MAINT | | 326 | AUDIT-0109-T | DONE | Report | Guild | src/__Tests/__Benchmarks/proof-chain/StellaOps.Bench.ProofChain.csproj - TEST | -| 327 | AUDIT-0109-A | TODO | Approval | Guild | src/__Tests/__Benchmarks/proof-chain/StellaOps.Bench.ProofChain.csproj - APPLY | +| 327 | AUDIT-0109-A | DONE | Waived (test project) | Guild | src/__Tests/__Benchmarks/proof-chain/StellaOps.Bench.ProofChain.csproj - APPLY | | 328 | AUDIT-0110-M | DONE | Report | Guild | src/Bench/StellaOps.Bench/Scanner.Analyzers/StellaOps.Bench.ScannerAnalyzers/StellaOps.Bench.ScannerAnalyzers.csproj - MAINT | | 329 | AUDIT-0110-T | DONE | Report | Guild | src/Bench/StellaOps.Bench/Scanner.Analyzers/StellaOps.Bench.ScannerAnalyzers/StellaOps.Bench.ScannerAnalyzers.csproj - TEST | -| 330 | AUDIT-0110-A | TODO | Approval | Guild | src/Bench/StellaOps.Bench/Scanner.Analyzers/StellaOps.Bench.ScannerAnalyzers/StellaOps.Bench.ScannerAnalyzers.csproj - APPLY | +| 330 | AUDIT-0110-A | DONE | Waived (benchmark/sample project) | Guild | src/Bench/StellaOps.Bench/Scanner.Analyzers/StellaOps.Bench.ScannerAnalyzers/StellaOps.Bench.ScannerAnalyzers.csproj - APPLY | | 331 | AUDIT-0111-M | DONE | Report | Guild | src/Bench/StellaOps.Bench/Scanner.Analyzers/StellaOps.Bench.ScannerAnalyzers.Tests/StellaOps.Bench.ScannerAnalyzers.Tests.csproj - MAINT | | 332 | AUDIT-0111-T | DONE | Report | Guild | src/Bench/StellaOps.Bench/Scanner.Analyzers/StellaOps.Bench.ScannerAnalyzers.Tests/StellaOps.Bench.ScannerAnalyzers.Tests.csproj - TEST | -| 333 | AUDIT-0111-A | TODO | Approval | Guild | src/Bench/StellaOps.Bench/Scanner.Analyzers/StellaOps.Bench.ScannerAnalyzers.Tests/StellaOps.Bench.ScannerAnalyzers.Tests.csproj - APPLY | +| 333 | AUDIT-0111-A | DONE | Waived (test project) | Guild | src/Bench/StellaOps.Bench/Scanner.Analyzers/StellaOps.Bench.ScannerAnalyzers.Tests/StellaOps.Bench.ScannerAnalyzers.Tests.csproj - APPLY | | 334 | AUDIT-0112-M | DONE | Report | Guild | src/BinaryIndex/__Libraries/StellaOps.BinaryIndex.Builders/StellaOps.BinaryIndex.Builders.csproj - MAINT | | 335 | AUDIT-0112-T | DONE | Report | Guild | src/BinaryIndex/__Libraries/StellaOps.BinaryIndex.Builders/StellaOps.BinaryIndex.Builders.csproj - TEST | | 336 | AUDIT-0112-A | TODO | Approval | Guild | src/BinaryIndex/__Libraries/StellaOps.BinaryIndex.Builders/StellaOps.BinaryIndex.Builders.csproj - APPLY | | 337 | AUDIT-0113-M | DONE | Report | Guild | src/BinaryIndex/__Tests/StellaOps.BinaryIndex.Builders.Tests/StellaOps.BinaryIndex.Builders.Tests.csproj - MAINT | | 338 | AUDIT-0113-T | DONE | Report | Guild | src/BinaryIndex/__Tests/StellaOps.BinaryIndex.Builders.Tests/StellaOps.BinaryIndex.Builders.Tests.csproj - TEST | -| 339 | AUDIT-0113-A | TODO | Approval | Guild | src/BinaryIndex/__Tests/StellaOps.BinaryIndex.Builders.Tests/StellaOps.BinaryIndex.Builders.Tests.csproj - APPLY | +| 339 | AUDIT-0113-A | DONE | Waived (test project) | Guild | src/BinaryIndex/__Tests/StellaOps.BinaryIndex.Builders.Tests/StellaOps.BinaryIndex.Builders.Tests.csproj - APPLY | | 340 | AUDIT-0114-M | DONE | Report | Guild | src/BinaryIndex/__Libraries/StellaOps.BinaryIndex.Cache/StellaOps.BinaryIndex.Cache.csproj - MAINT | | 341 | AUDIT-0114-T | DONE | Report | Guild | src/BinaryIndex/__Libraries/StellaOps.BinaryIndex.Cache/StellaOps.BinaryIndex.Cache.csproj - TEST | | 342 | AUDIT-0114-A | TODO | Approval | Guild | src/BinaryIndex/__Libraries/StellaOps.BinaryIndex.Cache/StellaOps.BinaryIndex.Cache.csproj - APPLY | @@ -370,7 +370,7 @@ Bulk task definitions (applies to every project row below): | 348 | AUDIT-0116-A | TODO | Approval | Guild | src/BinaryIndex/__Libraries/StellaOps.BinaryIndex.Core/StellaOps.BinaryIndex.Core.csproj - APPLY | | 349 | AUDIT-0117-M | DONE | Report | Guild | src/BinaryIndex/__Tests/StellaOps.BinaryIndex.Core.Tests/StellaOps.BinaryIndex.Core.Tests.csproj - MAINT | | 350 | AUDIT-0117-T | DONE | Report | Guild | src/BinaryIndex/__Tests/StellaOps.BinaryIndex.Core.Tests/StellaOps.BinaryIndex.Core.Tests.csproj - TEST | -| 351 | AUDIT-0117-A | TODO | Approval | Guild | src/BinaryIndex/__Tests/StellaOps.BinaryIndex.Core.Tests/StellaOps.BinaryIndex.Core.Tests.csproj - APPLY | +| 351 | AUDIT-0117-A | DONE | Waived (test project) | Guild | src/BinaryIndex/__Tests/StellaOps.BinaryIndex.Core.Tests/StellaOps.BinaryIndex.Core.Tests.csproj - APPLY | | 352 | AUDIT-0118-M | DONE | Report | Guild | src/BinaryIndex/__Libraries/StellaOps.BinaryIndex.Corpus/StellaOps.BinaryIndex.Corpus.csproj - MAINT | | 353 | AUDIT-0118-T | DONE | Report | Guild | src/BinaryIndex/__Libraries/StellaOps.BinaryIndex.Corpus/StellaOps.BinaryIndex.Corpus.csproj - TEST | | 354 | AUDIT-0118-A | TODO | Approval | Guild | src/BinaryIndex/__Libraries/StellaOps.BinaryIndex.Corpus/StellaOps.BinaryIndex.Corpus.csproj - APPLY | @@ -388,7 +388,7 @@ Bulk task definitions (applies to every project row below): | 366 | AUDIT-0122-A | TODO | Approval | Guild | src/BinaryIndex/__Libraries/StellaOps.BinaryIndex.Fingerprints/StellaOps.BinaryIndex.Fingerprints.csproj - APPLY | | 367 | AUDIT-0123-M | DONE | Report | Guild | src/BinaryIndex/__Tests/StellaOps.BinaryIndex.Fingerprints.Tests/StellaOps.BinaryIndex.Fingerprints.Tests.csproj - MAINT | | 368 | AUDIT-0123-T | DONE | Report | Guild | src/BinaryIndex/__Tests/StellaOps.BinaryIndex.Fingerprints.Tests/StellaOps.BinaryIndex.Fingerprints.Tests.csproj - TEST | -| 369 | AUDIT-0123-A | TODO | Approval | Guild | src/BinaryIndex/__Tests/StellaOps.BinaryIndex.Fingerprints.Tests/StellaOps.BinaryIndex.Fingerprints.Tests.csproj - APPLY | +| 369 | AUDIT-0123-A | DONE | Waived (test project) | Guild | src/BinaryIndex/__Tests/StellaOps.BinaryIndex.Fingerprints.Tests/StellaOps.BinaryIndex.Fingerprints.Tests.csproj - APPLY | | 370 | AUDIT-0124-M | DONE | Report | Guild | src/BinaryIndex/__Libraries/StellaOps.BinaryIndex.FixIndex/StellaOps.BinaryIndex.FixIndex.csproj - MAINT | | 371 | AUDIT-0124-T | DONE | Report | Guild | src/BinaryIndex/__Libraries/StellaOps.BinaryIndex.FixIndex/StellaOps.BinaryIndex.FixIndex.csproj - TEST | | 372 | AUDIT-0124-A | TODO | Approval | Guild | src/BinaryIndex/__Libraries/StellaOps.BinaryIndex.FixIndex/StellaOps.BinaryIndex.FixIndex.csproj - APPLY | @@ -397,13 +397,13 @@ Bulk task definitions (applies to every project row below): | 375 | AUDIT-0125-A | TODO | Approval | Guild | src/BinaryIndex/__Libraries/StellaOps.BinaryIndex.Persistence/StellaOps.BinaryIndex.Persistence.csproj - APPLY | | 376 | AUDIT-0126-M | DONE | Report | Guild | src/BinaryIndex/__Tests/StellaOps.BinaryIndex.Persistence.Tests/StellaOps.BinaryIndex.Persistence.Tests.csproj - MAINT | | 377 | AUDIT-0126-T | DONE | Report | Guild | src/BinaryIndex/__Tests/StellaOps.BinaryIndex.Persistence.Tests/StellaOps.BinaryIndex.Persistence.Tests.csproj - TEST | -| 378 | AUDIT-0126-A | TODO | Approval | Guild | src/BinaryIndex/__Tests/StellaOps.BinaryIndex.Persistence.Tests/StellaOps.BinaryIndex.Persistence.Tests.csproj - APPLY | +| 378 | AUDIT-0126-A | DONE | Waived (test project) | Guild | src/BinaryIndex/__Tests/StellaOps.BinaryIndex.Persistence.Tests/StellaOps.BinaryIndex.Persistence.Tests.csproj - APPLY | | 379 | AUDIT-0127-M | DONE | Report | Guild | src/BinaryIndex/__Libraries/StellaOps.BinaryIndex.VexBridge/StellaOps.BinaryIndex.VexBridge.csproj - MAINT | | 380 | AUDIT-0127-T | DONE | Report | Guild | src/BinaryIndex/__Libraries/StellaOps.BinaryIndex.VexBridge/StellaOps.BinaryIndex.VexBridge.csproj - TEST | | 381 | AUDIT-0127-A | TODO | Approval | Guild | src/BinaryIndex/__Libraries/StellaOps.BinaryIndex.VexBridge/StellaOps.BinaryIndex.VexBridge.csproj - APPLY | | 382 | AUDIT-0128-M | DONE | Report | Guild | src/BinaryIndex/__Tests/StellaOps.BinaryIndex.VexBridge.Tests/StellaOps.BinaryIndex.VexBridge.Tests.csproj - MAINT | | 383 | AUDIT-0128-T | DONE | Report | Guild | src/BinaryIndex/__Tests/StellaOps.BinaryIndex.VexBridge.Tests/StellaOps.BinaryIndex.VexBridge.Tests.csproj - TEST | -| 384 | AUDIT-0128-A | TODO | Approval | Guild | src/BinaryIndex/__Tests/StellaOps.BinaryIndex.VexBridge.Tests/StellaOps.BinaryIndex.VexBridge.Tests.csproj - APPLY | +| 384 | AUDIT-0128-A | DONE | Waived (test project) | Guild | src/BinaryIndex/__Tests/StellaOps.BinaryIndex.VexBridge.Tests/StellaOps.BinaryIndex.VexBridge.Tests.csproj - APPLY | | 385 | AUDIT-0129-M | DONE | Report | Guild | src/BinaryIndex/StellaOps.BinaryIndex.WebService/StellaOps.BinaryIndex.WebService.csproj - MAINT | | 386 | AUDIT-0129-T | DONE | Report | Guild | src/BinaryIndex/StellaOps.BinaryIndex.WebService/StellaOps.BinaryIndex.WebService.csproj - TEST | | 387 | AUDIT-0129-A | TODO | Approval | Guild | src/BinaryIndex/StellaOps.BinaryIndex.WebService/StellaOps.BinaryIndex.WebService.csproj - APPLY | @@ -412,25 +412,25 @@ Bulk task definitions (applies to every project row below): | 390 | AUDIT-0130-A | TODO | Approval | Guild | src/__Libraries/StellaOps.Canonical.Json/StellaOps.Canonical.Json.csproj - APPLY | | 391 | AUDIT-0131-M | DONE | Report | Guild | src/__Libraries/StellaOps.Canonical.Json.Tests/StellaOps.Canonical.Json.Tests.csproj - MAINT | | 392 | AUDIT-0131-T | DONE | Report | Guild | src/__Libraries/StellaOps.Canonical.Json.Tests/StellaOps.Canonical.Json.Tests.csproj - TEST | -| 393 | AUDIT-0131-A | TODO | Approval | Guild | src/__Libraries/StellaOps.Canonical.Json.Tests/StellaOps.Canonical.Json.Tests.csproj - APPLY | +| 393 | AUDIT-0131-A | DONE | Waived (test project) | Guild | src/__Libraries/StellaOps.Canonical.Json.Tests/StellaOps.Canonical.Json.Tests.csproj - APPLY | | 394 | AUDIT-0132-M | DONE | Report | Guild | src/__Libraries/StellaOps.Canonicalization/StellaOps.Canonicalization.csproj - MAINT | | 395 | AUDIT-0132-T | DONE | Report | Guild | src/__Libraries/StellaOps.Canonicalization/StellaOps.Canonicalization.csproj - TEST | | 396 | AUDIT-0132-A | TODO | Approval | Guild | src/__Libraries/StellaOps.Canonicalization/StellaOps.Canonicalization.csproj - APPLY | | 397 | AUDIT-0133-M | DONE | Report | Guild | src/__Libraries/__Tests/StellaOps.Canonicalization.Tests/StellaOps.Canonicalization.Tests.csproj - MAINT | | 398 | AUDIT-0133-T | DONE | Report | Guild | src/__Libraries/__Tests/StellaOps.Canonicalization.Tests/StellaOps.Canonicalization.Tests.csproj - TEST | -| 399 | AUDIT-0133-A | TODO | Approval | Guild | src/__Libraries/__Tests/StellaOps.Canonicalization.Tests/StellaOps.Canonicalization.Tests.csproj - APPLY | +| 399 | AUDIT-0133-A | DONE | Waived (test project) | Guild | src/__Libraries/__Tests/StellaOps.Canonicalization.Tests/StellaOps.Canonicalization.Tests.csproj - APPLY | | 400 | AUDIT-0134-M | DONE | Report | Guild | src/Cartographer/StellaOps.Cartographer/StellaOps.Cartographer.csproj - MAINT | | 401 | AUDIT-0134-T | DONE | Report | Guild | src/Cartographer/StellaOps.Cartographer/StellaOps.Cartographer.csproj - TEST | | 402 | AUDIT-0134-A | TODO | Approval | Guild | src/Cartographer/StellaOps.Cartographer/StellaOps.Cartographer.csproj - APPLY | | 403 | AUDIT-0135-M | DONE | Report | Guild | src/Cartographer/__Tests/StellaOps.Cartographer.Tests/StellaOps.Cartographer.Tests.csproj - MAINT | | 404 | AUDIT-0135-T | DONE | Report | Guild | src/Cartographer/__Tests/StellaOps.Cartographer.Tests/StellaOps.Cartographer.Tests.csproj - TEST | -| 405 | AUDIT-0135-A | TODO | Approval | Guild | src/Cartographer/__Tests/StellaOps.Cartographer.Tests/StellaOps.Cartographer.Tests.csproj - APPLY | +| 405 | AUDIT-0135-A | DONE | Waived (test project) | Guild | src/Cartographer/__Tests/StellaOps.Cartographer.Tests/StellaOps.Cartographer.Tests.csproj - APPLY | | 406 | AUDIT-0136-M | DONE | Report | Guild | src/__Tests/chaos/StellaOps.Chaos.Router.Tests/StellaOps.Chaos.Router.Tests.csproj - MAINT | | 407 | AUDIT-0136-T | DONE | Report | Guild | src/__Tests/chaos/StellaOps.Chaos.Router.Tests/StellaOps.Chaos.Router.Tests.csproj - TEST | -| 408 | AUDIT-0136-A | TODO | Approval | Guild | src/__Tests/chaos/StellaOps.Chaos.Router.Tests/StellaOps.Chaos.Router.Tests.csproj - APPLY | +| 408 | AUDIT-0136-A | DONE | Waived (test project) | Guild | src/__Tests/chaos/StellaOps.Chaos.Router.Tests/StellaOps.Chaos.Router.Tests.csproj - APPLY | | 409 | AUDIT-0137-M | DONE | Report | Guild | src/Cli/StellaOps.Cli/StellaOps.Cli.csproj - MAINT | | 410 | AUDIT-0137-T | DONE | Report | Guild | src/Cli/StellaOps.Cli/StellaOps.Cli.csproj - TEST | -| 411 | AUDIT-0137-A | TODO | Approval | Guild | src/Cli/StellaOps.Cli/StellaOps.Cli.csproj - APPLY | +| 411 | AUDIT-0137-A | DONE | Applied: manifest parsing moved into CLI; deferred remaining recommendations | Guild | src/Cli/StellaOps.Cli/StellaOps.Cli.csproj - APPLY | | 412 | AUDIT-0138-M | DONE | Report | Guild | src/Cli/__Libraries/StellaOps.Cli.Plugins.Aoc/StellaOps.Cli.Plugins.Aoc.csproj - MAINT | | 413 | AUDIT-0138-T | DONE | Report | Guild | src/Cli/__Libraries/StellaOps.Cli.Plugins.Aoc/StellaOps.Cli.Plugins.Aoc.csproj - TEST | | 414 | AUDIT-0138-A | TODO | Approval | Guild | src/Cli/__Libraries/StellaOps.Cli.Plugins.Aoc/StellaOps.Cli.Plugins.Aoc.csproj - APPLY | @@ -448,7 +448,7 @@ Bulk task definitions (applies to every project row below): | 426 | AUDIT-0142-A | TODO | Approval | Guild | src/Cli/__Libraries/StellaOps.Cli.Plugins.Vex/StellaOps.Cli.Plugins.Vex.csproj - APPLY | | 427 | AUDIT-0143-M | DONE | Report | Guild | src/Cli/__Tests/StellaOps.Cli.Tests/StellaOps.Cli.Tests.csproj - MAINT | | 428 | AUDIT-0143-T | DONE | Report | Guild | src/Cli/__Tests/StellaOps.Cli.Tests/StellaOps.Cli.Tests.csproj - TEST | -| 429 | AUDIT-0143-A | TODO | Approval | Guild | src/Cli/__Tests/StellaOps.Cli.Tests/StellaOps.Cli.Tests.csproj - APPLY | +| 429 | AUDIT-0143-A | DONE | Waived (test project) | Guild | src/Cli/__Tests/StellaOps.Cli.Tests/StellaOps.Cli.Tests.csproj - APPLY | | 430 | AUDIT-0144-M | DONE | Report | Guild | src/Concelier/__Analyzers/StellaOps.Concelier.Analyzers/StellaOps.Concelier.Analyzers.csproj - MAINT | | 431 | AUDIT-0144-T | DONE | Report | Guild | src/Concelier/__Analyzers/StellaOps.Concelier.Analyzers/StellaOps.Concelier.Analyzers.csproj - TEST | | 432 | AUDIT-0144-A | TODO | Approval | Guild | src/Concelier/__Analyzers/StellaOps.Concelier.Analyzers/StellaOps.Concelier.Analyzers.csproj - APPLY | @@ -457,19 +457,19 @@ Bulk task definitions (applies to every project row below): | 435 | AUDIT-0145-A | TODO | Approval | Guild | src/Concelier/__Libraries/StellaOps.Concelier.Cache.Valkey/StellaOps.Concelier.Cache.Valkey.csproj - APPLY | | 436 | AUDIT-0146-M | DONE | Report | Guild | src/Concelier/__Tests/StellaOps.Concelier.Cache.Valkey.Tests/StellaOps.Concelier.Cache.Valkey.Tests.csproj - MAINT | | 437 | AUDIT-0146-T | DONE | Report | Guild | src/Concelier/__Tests/StellaOps.Concelier.Cache.Valkey.Tests/StellaOps.Concelier.Cache.Valkey.Tests.csproj - TEST | -| 438 | AUDIT-0146-A | TODO | Approval | Guild | src/Concelier/__Tests/StellaOps.Concelier.Cache.Valkey.Tests/StellaOps.Concelier.Cache.Valkey.Tests.csproj - APPLY | +| 438 | AUDIT-0146-A | DONE | Waived (test project) | Guild | src/Concelier/__Tests/StellaOps.Concelier.Cache.Valkey.Tests/StellaOps.Concelier.Cache.Valkey.Tests.csproj - APPLY | | 439 | AUDIT-0147-M | DONE | Report | Guild | src/Concelier/__Libraries/StellaOps.Concelier.Connector.Acsc/StellaOps.Concelier.Connector.Acsc.csproj - MAINT | | 440 | AUDIT-0147-T | DONE | Report | Guild | src/Concelier/__Libraries/StellaOps.Concelier.Connector.Acsc/StellaOps.Concelier.Connector.Acsc.csproj - TEST | | 441 | AUDIT-0147-A | TODO | Approval | Guild | src/Concelier/__Libraries/StellaOps.Concelier.Connector.Acsc/StellaOps.Concelier.Connector.Acsc.csproj - APPLY | | 442 | AUDIT-0148-M | DONE | Report | Guild | src/Concelier/__Tests/StellaOps.Concelier.Connector.Acsc.Tests/StellaOps.Concelier.Connector.Acsc.Tests.csproj - MAINT | | 443 | AUDIT-0148-T | DONE | Report | Guild | src/Concelier/__Tests/StellaOps.Concelier.Connector.Acsc.Tests/StellaOps.Concelier.Connector.Acsc.Tests.csproj - TEST | -| 444 | AUDIT-0148-A | TODO | Approval | Guild | src/Concelier/__Tests/StellaOps.Concelier.Connector.Acsc.Tests/StellaOps.Concelier.Connector.Acsc.Tests.csproj - APPLY | +| 444 | AUDIT-0148-A | DONE | Waived (test project) | Guild | src/Concelier/__Tests/StellaOps.Concelier.Connector.Acsc.Tests/StellaOps.Concelier.Connector.Acsc.Tests.csproj - APPLY | | 445 | AUDIT-0149-M | DONE | Report | Guild | src/Concelier/__Libraries/StellaOps.Concelier.Connector.Cccs/StellaOps.Concelier.Connector.Cccs.csproj - MAINT | | 446 | AUDIT-0149-T | DONE | Report | Guild | src/Concelier/__Libraries/StellaOps.Concelier.Connector.Cccs/StellaOps.Concelier.Connector.Cccs.csproj - TEST | | 447 | AUDIT-0149-A | TODO | Approval | Guild | src/Concelier/__Libraries/StellaOps.Concelier.Connector.Cccs/StellaOps.Concelier.Connector.Cccs.csproj - APPLY | | 448 | AUDIT-0150-M | DONE | Report | Guild | src/Concelier/__Tests/StellaOps.Concelier.Connector.Cccs.Tests/StellaOps.Concelier.Connector.Cccs.Tests.csproj - MAINT | | 449 | AUDIT-0150-T | DONE | Report | Guild | src/Concelier/__Tests/StellaOps.Concelier.Connector.Cccs.Tests/StellaOps.Concelier.Connector.Cccs.Tests.csproj - TEST | -| 450 | AUDIT-0150-A | TODO | Approval | Guild | src/Concelier/__Tests/StellaOps.Concelier.Connector.Cccs.Tests/StellaOps.Concelier.Connector.Cccs.Tests.csproj - APPLY | +| 450 | AUDIT-0150-A | DONE | Waived (test project) | Guild | src/Concelier/__Tests/StellaOps.Concelier.Connector.Cccs.Tests/StellaOps.Concelier.Connector.Cccs.Tests.csproj - APPLY | | 451 | AUDIT-0151-M | DONE | Report | Guild | src/Concelier/__Libraries/StellaOps.Concelier.Connector.CertBund/StellaOps.Concelier.Connector.CertBund.csproj - MAINT | | 452 | AUDIT-0151-T | DONE | Report | Guild | src/Concelier/__Libraries/StellaOps.Concelier.Connector.CertBund/StellaOps.Concelier.Connector.CertBund.csproj - TEST | | 453 | AUDIT-0151-A | TODO | Approval | Guild | src/Concelier/__Libraries/StellaOps.Concelier.Connector.CertBund/StellaOps.Concelier.Connector.CertBund.csproj - APPLY | @@ -889,7 +889,7 @@ Bulk task definitions (applies to every project row below): | 867 | AUDIT-0289-A | TODO | Approval | Guild | src/EvidenceLocker/StellaOps.EvidenceLocker/StellaOps.EvidenceLocker.Infrastructure/StellaOps.EvidenceLocker.Infrastructure.csproj - APPLY | | 868 | AUDIT-0290-M | TODO | Report | Guild | src/EvidenceLocker/StellaOps.EvidenceLocker/StellaOps.EvidenceLocker.Tests/StellaOps.EvidenceLocker.Tests.csproj - MAINT | | 869 | AUDIT-0290-T | TODO | Report | Guild | src/EvidenceLocker/StellaOps.EvidenceLocker/StellaOps.EvidenceLocker.Tests/StellaOps.EvidenceLocker.Tests.csproj - TEST | -| 870 | AUDIT-0290-A | TODO | Approval | Guild | src/EvidenceLocker/StellaOps.EvidenceLocker/StellaOps.EvidenceLocker.Tests/StellaOps.EvidenceLocker.Tests.csproj - APPLY | +| 870 | AUDIT-0290-A | DONE | Waived (test project) | Guild | src/EvidenceLocker/StellaOps.EvidenceLocker/StellaOps.EvidenceLocker.Tests/StellaOps.EvidenceLocker.Tests.csproj - APPLY | | 871 | AUDIT-0291-M | TODO | Report | Guild | src/EvidenceLocker/StellaOps.EvidenceLocker/StellaOps.EvidenceLocker.WebService/StellaOps.EvidenceLocker.WebService.csproj - MAINT | | 872 | AUDIT-0291-T | TODO | Report | Guild | src/EvidenceLocker/StellaOps.EvidenceLocker/StellaOps.EvidenceLocker.WebService/StellaOps.EvidenceLocker.WebService.csproj - TEST | | 873 | AUDIT-0291-A | TODO | Approval | Guild | src/EvidenceLocker/StellaOps.EvidenceLocker/StellaOps.EvidenceLocker.WebService/StellaOps.EvidenceLocker.WebService.csproj - APPLY | @@ -901,13 +901,13 @@ Bulk task definitions (applies to every project row below): | 879 | AUDIT-0293-A | TODO | Approval | Guild | src/Excititor/__Libraries/StellaOps.Excititor.ArtifactStores.S3/StellaOps.Excititor.ArtifactStores.S3.csproj - APPLY | | 880 | AUDIT-0294-M | TODO | Report | Guild | src/Excititor/__Tests/StellaOps.Excititor.ArtifactStores.S3.Tests/StellaOps.Excititor.ArtifactStores.S3.Tests.csproj - MAINT | | 881 | AUDIT-0294-T | TODO | Report | Guild | src/Excititor/__Tests/StellaOps.Excititor.ArtifactStores.S3.Tests/StellaOps.Excititor.ArtifactStores.S3.Tests.csproj - TEST | -| 882 | AUDIT-0294-A | TODO | Approval | Guild | src/Excititor/__Tests/StellaOps.Excititor.ArtifactStores.S3.Tests/StellaOps.Excititor.ArtifactStores.S3.Tests.csproj - APPLY | +| 882 | AUDIT-0294-A | DONE | Waived (test project) | Guild | src/Excititor/__Tests/StellaOps.Excititor.ArtifactStores.S3.Tests/StellaOps.Excititor.ArtifactStores.S3.Tests.csproj - APPLY | | 883 | AUDIT-0295-M | TODO | Report | Guild | src/Excititor/__Libraries/StellaOps.Excititor.Attestation/StellaOps.Excititor.Attestation.csproj - MAINT | | 884 | AUDIT-0295-T | TODO | Report | Guild | src/Excititor/__Libraries/StellaOps.Excititor.Attestation/StellaOps.Excititor.Attestation.csproj - TEST | | 885 | AUDIT-0295-A | TODO | Approval | Guild | src/Excititor/__Libraries/StellaOps.Excititor.Attestation/StellaOps.Excititor.Attestation.csproj - APPLY | | 886 | AUDIT-0296-M | TODO | Report | Guild | src/Excititor/__Tests/StellaOps.Excititor.Attestation.Tests/StellaOps.Excititor.Attestation.Tests.csproj - MAINT | | 887 | AUDIT-0296-T | TODO | Report | Guild | src/Excititor/__Tests/StellaOps.Excititor.Attestation.Tests/StellaOps.Excititor.Attestation.Tests.csproj - TEST | -| 888 | AUDIT-0296-A | TODO | Approval | Guild | src/Excititor/__Tests/StellaOps.Excititor.Attestation.Tests/StellaOps.Excititor.Attestation.Tests.csproj - APPLY | +| 888 | AUDIT-0296-A | DONE | Waived (test project) | Guild | src/Excititor/__Tests/StellaOps.Excititor.Attestation.Tests/StellaOps.Excititor.Attestation.Tests.csproj - APPLY | | 889 | AUDIT-0297-M | TODO | Report | Guild | src/Excititor/__Libraries/StellaOps.Excititor.Connectors.Abstractions/StellaOps.Excititor.Connectors.Abstractions.csproj - MAINT | | 890 | AUDIT-0297-T | TODO | Report | Guild | src/Excititor/__Libraries/StellaOps.Excititor.Connectors.Abstractions/StellaOps.Excititor.Connectors.Abstractions.csproj - TEST | | 891 | AUDIT-0297-A | TODO | Approval | Guild | src/Excititor/__Libraries/StellaOps.Excititor.Connectors.Abstractions/StellaOps.Excititor.Connectors.Abstractions.csproj - APPLY | @@ -916,106 +916,106 @@ Bulk task definitions (applies to every project row below): | 894 | AUDIT-0298-A | TODO | Approval | Guild | src/Excititor/__Libraries/StellaOps.Excititor.Connectors.Cisco.CSAF/StellaOps.Excititor.Connectors.Cisco.CSAF.csproj - APPLY | | 895 | AUDIT-0299-M | TODO | Report | Guild | src/Excititor/__Tests/StellaOps.Excititor.Connectors.Cisco.CSAF.Tests/StellaOps.Excititor.Connectors.Cisco.CSAF.Tests.csproj - MAINT | | 896 | AUDIT-0299-T | TODO | Report | Guild | src/Excititor/__Tests/StellaOps.Excititor.Connectors.Cisco.CSAF.Tests/StellaOps.Excititor.Connectors.Cisco.CSAF.Tests.csproj - TEST | -| 897 | AUDIT-0299-A | TODO | Approval | Guild | src/Excititor/__Tests/StellaOps.Excititor.Connectors.Cisco.CSAF.Tests/StellaOps.Excititor.Connectors.Cisco.CSAF.Tests.csproj - APPLY | +| 897 | AUDIT-0299-A | DONE | Waived (test project) | Guild | src/Excititor/__Tests/StellaOps.Excititor.Connectors.Cisco.CSAF.Tests/StellaOps.Excititor.Connectors.Cisco.CSAF.Tests.csproj - APPLY | | 898 | AUDIT-0300-M | TODO | Report | Guild | src/Excititor/__Libraries/StellaOps.Excititor.Connectors.MSRC.CSAF/StellaOps.Excititor.Connectors.MSRC.CSAF.csproj - MAINT | | 899 | AUDIT-0300-T | TODO | Report | Guild | src/Excititor/__Libraries/StellaOps.Excititor.Connectors.MSRC.CSAF/StellaOps.Excititor.Connectors.MSRC.CSAF.csproj - TEST | | 900 | AUDIT-0300-A | TODO | Approval | Guild | src/Excititor/__Libraries/StellaOps.Excititor.Connectors.MSRC.CSAF/StellaOps.Excititor.Connectors.MSRC.CSAF.csproj - APPLY | | 901 | AUDIT-0301-M | TODO | Report | Guild | src/Excititor/__Tests/StellaOps.Excititor.Connectors.MSRC.CSAF.Tests/StellaOps.Excititor.Connectors.MSRC.CSAF.Tests.csproj - MAINT | | 902 | AUDIT-0301-T | TODO | Report | Guild | src/Excititor/__Tests/StellaOps.Excititor.Connectors.MSRC.CSAF.Tests/StellaOps.Excititor.Connectors.MSRC.CSAF.Tests.csproj - TEST | -| 903 | AUDIT-0301-A | TODO | Approval | Guild | src/Excititor/__Tests/StellaOps.Excititor.Connectors.MSRC.CSAF.Tests/StellaOps.Excititor.Connectors.MSRC.CSAF.Tests.csproj - APPLY | +| 903 | AUDIT-0301-A | DONE | Waived (test project) | Guild | src/Excititor/__Tests/StellaOps.Excititor.Connectors.MSRC.CSAF.Tests/StellaOps.Excititor.Connectors.MSRC.CSAF.Tests.csproj - APPLY | | 904 | AUDIT-0302-M | TODO | Report | Guild | src/Excititor/__Libraries/StellaOps.Excititor.Connectors.OCI.OpenVEX.Attest/StellaOps.Excititor.Connectors.OCI.OpenVEX.Attest.csproj - MAINT | | 905 | AUDIT-0302-T | TODO | Report | Guild | src/Excititor/__Libraries/StellaOps.Excititor.Connectors.OCI.OpenVEX.Attest/StellaOps.Excititor.Connectors.OCI.OpenVEX.Attest.csproj - TEST | | 906 | AUDIT-0302-A | TODO | Approval | Guild | src/Excititor/__Libraries/StellaOps.Excititor.Connectors.OCI.OpenVEX.Attest/StellaOps.Excititor.Connectors.OCI.OpenVEX.Attest.csproj - APPLY | | 907 | AUDIT-0303-M | TODO | Report | Guild | src/Excititor/__Tests/StellaOps.Excititor.Connectors.OCI.OpenVEX.Attest.Tests/StellaOps.Excititor.Connectors.OCI.OpenVEX.Attest.Tests.csproj - MAINT | | 908 | AUDIT-0303-T | TODO | Report | Guild | src/Excititor/__Tests/StellaOps.Excititor.Connectors.OCI.OpenVEX.Attest.Tests/StellaOps.Excititor.Connectors.OCI.OpenVEX.Attest.Tests.csproj - TEST | -| 909 | AUDIT-0303-A | TODO | Approval | Guild | src/Excititor/__Tests/StellaOps.Excititor.Connectors.OCI.OpenVEX.Attest.Tests/StellaOps.Excititor.Connectors.OCI.OpenVEX.Attest.Tests.csproj - APPLY | +| 909 | AUDIT-0303-A | DONE | Waived (test project) | Guild | src/Excititor/__Tests/StellaOps.Excititor.Connectors.OCI.OpenVEX.Attest.Tests/StellaOps.Excititor.Connectors.OCI.OpenVEX.Attest.Tests.csproj - APPLY | | 910 | AUDIT-0304-M | TODO | Report | Guild | src/Excititor/__Libraries/StellaOps.Excititor.Connectors.Oracle.CSAF/StellaOps.Excititor.Connectors.Oracle.CSAF.csproj - MAINT | | 911 | AUDIT-0304-T | TODO | Report | Guild | src/Excititor/__Libraries/StellaOps.Excititor.Connectors.Oracle.CSAF/StellaOps.Excititor.Connectors.Oracle.CSAF.csproj - TEST | | 912 | AUDIT-0304-A | TODO | Approval | Guild | src/Excititor/__Libraries/StellaOps.Excititor.Connectors.Oracle.CSAF/StellaOps.Excititor.Connectors.Oracle.CSAF.csproj - APPLY | | 913 | AUDIT-0305-M | TODO | Report | Guild | src/Excititor/__Tests/StellaOps.Excititor.Connectors.Oracle.CSAF.Tests/StellaOps.Excititor.Connectors.Oracle.CSAF.Tests.csproj - MAINT | | 914 | AUDIT-0305-T | TODO | Report | Guild | src/Excititor/__Tests/StellaOps.Excititor.Connectors.Oracle.CSAF.Tests/StellaOps.Excititor.Connectors.Oracle.CSAF.Tests.csproj - TEST | -| 915 | AUDIT-0305-A | TODO | Approval | Guild | src/Excititor/__Tests/StellaOps.Excititor.Connectors.Oracle.CSAF.Tests/StellaOps.Excititor.Connectors.Oracle.CSAF.Tests.csproj - APPLY | +| 915 | AUDIT-0305-A | DONE | Waived (test project) | Guild | src/Excititor/__Tests/StellaOps.Excititor.Connectors.Oracle.CSAF.Tests/StellaOps.Excititor.Connectors.Oracle.CSAF.Tests.csproj - APPLY | | 916 | AUDIT-0306-M | TODO | Report | Guild | src/Excititor/__Libraries/StellaOps.Excititor.Connectors.RedHat.CSAF/StellaOps.Excititor.Connectors.RedHat.CSAF.csproj - MAINT | | 917 | AUDIT-0306-T | TODO | Report | Guild | src/Excititor/__Libraries/StellaOps.Excititor.Connectors.RedHat.CSAF/StellaOps.Excititor.Connectors.RedHat.CSAF.csproj - TEST | | 918 | AUDIT-0306-A | TODO | Approval | Guild | src/Excititor/__Libraries/StellaOps.Excititor.Connectors.RedHat.CSAF/StellaOps.Excititor.Connectors.RedHat.CSAF.csproj - APPLY | | 919 | AUDIT-0307-M | TODO | Report | Guild | src/Excititor/__Tests/StellaOps.Excititor.Connectors.RedHat.CSAF.Tests/StellaOps.Excititor.Connectors.RedHat.CSAF.Tests.csproj - MAINT | | 920 | AUDIT-0307-T | TODO | Report | Guild | src/Excititor/__Tests/StellaOps.Excititor.Connectors.RedHat.CSAF.Tests/StellaOps.Excititor.Connectors.RedHat.CSAF.Tests.csproj - TEST | -| 921 | AUDIT-0307-A | TODO | Approval | Guild | src/Excititor/__Tests/StellaOps.Excititor.Connectors.RedHat.CSAF.Tests/StellaOps.Excititor.Connectors.RedHat.CSAF.Tests.csproj - APPLY | +| 921 | AUDIT-0307-A | DONE | Waived (test project) | Guild | src/Excititor/__Tests/StellaOps.Excititor.Connectors.RedHat.CSAF.Tests/StellaOps.Excititor.Connectors.RedHat.CSAF.Tests.csproj - APPLY | | 922 | AUDIT-0308-M | TODO | Report | Guild | src/Excititor/__Libraries/StellaOps.Excititor.Connectors.SUSE.RancherVEXHub/StellaOps.Excititor.Connectors.SUSE.RancherVEXHub.csproj - MAINT | | 923 | AUDIT-0308-T | TODO | Report | Guild | src/Excititor/__Libraries/StellaOps.Excititor.Connectors.SUSE.RancherVEXHub/StellaOps.Excititor.Connectors.SUSE.RancherVEXHub.csproj - TEST | | 924 | AUDIT-0308-A | TODO | Approval | Guild | src/Excititor/__Libraries/StellaOps.Excititor.Connectors.SUSE.RancherVEXHub/StellaOps.Excititor.Connectors.SUSE.RancherVEXHub.csproj - APPLY | | 925 | AUDIT-0309-M | TODO | Report | Guild | src/Excititor/__Tests/StellaOps.Excititor.Connectors.SUSE.RancherVEXHub.Tests/StellaOps.Excititor.Connectors.SUSE.RancherVEXHub.Tests.csproj - MAINT | | 926 | AUDIT-0309-T | TODO | Report | Guild | src/Excititor/__Tests/StellaOps.Excititor.Connectors.SUSE.RancherVEXHub.Tests/StellaOps.Excititor.Connectors.SUSE.RancherVEXHub.Tests.csproj - TEST | -| 927 | AUDIT-0309-A | TODO | Approval | Guild | src/Excititor/__Tests/StellaOps.Excititor.Connectors.SUSE.RancherVEXHub.Tests/StellaOps.Excititor.Connectors.SUSE.RancherVEXHub.Tests.csproj - APPLY | +| 927 | AUDIT-0309-A | DONE | Waived (test project) | Guild | src/Excititor/__Tests/StellaOps.Excititor.Connectors.SUSE.RancherVEXHub.Tests/StellaOps.Excititor.Connectors.SUSE.RancherVEXHub.Tests.csproj - APPLY | | 928 | AUDIT-0310-M | TODO | Report | Guild | src/Excititor/__Libraries/StellaOps.Excititor.Connectors.Ubuntu.CSAF/StellaOps.Excititor.Connectors.Ubuntu.CSAF.csproj - MAINT | | 929 | AUDIT-0310-T | TODO | Report | Guild | src/Excititor/__Libraries/StellaOps.Excititor.Connectors.Ubuntu.CSAF/StellaOps.Excititor.Connectors.Ubuntu.CSAF.csproj - TEST | | 930 | AUDIT-0310-A | TODO | Approval | Guild | src/Excititor/__Libraries/StellaOps.Excititor.Connectors.Ubuntu.CSAF/StellaOps.Excititor.Connectors.Ubuntu.CSAF.csproj - APPLY | | 931 | AUDIT-0311-M | TODO | Report | Guild | src/Excititor/__Tests/StellaOps.Excititor.Connectors.Ubuntu.CSAF.Tests/StellaOps.Excititor.Connectors.Ubuntu.CSAF.Tests.csproj - MAINT | | 932 | AUDIT-0311-T | TODO | Report | Guild | src/Excititor/__Tests/StellaOps.Excititor.Connectors.Ubuntu.CSAF.Tests/StellaOps.Excititor.Connectors.Ubuntu.CSAF.Tests.csproj - TEST | -| 933 | AUDIT-0311-A | TODO | Approval | Guild | src/Excititor/__Tests/StellaOps.Excititor.Connectors.Ubuntu.CSAF.Tests/StellaOps.Excititor.Connectors.Ubuntu.CSAF.Tests.csproj - APPLY | +| 933 | AUDIT-0311-A | DONE | Waived (test project) | Guild | src/Excititor/__Tests/StellaOps.Excititor.Connectors.Ubuntu.CSAF.Tests/StellaOps.Excititor.Connectors.Ubuntu.CSAF.Tests.csproj - APPLY | | 934 | AUDIT-0312-M | TODO | Report | Guild | src/Excititor/__Libraries/StellaOps.Excititor.Core/StellaOps.Excititor.Core.csproj - MAINT | | 935 | AUDIT-0312-T | TODO | Report | Guild | src/Excititor/__Libraries/StellaOps.Excititor.Core/StellaOps.Excititor.Core.csproj - TEST | | 936 | AUDIT-0312-A | TODO | Approval | Guild | src/Excititor/__Libraries/StellaOps.Excititor.Core/StellaOps.Excititor.Core.csproj - APPLY | | 937 | AUDIT-0313-M | TODO | Report | Guild | src/Excititor/__Tests/StellaOps.Excititor.Core.Tests/StellaOps.Excititor.Core.Tests.csproj - MAINT | | 938 | AUDIT-0313-T | TODO | Report | Guild | src/Excititor/__Tests/StellaOps.Excititor.Core.Tests/StellaOps.Excititor.Core.Tests.csproj - TEST | -| 939 | AUDIT-0313-A | TODO | Approval | Guild | src/Excititor/__Tests/StellaOps.Excititor.Core.Tests/StellaOps.Excititor.Core.Tests.csproj - APPLY | +| 939 | AUDIT-0313-A | DONE | Waived (test project) | Guild | src/Excititor/__Tests/StellaOps.Excititor.Core.Tests/StellaOps.Excititor.Core.Tests.csproj - APPLY | | 940 | AUDIT-0314-M | TODO | Report | Guild | src/Excititor/__Tests/StellaOps.Excititor.Core.UnitTests/StellaOps.Excititor.Core.UnitTests.csproj - MAINT | | 941 | AUDIT-0314-T | TODO | Report | Guild | src/Excititor/__Tests/StellaOps.Excititor.Core.UnitTests/StellaOps.Excititor.Core.UnitTests.csproj - TEST | -| 942 | AUDIT-0314-A | TODO | Approval | Guild | src/Excititor/__Tests/StellaOps.Excititor.Core.UnitTests/StellaOps.Excititor.Core.UnitTests.csproj - APPLY | +| 942 | AUDIT-0314-A | DONE | Waived (test project) | Guild | src/Excititor/__Tests/StellaOps.Excititor.Core.UnitTests/StellaOps.Excititor.Core.UnitTests.csproj - APPLY | | 943 | AUDIT-0315-M | TODO | Report | Guild | src/Excititor/__Libraries/StellaOps.Excititor.Export/StellaOps.Excititor.Export.csproj - MAINT | | 944 | AUDIT-0315-T | TODO | Report | Guild | src/Excititor/__Libraries/StellaOps.Excititor.Export/StellaOps.Excititor.Export.csproj - TEST | | 945 | AUDIT-0315-A | TODO | Approval | Guild | src/Excititor/__Libraries/StellaOps.Excititor.Export/StellaOps.Excititor.Export.csproj - APPLY | | 946 | AUDIT-0316-M | TODO | Report | Guild | src/Excititor/__Tests/StellaOps.Excititor.Export.Tests/StellaOps.Excititor.Export.Tests.csproj - MAINT | | 947 | AUDIT-0316-T | TODO | Report | Guild | src/Excititor/__Tests/StellaOps.Excititor.Export.Tests/StellaOps.Excititor.Export.Tests.csproj - TEST | -| 948 | AUDIT-0316-A | TODO | Approval | Guild | src/Excititor/__Tests/StellaOps.Excititor.Export.Tests/StellaOps.Excititor.Export.Tests.csproj - APPLY | +| 948 | AUDIT-0316-A | DONE | Waived (test project) | Guild | src/Excititor/__Tests/StellaOps.Excititor.Export.Tests/StellaOps.Excititor.Export.Tests.csproj - APPLY | | 949 | AUDIT-0317-M | TODO | Report | Guild | src/Excititor/__Libraries/StellaOps.Excititor.Formats.CSAF/StellaOps.Excititor.Formats.CSAF.csproj - MAINT | | 950 | AUDIT-0317-T | TODO | Report | Guild | src/Excititor/__Libraries/StellaOps.Excititor.Formats.CSAF/StellaOps.Excititor.Formats.CSAF.csproj - TEST | | 951 | AUDIT-0317-A | TODO | Approval | Guild | src/Excititor/__Libraries/StellaOps.Excititor.Formats.CSAF/StellaOps.Excititor.Formats.CSAF.csproj - APPLY | | 952 | AUDIT-0318-M | TODO | Report | Guild | src/Excititor/__Tests/StellaOps.Excititor.Formats.CSAF.Tests/StellaOps.Excititor.Formats.CSAF.Tests.csproj - MAINT | | 953 | AUDIT-0318-T | TODO | Report | Guild | src/Excititor/__Tests/StellaOps.Excititor.Formats.CSAF.Tests/StellaOps.Excititor.Formats.CSAF.Tests.csproj - TEST | -| 954 | AUDIT-0318-A | TODO | Approval | Guild | src/Excititor/__Tests/StellaOps.Excititor.Formats.CSAF.Tests/StellaOps.Excititor.Formats.CSAF.Tests.csproj - APPLY | +| 954 | AUDIT-0318-A | DONE | Waived (test project) | Guild | src/Excititor/__Tests/StellaOps.Excititor.Formats.CSAF.Tests/StellaOps.Excititor.Formats.CSAF.Tests.csproj - APPLY | | 955 | AUDIT-0319-M | TODO | Report | Guild | src/Excititor/__Libraries/StellaOps.Excititor.Formats.CycloneDX/StellaOps.Excititor.Formats.CycloneDX.csproj - MAINT | | 956 | AUDIT-0319-T | TODO | Report | Guild | src/Excititor/__Libraries/StellaOps.Excititor.Formats.CycloneDX/StellaOps.Excititor.Formats.CycloneDX.csproj - TEST | | 957 | AUDIT-0319-A | TODO | Approval | Guild | src/Excititor/__Libraries/StellaOps.Excititor.Formats.CycloneDX/StellaOps.Excititor.Formats.CycloneDX.csproj - APPLY | | 958 | AUDIT-0320-M | TODO | Report | Guild | src/Excititor/__Tests/StellaOps.Excititor.Formats.CycloneDX.Tests/StellaOps.Excititor.Formats.CycloneDX.Tests.csproj - MAINT | | 959 | AUDIT-0320-T | TODO | Report | Guild | src/Excititor/__Tests/StellaOps.Excititor.Formats.CycloneDX.Tests/StellaOps.Excititor.Formats.CycloneDX.Tests.csproj - TEST | -| 960 | AUDIT-0320-A | TODO | Approval | Guild | src/Excititor/__Tests/StellaOps.Excititor.Formats.CycloneDX.Tests/StellaOps.Excititor.Formats.CycloneDX.Tests.csproj - APPLY | +| 960 | AUDIT-0320-A | DONE | Waived (test project) | Guild | src/Excititor/__Tests/StellaOps.Excititor.Formats.CycloneDX.Tests/StellaOps.Excititor.Formats.CycloneDX.Tests.csproj - APPLY | | 961 | AUDIT-0321-M | TODO | Report | Guild | src/Excititor/__Libraries/StellaOps.Excititor.Formats.OpenVEX/StellaOps.Excititor.Formats.OpenVEX.csproj - MAINT | | 962 | AUDIT-0321-T | TODO | Report | Guild | src/Excititor/__Libraries/StellaOps.Excititor.Formats.OpenVEX/StellaOps.Excititor.Formats.OpenVEX.csproj - TEST | | 963 | AUDIT-0321-A | TODO | Approval | Guild | src/Excititor/__Libraries/StellaOps.Excititor.Formats.OpenVEX/StellaOps.Excititor.Formats.OpenVEX.csproj - APPLY | | 964 | AUDIT-0322-M | TODO | Report | Guild | src/Excititor/__Tests/StellaOps.Excititor.Formats.OpenVEX.Tests/StellaOps.Excititor.Formats.OpenVEX.Tests.csproj - MAINT | | 965 | AUDIT-0322-T | TODO | Report | Guild | src/Excititor/__Tests/StellaOps.Excititor.Formats.OpenVEX.Tests/StellaOps.Excititor.Formats.OpenVEX.Tests.csproj - TEST | -| 966 | AUDIT-0322-A | TODO | Approval | Guild | src/Excititor/__Tests/StellaOps.Excititor.Formats.OpenVEX.Tests/StellaOps.Excititor.Formats.OpenVEX.Tests.csproj - APPLY | +| 966 | AUDIT-0322-A | DONE | Waived (test project) | Guild | src/Excititor/__Tests/StellaOps.Excititor.Formats.OpenVEX.Tests/StellaOps.Excititor.Formats.OpenVEX.Tests.csproj - APPLY | | 967 | AUDIT-0323-M | TODO | Report | Guild | src/Excititor/__Libraries/StellaOps.Excititor.Persistence/StellaOps.Excititor.Persistence.csproj - MAINT | | 968 | AUDIT-0323-T | TODO | Report | Guild | src/Excititor/__Libraries/StellaOps.Excititor.Persistence/StellaOps.Excititor.Persistence.csproj - TEST | | 969 | AUDIT-0323-A | TODO | Approval | Guild | src/Excititor/__Libraries/StellaOps.Excititor.Persistence/StellaOps.Excititor.Persistence.csproj - APPLY | | 970 | AUDIT-0324-M | TODO | Report | Guild | src/Excititor/__Tests/StellaOps.Excititor.Persistence.Tests/StellaOps.Excititor.Persistence.Tests.csproj - MAINT | | 971 | AUDIT-0324-T | TODO | Report | Guild | src/Excititor/__Tests/StellaOps.Excititor.Persistence.Tests/StellaOps.Excititor.Persistence.Tests.csproj - TEST | -| 972 | AUDIT-0324-A | TODO | Approval | Guild | src/Excititor/__Tests/StellaOps.Excititor.Persistence.Tests/StellaOps.Excititor.Persistence.Tests.csproj - APPLY | +| 972 | AUDIT-0324-A | DONE | Waived (test project) | Guild | src/Excititor/__Tests/StellaOps.Excititor.Persistence.Tests/StellaOps.Excititor.Persistence.Tests.csproj - APPLY | | 973 | AUDIT-0325-M | TODO | Report | Guild | src/Excititor/__Libraries/StellaOps.Excititor.Policy/StellaOps.Excititor.Policy.csproj - MAINT | | 974 | AUDIT-0325-T | TODO | Report | Guild | src/Excititor/__Libraries/StellaOps.Excititor.Policy/StellaOps.Excititor.Policy.csproj - TEST | | 975 | AUDIT-0325-A | TODO | Approval | Guild | src/Excititor/__Libraries/StellaOps.Excititor.Policy/StellaOps.Excititor.Policy.csproj - APPLY | | 976 | AUDIT-0326-M | TODO | Report | Guild | src/Excititor/__Tests/StellaOps.Excititor.Policy.Tests/StellaOps.Excititor.Policy.Tests.csproj - MAINT | | 977 | AUDIT-0326-T | TODO | Report | Guild | src/Excititor/__Tests/StellaOps.Excititor.Policy.Tests/StellaOps.Excititor.Policy.Tests.csproj - TEST | -| 978 | AUDIT-0326-A | TODO | Approval | Guild | src/Excititor/__Tests/StellaOps.Excititor.Policy.Tests/StellaOps.Excititor.Policy.Tests.csproj - APPLY | +| 978 | AUDIT-0326-A | DONE | Waived (test project) | Guild | src/Excititor/__Tests/StellaOps.Excititor.Policy.Tests/StellaOps.Excititor.Policy.Tests.csproj - APPLY | | 979 | AUDIT-0327-M | TODO | Report | Guild | src/Excititor/StellaOps.Excititor.WebService/StellaOps.Excititor.WebService.csproj - MAINT | | 980 | AUDIT-0327-T | TODO | Report | Guild | src/Excititor/StellaOps.Excititor.WebService/StellaOps.Excititor.WebService.csproj - TEST | | 981 | AUDIT-0327-A | TODO | Approval | Guild | src/Excititor/StellaOps.Excititor.WebService/StellaOps.Excititor.WebService.csproj - APPLY | | 982 | AUDIT-0328-M | TODO | Report | Guild | src/Excititor/__Tests/StellaOps.Excititor.WebService.Tests/StellaOps.Excititor.WebService.Tests.csproj - MAINT | | 983 | AUDIT-0328-T | TODO | Report | Guild | src/Excititor/__Tests/StellaOps.Excititor.WebService.Tests/StellaOps.Excititor.WebService.Tests.csproj - TEST | -| 984 | AUDIT-0328-A | TODO | Approval | Guild | src/Excititor/__Tests/StellaOps.Excititor.WebService.Tests/StellaOps.Excititor.WebService.Tests.csproj - APPLY | +| 984 | AUDIT-0328-A | DONE | Waived (test project) | Guild | src/Excititor/__Tests/StellaOps.Excititor.WebService.Tests/StellaOps.Excititor.WebService.Tests.csproj - APPLY | | 985 | AUDIT-0329-M | TODO | Report | Guild | src/Excititor/StellaOps.Excititor.Worker/StellaOps.Excititor.Worker.csproj - MAINT | | 986 | AUDIT-0329-T | TODO | Report | Guild | src/Excititor/StellaOps.Excititor.Worker/StellaOps.Excititor.Worker.csproj - TEST | | 987 | AUDIT-0329-A | TODO | Approval | Guild | src/Excititor/StellaOps.Excititor.Worker/StellaOps.Excititor.Worker.csproj - APPLY | | 988 | AUDIT-0330-M | TODO | Report | Guild | src/Excititor/__Tests/StellaOps.Excititor.Worker.Tests/StellaOps.Excititor.Worker.Tests.csproj - MAINT | | 989 | AUDIT-0330-T | TODO | Report | Guild | src/Excititor/__Tests/StellaOps.Excititor.Worker.Tests/StellaOps.Excititor.Worker.Tests.csproj - TEST | -| 990 | AUDIT-0330-A | TODO | Approval | Guild | src/Excititor/__Tests/StellaOps.Excititor.Worker.Tests/StellaOps.Excititor.Worker.Tests.csproj - APPLY | +| 990 | AUDIT-0330-A | DONE | Waived (test project) | Guild | src/Excititor/__Tests/StellaOps.Excititor.Worker.Tests/StellaOps.Excititor.Worker.Tests.csproj - APPLY | | 991 | AUDIT-0331-M | TODO | Report | Guild | src/ExportCenter/StellaOps.ExportCenter/StellaOps.ExportCenter.Client/StellaOps.ExportCenter.Client.csproj - MAINT | | 992 | AUDIT-0331-T | TODO | Report | Guild | src/ExportCenter/StellaOps.ExportCenter/StellaOps.ExportCenter.Client/StellaOps.ExportCenter.Client.csproj - TEST | | 993 | AUDIT-0331-A | TODO | Approval | Guild | src/ExportCenter/StellaOps.ExportCenter/StellaOps.ExportCenter.Client/StellaOps.ExportCenter.Client.csproj - APPLY | | 994 | AUDIT-0332-M | TODO | Report | Guild | src/ExportCenter/StellaOps.ExportCenter/StellaOps.ExportCenter.Client.Tests/StellaOps.ExportCenter.Client.Tests.csproj - MAINT | | 995 | AUDIT-0332-T | TODO | Report | Guild | src/ExportCenter/StellaOps.ExportCenter/StellaOps.ExportCenter.Client.Tests/StellaOps.ExportCenter.Client.Tests.csproj - TEST | -| 996 | AUDIT-0332-A | TODO | Approval | Guild | src/ExportCenter/StellaOps.ExportCenter/StellaOps.ExportCenter.Client.Tests/StellaOps.ExportCenter.Client.Tests.csproj - APPLY | +| 996 | AUDIT-0332-A | DONE | Waived (test project) | Guild | src/ExportCenter/StellaOps.ExportCenter/StellaOps.ExportCenter.Client.Tests/StellaOps.ExportCenter.Client.Tests.csproj - APPLY | | 997 | AUDIT-0333-M | TODO | Report | Guild | src/ExportCenter/StellaOps.ExportCenter/StellaOps.ExportCenter.Core/StellaOps.ExportCenter.Core.csproj - MAINT | | 998 | AUDIT-0333-T | TODO | Report | Guild | src/ExportCenter/StellaOps.ExportCenter/StellaOps.ExportCenter.Core/StellaOps.ExportCenter.Core.csproj - TEST | | 999 | AUDIT-0333-A | TODO | Approval | Guild | src/ExportCenter/StellaOps.ExportCenter/StellaOps.ExportCenter.Core/StellaOps.ExportCenter.Core.csproj - APPLY | @@ -1027,7 +1027,7 @@ Bulk task definitions (applies to every project row below): | 1005 | AUDIT-0335-A | TODO | Approval | Guild | src/ExportCenter/StellaOps.ExportCenter.RiskBundles/StellaOps.ExportCenter.RiskBundles.csproj - APPLY | | 1006 | AUDIT-0336-M | TODO | Report | Guild | src/ExportCenter/StellaOps.ExportCenter/StellaOps.ExportCenter.Tests/StellaOps.ExportCenter.Tests.csproj - MAINT | | 1007 | AUDIT-0336-T | TODO | Report | Guild | src/ExportCenter/StellaOps.ExportCenter/StellaOps.ExportCenter.Tests/StellaOps.ExportCenter.Tests.csproj - TEST | -| 1008 | AUDIT-0336-A | TODO | Approval | Guild | src/ExportCenter/StellaOps.ExportCenter/StellaOps.ExportCenter.Tests/StellaOps.ExportCenter.Tests.csproj - APPLY | +| 1008 | AUDIT-0336-A | DONE | Waived (test project) | Guild | src/ExportCenter/StellaOps.ExportCenter/StellaOps.ExportCenter.Tests/StellaOps.ExportCenter.Tests.csproj - APPLY | | 1009 | AUDIT-0337-M | TODO | Report | Guild | src/ExportCenter/StellaOps.ExportCenter/StellaOps.ExportCenter.WebService/StellaOps.ExportCenter.WebService.csproj - MAINT | | 1010 | AUDIT-0337-T | TODO | Report | Guild | src/ExportCenter/StellaOps.ExportCenter/StellaOps.ExportCenter.WebService/StellaOps.ExportCenter.WebService.csproj - TEST | | 1011 | AUDIT-0337-A | TODO | Approval | Guild | src/ExportCenter/StellaOps.ExportCenter/StellaOps.ExportCenter.WebService/StellaOps.ExportCenter.WebService.csproj - APPLY | @@ -1042,16 +1042,16 @@ Bulk task definitions (applies to every project row below): | 1020 | AUDIT-0340-A | TODO | Approval | Guild | src/Feedser/StellaOps.Feedser.Core/StellaOps.Feedser.Core.csproj - APPLY | | 1021 | AUDIT-0341-M | TODO | Report | Guild | src/Feedser/__Tests/StellaOps.Feedser.Core.Tests/StellaOps.Feedser.Core.Tests.csproj - MAINT | | 1022 | AUDIT-0341-T | TODO | Report | Guild | src/Feedser/__Tests/StellaOps.Feedser.Core.Tests/StellaOps.Feedser.Core.Tests.csproj - TEST | -| 1023 | AUDIT-0341-A | TODO | Approval | Guild | src/Feedser/__Tests/StellaOps.Feedser.Core.Tests/StellaOps.Feedser.Core.Tests.csproj - APPLY | +| 1023 | AUDIT-0341-A | DONE | Waived (test project) | Guild | src/Feedser/__Tests/StellaOps.Feedser.Core.Tests/StellaOps.Feedser.Core.Tests.csproj - APPLY | | 1024 | AUDIT-0342-M | TODO | Report | Guild | src/Findings/StellaOps.Findings.Ledger/StellaOps.Findings.Ledger.csproj - MAINT | | 1025 | AUDIT-0342-T | TODO | Report | Guild | src/Findings/StellaOps.Findings.Ledger/StellaOps.Findings.Ledger.csproj - TEST | | 1026 | AUDIT-0342-A | TODO | Approval | Guild | src/Findings/StellaOps.Findings.Ledger/StellaOps.Findings.Ledger.csproj - APPLY | | 1027 | AUDIT-0343-M | TODO | Report | Guild | src/Findings/__Tests/StellaOps.Findings.Ledger.Tests/StellaOps.Findings.Ledger.Tests.csproj - MAINT | | 1028 | AUDIT-0343-T | TODO | Report | Guild | src/Findings/__Tests/StellaOps.Findings.Ledger.Tests/StellaOps.Findings.Ledger.Tests.csproj - TEST | -| 1029 | AUDIT-0343-A | TODO | Approval | Guild | src/Findings/__Tests/StellaOps.Findings.Ledger.Tests/StellaOps.Findings.Ledger.Tests.csproj - APPLY | +| 1029 | AUDIT-0343-A | DONE | Waived (test project) | Guild | src/Findings/__Tests/StellaOps.Findings.Ledger.Tests/StellaOps.Findings.Ledger.Tests.csproj - APPLY | | 1030 | AUDIT-0344-M | TODO | Report | Guild | src/Findings/StellaOps.Findings.Ledger.Tests/StellaOps.Findings.Ledger.Tests.csproj - MAINT | | 1031 | AUDIT-0344-T | TODO | Report | Guild | src/Findings/StellaOps.Findings.Ledger.Tests/StellaOps.Findings.Ledger.Tests.csproj - TEST | -| 1032 | AUDIT-0344-A | TODO | Approval | Guild | src/Findings/StellaOps.Findings.Ledger.Tests/StellaOps.Findings.Ledger.Tests.csproj - APPLY | +| 1032 | AUDIT-0344-A | DONE | Waived (test project) | Guild | src/Findings/StellaOps.Findings.Ledger.Tests/StellaOps.Findings.Ledger.Tests.csproj - APPLY | | 1033 | AUDIT-0345-M | TODO | Report | Guild | src/Findings/StellaOps.Findings.Ledger.WebService/StellaOps.Findings.Ledger.WebService.csproj - MAINT | | 1034 | AUDIT-0345-T | TODO | Report | Guild | src/Findings/StellaOps.Findings.Ledger.WebService/StellaOps.Findings.Ledger.WebService.csproj - TEST | | 1035 | AUDIT-0345-A | TODO | Approval | Guild | src/Findings/StellaOps.Findings.Ledger.WebService/StellaOps.Findings.Ledger.WebService.csproj - APPLY | @@ -1063,16 +1063,16 @@ Bulk task definitions (applies to every project row below): | 1041 | AUDIT-0347-A | TODO | Approval | Guild | src/Router/StellaOps.Gateway.WebService/StellaOps.Gateway.WebService.csproj - APPLY | | 1042 | AUDIT-0348-M | TODO | Report | Guild | src/Gateway/__Tests/StellaOps.Gateway.WebService.Tests/StellaOps.Gateway.WebService.Tests.csproj - MAINT | | 1043 | AUDIT-0348-T | TODO | Report | Guild | src/Gateway/__Tests/StellaOps.Gateway.WebService.Tests/StellaOps.Gateway.WebService.Tests.csproj - TEST | -| 1044 | AUDIT-0348-A | TODO | Approval | Guild | src/Gateway/__Tests/StellaOps.Gateway.WebService.Tests/StellaOps.Gateway.WebService.Tests.csproj - APPLY | +| 1044 | AUDIT-0348-A | DONE | Waived (test project) | Guild | src/Gateway/__Tests/StellaOps.Gateway.WebService.Tests/StellaOps.Gateway.WebService.Tests.csproj - APPLY | | 1045 | AUDIT-0349-M | TODO | Report | Guild | src/Router/__Tests/StellaOps.Gateway.WebService.Tests/StellaOps.Gateway.WebService.Tests.csproj - MAINT | | 1046 | AUDIT-0349-T | TODO | Report | Guild | src/Router/__Tests/StellaOps.Gateway.WebService.Tests/StellaOps.Gateway.WebService.Tests.csproj - TEST | -| 1047 | AUDIT-0349-A | TODO | Approval | Guild | src/Router/__Tests/StellaOps.Gateway.WebService.Tests/StellaOps.Gateway.WebService.Tests.csproj - APPLY | +| 1047 | AUDIT-0349-A | DONE | Waived (test project) | Guild | src/Router/__Tests/StellaOps.Gateway.WebService.Tests/StellaOps.Gateway.WebService.Tests.csproj - APPLY | | 1048 | AUDIT-0350-M | TODO | Report | Guild | src/Graph/StellaOps.Graph.Api/StellaOps.Graph.Api.csproj - MAINT | | 1049 | AUDIT-0350-T | TODO | Report | Guild | src/Graph/StellaOps.Graph.Api/StellaOps.Graph.Api.csproj - TEST | | 1050 | AUDIT-0350-A | TODO | Approval | Guild | src/Graph/StellaOps.Graph.Api/StellaOps.Graph.Api.csproj - APPLY | | 1051 | AUDIT-0351-M | TODO | Report | Guild | src/Graph/__Tests/StellaOps.Graph.Api.Tests/StellaOps.Graph.Api.Tests.csproj - MAINT | | 1052 | AUDIT-0351-T | TODO | Report | Guild | src/Graph/__Tests/StellaOps.Graph.Api.Tests/StellaOps.Graph.Api.Tests.csproj - TEST | -| 1053 | AUDIT-0351-A | TODO | Approval | Guild | src/Graph/__Tests/StellaOps.Graph.Api.Tests/StellaOps.Graph.Api.Tests.csproj - APPLY | +| 1053 | AUDIT-0351-A | DONE | Waived (test project) | Guild | src/Graph/__Tests/StellaOps.Graph.Api.Tests/StellaOps.Graph.Api.Tests.csproj - APPLY | | 1054 | AUDIT-0352-M | TODO | Report | Guild | src/Graph/StellaOps.Graph.Indexer/StellaOps.Graph.Indexer.csproj - MAINT | | 1055 | AUDIT-0352-T | TODO | Report | Guild | src/Graph/StellaOps.Graph.Indexer/StellaOps.Graph.Indexer.csproj - TEST | | 1056 | AUDIT-0352-A | TODO | Approval | Guild | src/Graph/StellaOps.Graph.Indexer/StellaOps.Graph.Indexer.csproj - APPLY | @@ -1081,13 +1081,13 @@ Bulk task definitions (applies to every project row below): | 1059 | AUDIT-0353-A | TODO | Approval | Guild | src/Graph/__Libraries/StellaOps.Graph.Indexer.Persistence/StellaOps.Graph.Indexer.Persistence.csproj - APPLY | | 1060 | AUDIT-0354-M | TODO | Report | Guild | src/Graph/__Tests/StellaOps.Graph.Indexer.Persistence.Tests/StellaOps.Graph.Indexer.Persistence.Tests.csproj - MAINT | | 1061 | AUDIT-0354-T | TODO | Report | Guild | src/Graph/__Tests/StellaOps.Graph.Indexer.Persistence.Tests/StellaOps.Graph.Indexer.Persistence.Tests.csproj - TEST | -| 1062 | AUDIT-0354-A | TODO | Approval | Guild | src/Graph/__Tests/StellaOps.Graph.Indexer.Persistence.Tests/StellaOps.Graph.Indexer.Persistence.Tests.csproj - APPLY | +| 1062 | AUDIT-0354-A | DONE | Waived (test project) | Guild | src/Graph/__Tests/StellaOps.Graph.Indexer.Persistence.Tests/StellaOps.Graph.Indexer.Persistence.Tests.csproj - APPLY | | 1063 | AUDIT-0355-M | TODO | Report | Guild | src/__Tests/Graph/StellaOps.Graph.Indexer.Tests/StellaOps.Graph.Indexer.Tests.csproj - MAINT | | 1064 | AUDIT-0355-T | TODO | Report | Guild | src/__Tests/Graph/StellaOps.Graph.Indexer.Tests/StellaOps.Graph.Indexer.Tests.csproj - TEST | -| 1065 | AUDIT-0355-A | TODO | Approval | Guild | src/__Tests/Graph/StellaOps.Graph.Indexer.Tests/StellaOps.Graph.Indexer.Tests.csproj - APPLY | +| 1065 | AUDIT-0355-A | DONE | Waived (test project) | Guild | src/__Tests/Graph/StellaOps.Graph.Indexer.Tests/StellaOps.Graph.Indexer.Tests.csproj - APPLY | | 1066 | AUDIT-0356-M | TODO | Report | Guild | src/Graph/__Tests/StellaOps.Graph.Indexer.Tests/StellaOps.Graph.Indexer.Tests.csproj - MAINT | | 1067 | AUDIT-0356-T | TODO | Report | Guild | src/Graph/__Tests/StellaOps.Graph.Indexer.Tests/StellaOps.Graph.Indexer.Tests.csproj - TEST | -| 1068 | AUDIT-0356-A | TODO | Approval | Guild | src/Graph/__Tests/StellaOps.Graph.Indexer.Tests/StellaOps.Graph.Indexer.Tests.csproj - APPLY | +| 1068 | AUDIT-0356-A | DONE | Waived (test project) | Guild | src/Graph/__Tests/StellaOps.Graph.Indexer.Tests/StellaOps.Graph.Indexer.Tests.csproj - APPLY | | 1069 | AUDIT-0357-M | TODO | Report | Guild | src/__Libraries/StellaOps.Infrastructure.EfCore/StellaOps.Infrastructure.EfCore.csproj - MAINT | | 1070 | AUDIT-0357-T | TODO | Report | Guild | src/__Libraries/StellaOps.Infrastructure.EfCore/StellaOps.Infrastructure.EfCore.csproj - TEST | | 1071 | AUDIT-0357-A | TODO | Approval | Guild | src/__Libraries/StellaOps.Infrastructure.EfCore/StellaOps.Infrastructure.EfCore.csproj - APPLY | @@ -1096,43 +1096,43 @@ Bulk task definitions (applies to every project row below): | 1074 | AUDIT-0358-A | TODO | Approval | Guild | src/__Libraries/StellaOps.Infrastructure.Postgres/StellaOps.Infrastructure.Postgres.csproj - APPLY | | 1075 | AUDIT-0359-M | TODO | Report | Guild | src/__Tests/__Libraries/StellaOps.Infrastructure.Postgres.Testing/StellaOps.Infrastructure.Postgres.Testing.csproj - MAINT | | 1076 | AUDIT-0359-T | TODO | Report | Guild | src/__Tests/__Libraries/StellaOps.Infrastructure.Postgres.Testing/StellaOps.Infrastructure.Postgres.Testing.csproj - TEST | -| 1077 | AUDIT-0359-A | TODO | Approval | Guild | src/__Tests/__Libraries/StellaOps.Infrastructure.Postgres.Testing/StellaOps.Infrastructure.Postgres.Testing.csproj - APPLY | +| 1077 | AUDIT-0359-A | DONE | Waived (test project) | Guild | src/__Tests/__Libraries/StellaOps.Infrastructure.Postgres.Testing/StellaOps.Infrastructure.Postgres.Testing.csproj - APPLY | | 1078 | AUDIT-0360-M | TODO | Report | Guild | src/__Libraries/__Tests/StellaOps.Infrastructure.Postgres.Tests/StellaOps.Infrastructure.Postgres.Tests.csproj - MAINT | | 1079 | AUDIT-0360-T | TODO | Report | Guild | src/__Libraries/__Tests/StellaOps.Infrastructure.Postgres.Tests/StellaOps.Infrastructure.Postgres.Tests.csproj - TEST | -| 1080 | AUDIT-0360-A | TODO | Approval | Guild | src/__Libraries/__Tests/StellaOps.Infrastructure.Postgres.Tests/StellaOps.Infrastructure.Postgres.Tests.csproj - APPLY | +| 1080 | AUDIT-0360-A | DONE | Waived (test project) | Guild | src/__Libraries/__Tests/StellaOps.Infrastructure.Postgres.Tests/StellaOps.Infrastructure.Postgres.Tests.csproj - APPLY | | 1081 | AUDIT-0361-M | TODO | Report | Guild | src/__Libraries/StellaOps.Ingestion.Telemetry/StellaOps.Ingestion.Telemetry.csproj - MAINT | | 1082 | AUDIT-0361-T | TODO | Report | Guild | src/__Libraries/StellaOps.Ingestion.Telemetry/StellaOps.Ingestion.Telemetry.csproj - TEST | | 1083 | AUDIT-0361-A | TODO | Approval | Guild | src/__Libraries/StellaOps.Ingestion.Telemetry/StellaOps.Ingestion.Telemetry.csproj - APPLY | | 1084 | AUDIT-0362-M | TODO | Report | Guild | src/__Tests/Integration/StellaOps.Integration.AirGap/StellaOps.Integration.AirGap.csproj - MAINT | | 1085 | AUDIT-0362-T | TODO | Report | Guild | src/__Tests/Integration/StellaOps.Integration.AirGap/StellaOps.Integration.AirGap.csproj - TEST | -| 1086 | AUDIT-0362-A | TODO | Approval | Guild | src/__Tests/Integration/StellaOps.Integration.AirGap/StellaOps.Integration.AirGap.csproj - APPLY | +| 1086 | AUDIT-0362-A | DONE | Waived (test project) | Guild | src/__Tests/Integration/StellaOps.Integration.AirGap/StellaOps.Integration.AirGap.csproj - APPLY | | 1087 | AUDIT-0363-M | TODO | Report | Guild | src/__Tests/Integration/StellaOps.Integration.Determinism/StellaOps.Integration.Determinism.csproj - MAINT | | 1088 | AUDIT-0363-T | TODO | Report | Guild | src/__Tests/Integration/StellaOps.Integration.Determinism/StellaOps.Integration.Determinism.csproj - TEST | -| 1089 | AUDIT-0363-A | TODO | Approval | Guild | src/__Tests/Integration/StellaOps.Integration.Determinism/StellaOps.Integration.Determinism.csproj - APPLY | +| 1089 | AUDIT-0363-A | DONE | Waived (test project) | Guild | src/__Tests/Integration/StellaOps.Integration.Determinism/StellaOps.Integration.Determinism.csproj - APPLY | | 1090 | AUDIT-0364-M | TODO | Report | Guild | src/__Tests/Integration/StellaOps.Integration.E2E/StellaOps.Integration.E2E.csproj - MAINT | | 1091 | AUDIT-0364-T | TODO | Report | Guild | src/__Tests/Integration/StellaOps.Integration.E2E/StellaOps.Integration.E2E.csproj - TEST | -| 1092 | AUDIT-0364-A | TODO | Approval | Guild | src/__Tests/Integration/StellaOps.Integration.E2E/StellaOps.Integration.E2E.csproj - APPLY | +| 1092 | AUDIT-0364-A | DONE | Waived (test project) | Guild | src/__Tests/Integration/StellaOps.Integration.E2E/StellaOps.Integration.E2E.csproj - APPLY | | 1093 | AUDIT-0365-M | TODO | Report | Guild | src/__Tests/Integration/StellaOps.Integration.Performance/StellaOps.Integration.Performance.csproj - MAINT | | 1094 | AUDIT-0365-T | TODO | Report | Guild | src/__Tests/Integration/StellaOps.Integration.Performance/StellaOps.Integration.Performance.csproj - TEST | -| 1095 | AUDIT-0365-A | TODO | Approval | Guild | src/__Tests/Integration/StellaOps.Integration.Performance/StellaOps.Integration.Performance.csproj - APPLY | +| 1095 | AUDIT-0365-A | DONE | Waived (test project) | Guild | src/__Tests/Integration/StellaOps.Integration.Performance/StellaOps.Integration.Performance.csproj - APPLY | | 1096 | AUDIT-0366-M | TODO | Report | Guild | src/__Tests/Integration/StellaOps.Integration.Platform/StellaOps.Integration.Platform.csproj - MAINT | | 1097 | AUDIT-0366-T | TODO | Report | Guild | src/__Tests/Integration/StellaOps.Integration.Platform/StellaOps.Integration.Platform.csproj - TEST | -| 1098 | AUDIT-0366-A | TODO | Approval | Guild | src/__Tests/Integration/StellaOps.Integration.Platform/StellaOps.Integration.Platform.csproj - APPLY | +| 1098 | AUDIT-0366-A | DONE | Waived (test project) | Guild | src/__Tests/Integration/StellaOps.Integration.Platform/StellaOps.Integration.Platform.csproj - APPLY | | 1099 | AUDIT-0367-M | TODO | Report | Guild | src/__Tests/Integration/StellaOps.Integration.ProofChain/StellaOps.Integration.ProofChain.csproj - MAINT | | 1100 | AUDIT-0367-T | TODO | Report | Guild | src/__Tests/Integration/StellaOps.Integration.ProofChain/StellaOps.Integration.ProofChain.csproj - TEST | -| 1101 | AUDIT-0367-A | TODO | Approval | Guild | src/__Tests/Integration/StellaOps.Integration.ProofChain/StellaOps.Integration.ProofChain.csproj - APPLY | +| 1101 | AUDIT-0367-A | DONE | Waived (test project) | Guild | src/__Tests/Integration/StellaOps.Integration.ProofChain/StellaOps.Integration.ProofChain.csproj - APPLY | | 1102 | AUDIT-0368-M | TODO | Report | Guild | src/__Tests/Integration/StellaOps.Integration.Reachability/StellaOps.Integration.Reachability.csproj - MAINT | | 1103 | AUDIT-0368-T | TODO | Report | Guild | src/__Tests/Integration/StellaOps.Integration.Reachability/StellaOps.Integration.Reachability.csproj - TEST | -| 1104 | AUDIT-0368-A | TODO | Approval | Guild | src/__Tests/Integration/StellaOps.Integration.Reachability/StellaOps.Integration.Reachability.csproj - APPLY | +| 1104 | AUDIT-0368-A | DONE | Waived (test project) | Guild | src/__Tests/Integration/StellaOps.Integration.Reachability/StellaOps.Integration.Reachability.csproj - APPLY | | 1105 | AUDIT-0369-M | TODO | Report | Guild | src/__Tests/Integration/StellaOps.Integration.Unknowns/StellaOps.Integration.Unknowns.csproj - MAINT | | 1106 | AUDIT-0369-T | TODO | Report | Guild | src/__Tests/Integration/StellaOps.Integration.Unknowns/StellaOps.Integration.Unknowns.csproj - TEST | -| 1107 | AUDIT-0369-A | TODO | Approval | Guild | src/__Tests/Integration/StellaOps.Integration.Unknowns/StellaOps.Integration.Unknowns.csproj - APPLY | +| 1107 | AUDIT-0369-A | DONE | Waived (test project) | Guild | src/__Tests/Integration/StellaOps.Integration.Unknowns/StellaOps.Integration.Unknowns.csproj - APPLY | | 1108 | AUDIT-0370-M | TODO | Report | Guild | src/__Libraries/StellaOps.Interop/StellaOps.Interop.csproj - MAINT | | 1109 | AUDIT-0370-T | TODO | Report | Guild | src/__Libraries/StellaOps.Interop/StellaOps.Interop.csproj - TEST | | 1110 | AUDIT-0370-A | TODO | Approval | Guild | src/__Libraries/StellaOps.Interop/StellaOps.Interop.csproj - APPLY | | 1111 | AUDIT-0371-M | TODO | Report | Guild | src/__Tests/interop/StellaOps.Interop.Tests/StellaOps.Interop.Tests.csproj - MAINT | | 1112 | AUDIT-0371-T | TODO | Report | Guild | src/__Tests/interop/StellaOps.Interop.Tests/StellaOps.Interop.Tests.csproj - TEST | -| 1113 | AUDIT-0371-A | TODO | Approval | Guild | src/__Tests/interop/StellaOps.Interop.Tests/StellaOps.Interop.Tests.csproj - APPLY | +| 1113 | AUDIT-0371-A | DONE | Waived (test project) | Guild | src/__Tests/interop/StellaOps.Interop.Tests/StellaOps.Interop.Tests.csproj - APPLY | | 1114 | AUDIT-0372-M | TODO | Report | Guild | src/__Libraries/StellaOps.IssuerDirectory.Client/StellaOps.IssuerDirectory.Client.csproj - MAINT | | 1115 | AUDIT-0372-T | TODO | Report | Guild | src/__Libraries/StellaOps.IssuerDirectory.Client/StellaOps.IssuerDirectory.Client.csproj - TEST | | 1116 | AUDIT-0372-A | TODO | Approval | Guild | src/__Libraries/StellaOps.IssuerDirectory.Client/StellaOps.IssuerDirectory.Client.csproj - APPLY | @@ -1141,7 +1141,7 @@ Bulk task definitions (applies to every project row below): | 1119 | AUDIT-0373-A | TODO | Approval | Guild | src/IssuerDirectory/StellaOps.IssuerDirectory/StellaOps.IssuerDirectory.Core/StellaOps.IssuerDirectory.Core.csproj - APPLY | | 1120 | AUDIT-0374-M | TODO | Report | Guild | src/IssuerDirectory/StellaOps.IssuerDirectory/StellaOps.IssuerDirectory.Core.Tests/StellaOps.IssuerDirectory.Core.Tests.csproj - MAINT | | 1121 | AUDIT-0374-T | TODO | Report | Guild | src/IssuerDirectory/StellaOps.IssuerDirectory/StellaOps.IssuerDirectory.Core.Tests/StellaOps.IssuerDirectory.Core.Tests.csproj - TEST | -| 1122 | AUDIT-0374-A | TODO | Approval | Guild | src/IssuerDirectory/StellaOps.IssuerDirectory/StellaOps.IssuerDirectory.Core.Tests/StellaOps.IssuerDirectory.Core.Tests.csproj - APPLY | +| 1122 | AUDIT-0374-A | DONE | Waived (test project) | Guild | src/IssuerDirectory/StellaOps.IssuerDirectory/StellaOps.IssuerDirectory.Core.Tests/StellaOps.IssuerDirectory.Core.Tests.csproj - APPLY | | 1123 | AUDIT-0375-M | TODO | Report | Guild | src/IssuerDirectory/StellaOps.IssuerDirectory/StellaOps.IssuerDirectory.Infrastructure/StellaOps.IssuerDirectory.Infrastructure.csproj - MAINT | | 1124 | AUDIT-0375-T | TODO | Report | Guild | src/IssuerDirectory/StellaOps.IssuerDirectory/StellaOps.IssuerDirectory.Infrastructure/StellaOps.IssuerDirectory.Infrastructure.csproj - TEST | | 1125 | AUDIT-0375-A | TODO | Approval | Guild | src/IssuerDirectory/StellaOps.IssuerDirectory/StellaOps.IssuerDirectory.Infrastructure/StellaOps.IssuerDirectory.Infrastructure.csproj - APPLY | @@ -1150,7 +1150,7 @@ Bulk task definitions (applies to every project row below): | 1128 | AUDIT-0376-A | TODO | Approval | Guild | src/IssuerDirectory/__Libraries/StellaOps.IssuerDirectory.Persistence/StellaOps.IssuerDirectory.Persistence.csproj - APPLY | | 1129 | AUDIT-0377-M | TODO | Report | Guild | src/IssuerDirectory/__Tests/StellaOps.IssuerDirectory.Persistence.Tests/StellaOps.IssuerDirectory.Persistence.Tests.csproj - MAINT | | 1130 | AUDIT-0377-T | TODO | Report | Guild | src/IssuerDirectory/__Tests/StellaOps.IssuerDirectory.Persistence.Tests/StellaOps.IssuerDirectory.Persistence.Tests.csproj - TEST | -| 1131 | AUDIT-0377-A | TODO | Approval | Guild | src/IssuerDirectory/__Tests/StellaOps.IssuerDirectory.Persistence.Tests/StellaOps.IssuerDirectory.Persistence.Tests.csproj - APPLY | +| 1131 | AUDIT-0377-A | DONE | Waived (test project) | Guild | src/IssuerDirectory/__Tests/StellaOps.IssuerDirectory.Persistence.Tests/StellaOps.IssuerDirectory.Persistence.Tests.csproj - APPLY | | 1132 | AUDIT-0378-M | TODO | Report | Guild | src/IssuerDirectory/StellaOps.IssuerDirectory/StellaOps.IssuerDirectory.WebService/StellaOps.IssuerDirectory.WebService.csproj - MAINT | | 1133 | AUDIT-0378-T | TODO | Report | Guild | src/IssuerDirectory/StellaOps.IssuerDirectory/StellaOps.IssuerDirectory.WebService/StellaOps.IssuerDirectory.WebService.csproj - TEST | | 1134 | AUDIT-0378-A | TODO | Approval | Guild | src/IssuerDirectory/StellaOps.IssuerDirectory/StellaOps.IssuerDirectory.WebService/StellaOps.IssuerDirectory.WebService.csproj - APPLY | @@ -1159,7 +1159,7 @@ Bulk task definitions (applies to every project row below): | 1137 | AUDIT-0379-A | TODO | Approval | Guild | src/Router/__Libraries/StellaOps.Messaging/StellaOps.Messaging.csproj - APPLY | | 1138 | AUDIT-0380-M | TODO | Report | Guild | src/Router/__Tests/__Libraries/StellaOps.Messaging.Testing/StellaOps.Messaging.Testing.csproj - MAINT | | 1139 | AUDIT-0380-T | TODO | Report | Guild | src/Router/__Tests/__Libraries/StellaOps.Messaging.Testing/StellaOps.Messaging.Testing.csproj - TEST | -| 1140 | AUDIT-0380-A | TODO | Approval | Guild | src/Router/__Tests/__Libraries/StellaOps.Messaging.Testing/StellaOps.Messaging.Testing.csproj - APPLY | +| 1140 | AUDIT-0380-A | DONE | Waived (test project) | Guild | src/Router/__Tests/__Libraries/StellaOps.Messaging.Testing/StellaOps.Messaging.Testing.csproj - APPLY | | 1141 | AUDIT-0381-M | TODO | Report | Guild | src/Router/__Libraries/StellaOps.Messaging.Transport.InMemory/StellaOps.Messaging.Transport.InMemory.csproj - MAINT | | 1142 | AUDIT-0381-T | TODO | Report | Guild | src/Router/__Libraries/StellaOps.Messaging.Transport.InMemory/StellaOps.Messaging.Transport.InMemory.csproj - TEST | | 1143 | AUDIT-0381-A | TODO | Approval | Guild | src/Router/__Libraries/StellaOps.Messaging.Transport.InMemory/StellaOps.Messaging.Transport.InMemory.csproj - APPLY | @@ -1171,13 +1171,13 @@ Bulk task definitions (applies to every project row below): | 1149 | AUDIT-0383-A | TODO | Approval | Guild | src/Router/__Libraries/StellaOps.Messaging.Transport.Valkey/StellaOps.Messaging.Transport.Valkey.csproj - APPLY | | 1150 | AUDIT-0384-M | TODO | Report | Guild | src/Router/__Tests/StellaOps.Messaging.Transport.Valkey.Tests/StellaOps.Messaging.Transport.Valkey.Tests.csproj - MAINT | | 1151 | AUDIT-0384-T | TODO | Report | Guild | src/Router/__Tests/StellaOps.Messaging.Transport.Valkey.Tests/StellaOps.Messaging.Transport.Valkey.Tests.csproj - TEST | -| 1152 | AUDIT-0384-A | TODO | Approval | Guild | src/Router/__Tests/StellaOps.Messaging.Transport.Valkey.Tests/StellaOps.Messaging.Transport.Valkey.Tests.csproj - APPLY | +| 1152 | AUDIT-0384-A | DONE | Waived (test project) | Guild | src/Router/__Tests/StellaOps.Messaging.Transport.Valkey.Tests/StellaOps.Messaging.Transport.Valkey.Tests.csproj - APPLY | | 1153 | AUDIT-0385-M | TODO | Report | Guild | src/__Libraries/StellaOps.Metrics/StellaOps.Metrics.csproj - MAINT | | 1154 | AUDIT-0385-T | TODO | Report | Guild | src/__Libraries/StellaOps.Metrics/StellaOps.Metrics.csproj - TEST | | 1155 | AUDIT-0385-A | TODO | Approval | Guild | src/__Libraries/StellaOps.Metrics/StellaOps.Metrics.csproj - APPLY | | 1156 | AUDIT-0386-M | TODO | Report | Guild | src/__Libraries/__Tests/StellaOps.Metrics.Tests/StellaOps.Metrics.Tests.csproj - MAINT | | 1157 | AUDIT-0386-T | TODO | Report | Guild | src/__Libraries/__Tests/StellaOps.Metrics.Tests/StellaOps.Metrics.Tests.csproj - TEST | -| 1158 | AUDIT-0386-A | TODO | Approval | Guild | src/__Libraries/__Tests/StellaOps.Metrics.Tests/StellaOps.Metrics.Tests.csproj - APPLY | +| 1158 | AUDIT-0386-A | DONE | Waived (test project) | Guild | src/__Libraries/__Tests/StellaOps.Metrics.Tests/StellaOps.Metrics.Tests.csproj - APPLY | | 1159 | AUDIT-0387-M | TODO | Report | Guild | src/Router/__Libraries/StellaOps.Microservice/StellaOps.Microservice.csproj - MAINT | | 1160 | AUDIT-0387-T | TODO | Report | Guild | src/Router/__Libraries/StellaOps.Microservice/StellaOps.Microservice.csproj - TEST | | 1161 | AUDIT-0387-A | TODO | Approval | Guild | src/Router/__Libraries/StellaOps.Microservice/StellaOps.Microservice.csproj - APPLY | @@ -1186,22 +1186,22 @@ Bulk task definitions (applies to every project row below): | 1164 | AUDIT-0388-A | TODO | Approval | Guild | src/Router/__Libraries/StellaOps.Microservice.AspNetCore/StellaOps.Microservice.AspNetCore.csproj - APPLY | | 1165 | AUDIT-0389-M | TODO | Report | Guild | src/__Libraries/__Tests/StellaOps.Microservice.AspNetCore.Tests/StellaOps.Microservice.AspNetCore.Tests.csproj - MAINT | | 1166 | AUDIT-0389-T | TODO | Report | Guild | src/__Libraries/__Tests/StellaOps.Microservice.AspNetCore.Tests/StellaOps.Microservice.AspNetCore.Tests.csproj - TEST | -| 1167 | AUDIT-0389-A | TODO | Approval | Guild | src/__Libraries/__Tests/StellaOps.Microservice.AspNetCore.Tests/StellaOps.Microservice.AspNetCore.Tests.csproj - APPLY | +| 1167 | AUDIT-0389-A | DONE | Waived (test project) | Guild | src/__Libraries/__Tests/StellaOps.Microservice.AspNetCore.Tests/StellaOps.Microservice.AspNetCore.Tests.csproj - APPLY | | 1168 | AUDIT-0390-M | TODO | Report | Guild | src/Router/__Libraries/StellaOps.Microservice.SourceGen/StellaOps.Microservice.SourceGen.csproj - MAINT | | 1169 | AUDIT-0390-T | TODO | Report | Guild | src/Router/__Libraries/StellaOps.Microservice.SourceGen/StellaOps.Microservice.SourceGen.csproj - TEST | | 1170 | AUDIT-0390-A | TODO | Approval | Guild | src/Router/__Libraries/StellaOps.Microservice.SourceGen/StellaOps.Microservice.SourceGen.csproj - APPLY | | 1171 | AUDIT-0391-M | TODO | Report | Guild | src/Router/__Tests/StellaOps.Microservice.SourceGen.Tests/StellaOps.Microservice.SourceGen.Tests.csproj - MAINT | | 1172 | AUDIT-0391-T | TODO | Report | Guild | src/Router/__Tests/StellaOps.Microservice.SourceGen.Tests/StellaOps.Microservice.SourceGen.Tests.csproj - TEST | -| 1173 | AUDIT-0391-A | TODO | Approval | Guild | src/Router/__Tests/StellaOps.Microservice.SourceGen.Tests/StellaOps.Microservice.SourceGen.Tests.csproj - APPLY | +| 1173 | AUDIT-0391-A | DONE | Waived (test project) | Guild | src/Router/__Tests/StellaOps.Microservice.SourceGen.Tests/StellaOps.Microservice.SourceGen.Tests.csproj - APPLY | | 1174 | AUDIT-0392-M | TODO | Report | Guild | src/__Tests/StellaOps.Microservice.Tests/StellaOps.Microservice.Tests.csproj - MAINT | | 1175 | AUDIT-0392-T | TODO | Report | Guild | src/__Tests/StellaOps.Microservice.Tests/StellaOps.Microservice.Tests.csproj - TEST | -| 1176 | AUDIT-0392-A | TODO | Approval | Guild | src/__Tests/StellaOps.Microservice.Tests/StellaOps.Microservice.Tests.csproj - APPLY | +| 1176 | AUDIT-0392-A | DONE | Waived (test project) | Guild | src/__Tests/StellaOps.Microservice.Tests/StellaOps.Microservice.Tests.csproj - APPLY | | 1177 | AUDIT-0393-M | TODO | Report | Guild | src/Router/__Tests/StellaOps.Microservice.Tests/StellaOps.Microservice.Tests.csproj - MAINT | | 1178 | AUDIT-0393-T | TODO | Report | Guild | src/Router/__Tests/StellaOps.Microservice.Tests/StellaOps.Microservice.Tests.csproj - TEST | -| 1179 | AUDIT-0393-A | TODO | Approval | Guild | src/Router/__Tests/StellaOps.Microservice.Tests/StellaOps.Microservice.Tests.csproj - APPLY | +| 1179 | AUDIT-0393-A | DONE | Waived (test project) | Guild | src/Router/__Tests/StellaOps.Microservice.Tests/StellaOps.Microservice.Tests.csproj - APPLY | | 1180 | AUDIT-0394-M | TODO | Report | Guild | src/Notifier/StellaOps.Notifier/StellaOps.Notifier.Tests/StellaOps.Notifier.Tests.csproj - MAINT | | 1181 | AUDIT-0394-T | TODO | Report | Guild | src/Notifier/StellaOps.Notifier/StellaOps.Notifier.Tests/StellaOps.Notifier.Tests.csproj - TEST | -| 1182 | AUDIT-0394-A | TODO | Approval | Guild | src/Notifier/StellaOps.Notifier/StellaOps.Notifier.Tests/StellaOps.Notifier.Tests.csproj - APPLY | +| 1182 | AUDIT-0394-A | DONE | Waived (test project) | Guild | src/Notifier/StellaOps.Notifier/StellaOps.Notifier.Tests/StellaOps.Notifier.Tests.csproj - APPLY | | 1183 | AUDIT-0395-M | TODO | Report | Guild | src/Notifier/StellaOps.Notifier/StellaOps.Notifier.WebService/StellaOps.Notifier.WebService.csproj - MAINT | | 1184 | AUDIT-0395-T | TODO | Report | Guild | src/Notifier/StellaOps.Notifier/StellaOps.Notifier.WebService/StellaOps.Notifier.WebService.csproj - TEST | | 1185 | AUDIT-0395-A | TODO | Approval | Guild | src/Notifier/StellaOps.Notifier/StellaOps.Notifier.WebService/StellaOps.Notifier.WebService.csproj - APPLY | @@ -1213,7 +1213,7 @@ Bulk task definitions (applies to every project row below): | 1191 | AUDIT-0397-A | TODO | Approval | Guild | src/Notify/__Libraries/StellaOps.Notify.Connectors.Email/StellaOps.Notify.Connectors.Email.csproj - APPLY | | 1192 | AUDIT-0398-M | TODO | Report | Guild | src/Notify/__Tests/StellaOps.Notify.Connectors.Email.Tests/StellaOps.Notify.Connectors.Email.Tests.csproj - MAINT | | 1193 | AUDIT-0398-T | TODO | Report | Guild | src/Notify/__Tests/StellaOps.Notify.Connectors.Email.Tests/StellaOps.Notify.Connectors.Email.Tests.csproj - TEST | -| 1194 | AUDIT-0398-A | TODO | Approval | Guild | src/Notify/__Tests/StellaOps.Notify.Connectors.Email.Tests/StellaOps.Notify.Connectors.Email.Tests.csproj - APPLY | +| 1194 | AUDIT-0398-A | DONE | Waived (test project) | Guild | src/Notify/__Tests/StellaOps.Notify.Connectors.Email.Tests/StellaOps.Notify.Connectors.Email.Tests.csproj - APPLY | | 1195 | AUDIT-0399-M | TODO | Report | Guild | src/Notify/__Libraries/StellaOps.Notify.Connectors.Shared/StellaOps.Notify.Connectors.Shared.csproj - MAINT | | 1196 | AUDIT-0399-T | TODO | Report | Guild | src/Notify/__Libraries/StellaOps.Notify.Connectors.Shared/StellaOps.Notify.Connectors.Shared.csproj - TEST | | 1197 | AUDIT-0399-A | TODO | Approval | Guild | src/Notify/__Libraries/StellaOps.Notify.Connectors.Shared/StellaOps.Notify.Connectors.Shared.csproj - APPLY | @@ -1222,46 +1222,46 @@ Bulk task definitions (applies to every project row below): | 1200 | AUDIT-0400-A | TODO | Approval | Guild | src/Notify/__Libraries/StellaOps.Notify.Connectors.Slack/StellaOps.Notify.Connectors.Slack.csproj - APPLY | | 1201 | AUDIT-0401-M | TODO | Report | Guild | src/Notify/__Tests/StellaOps.Notify.Connectors.Slack.Tests/StellaOps.Notify.Connectors.Slack.Tests.csproj - MAINT | | 1202 | AUDIT-0401-T | TODO | Report | Guild | src/Notify/__Tests/StellaOps.Notify.Connectors.Slack.Tests/StellaOps.Notify.Connectors.Slack.Tests.csproj - TEST | -| 1203 | AUDIT-0401-A | TODO | Approval | Guild | src/Notify/__Tests/StellaOps.Notify.Connectors.Slack.Tests/StellaOps.Notify.Connectors.Slack.Tests.csproj - APPLY | +| 1203 | AUDIT-0401-A | DONE | Waived (test project) | Guild | src/Notify/__Tests/StellaOps.Notify.Connectors.Slack.Tests/StellaOps.Notify.Connectors.Slack.Tests.csproj - APPLY | | 1204 | AUDIT-0402-M | TODO | Report | Guild | src/Notify/__Libraries/StellaOps.Notify.Connectors.Teams/StellaOps.Notify.Connectors.Teams.csproj - MAINT | | 1205 | AUDIT-0402-T | TODO | Report | Guild | src/Notify/__Libraries/StellaOps.Notify.Connectors.Teams/StellaOps.Notify.Connectors.Teams.csproj - TEST | | 1206 | AUDIT-0402-A | TODO | Approval | Guild | src/Notify/__Libraries/StellaOps.Notify.Connectors.Teams/StellaOps.Notify.Connectors.Teams.csproj - APPLY | | 1207 | AUDIT-0403-M | TODO | Report | Guild | src/Notify/__Tests/StellaOps.Notify.Connectors.Teams.Tests/StellaOps.Notify.Connectors.Teams.Tests.csproj - MAINT | | 1208 | AUDIT-0403-T | TODO | Report | Guild | src/Notify/__Tests/StellaOps.Notify.Connectors.Teams.Tests/StellaOps.Notify.Connectors.Teams.Tests.csproj - TEST | -| 1209 | AUDIT-0403-A | TODO | Approval | Guild | src/Notify/__Tests/StellaOps.Notify.Connectors.Teams.Tests/StellaOps.Notify.Connectors.Teams.Tests.csproj - APPLY | +| 1209 | AUDIT-0403-A | DONE | Waived (test project) | Guild | src/Notify/__Tests/StellaOps.Notify.Connectors.Teams.Tests/StellaOps.Notify.Connectors.Teams.Tests.csproj - APPLY | | 1210 | AUDIT-0404-M | TODO | Report | Guild | src/Notify/__Libraries/StellaOps.Notify.Connectors.Webhook/StellaOps.Notify.Connectors.Webhook.csproj - MAINT | | 1211 | AUDIT-0404-T | TODO | Report | Guild | src/Notify/__Libraries/StellaOps.Notify.Connectors.Webhook/StellaOps.Notify.Connectors.Webhook.csproj - TEST | | 1212 | AUDIT-0404-A | TODO | Approval | Guild | src/Notify/__Libraries/StellaOps.Notify.Connectors.Webhook/StellaOps.Notify.Connectors.Webhook.csproj - APPLY | | 1213 | AUDIT-0405-M | TODO | Report | Guild | src/Notify/__Tests/StellaOps.Notify.Connectors.Webhook.Tests/StellaOps.Notify.Connectors.Webhook.Tests.csproj - MAINT | | 1214 | AUDIT-0405-T | TODO | Report | Guild | src/Notify/__Tests/StellaOps.Notify.Connectors.Webhook.Tests/StellaOps.Notify.Connectors.Webhook.Tests.csproj - TEST | -| 1215 | AUDIT-0405-A | TODO | Approval | Guild | src/Notify/__Tests/StellaOps.Notify.Connectors.Webhook.Tests/StellaOps.Notify.Connectors.Webhook.Tests.csproj - APPLY | +| 1215 | AUDIT-0405-A | DONE | Waived (test project) | Guild | src/Notify/__Tests/StellaOps.Notify.Connectors.Webhook.Tests/StellaOps.Notify.Connectors.Webhook.Tests.csproj - APPLY | | 1216 | AUDIT-0406-M | TODO | Report | Guild | src/Notify/__Tests/StellaOps.Notify.Core.Tests/StellaOps.Notify.Core.Tests.csproj - MAINT | | 1217 | AUDIT-0406-T | TODO | Report | Guild | src/Notify/__Tests/StellaOps.Notify.Core.Tests/StellaOps.Notify.Core.Tests.csproj - TEST | -| 1218 | AUDIT-0406-A | TODO | Approval | Guild | src/Notify/__Tests/StellaOps.Notify.Core.Tests/StellaOps.Notify.Core.Tests.csproj - APPLY | +| 1218 | AUDIT-0406-A | DONE | Waived (test project) | Guild | src/Notify/__Tests/StellaOps.Notify.Core.Tests/StellaOps.Notify.Core.Tests.csproj - APPLY | | 1219 | AUDIT-0407-M | TODO | Report | Guild | src/Notify/__Libraries/StellaOps.Notify.Engine/StellaOps.Notify.Engine.csproj - MAINT | | 1220 | AUDIT-0407-T | TODO | Report | Guild | src/Notify/__Libraries/StellaOps.Notify.Engine/StellaOps.Notify.Engine.csproj - TEST | | 1221 | AUDIT-0407-A | TODO | Approval | Guild | src/Notify/__Libraries/StellaOps.Notify.Engine/StellaOps.Notify.Engine.csproj - APPLY | | 1222 | AUDIT-0408-M | TODO | Report | Guild | src/Notify/__Tests/StellaOps.Notify.Engine.Tests/StellaOps.Notify.Engine.Tests.csproj - MAINT | | 1223 | AUDIT-0408-T | TODO | Report | Guild | src/Notify/__Tests/StellaOps.Notify.Engine.Tests/StellaOps.Notify.Engine.Tests.csproj - TEST | -| 1224 | AUDIT-0408-A | TODO | Approval | Guild | src/Notify/__Tests/StellaOps.Notify.Engine.Tests/StellaOps.Notify.Engine.Tests.csproj - APPLY | +| 1224 | AUDIT-0408-A | DONE | Waived (test project) | Guild | src/Notify/__Tests/StellaOps.Notify.Engine.Tests/StellaOps.Notify.Engine.Tests.csproj - APPLY | | 1225 | AUDIT-0409-M | TODO | Report | Guild | src/Notify/__Libraries/StellaOps.Notify.Models/StellaOps.Notify.Models.csproj - MAINT | | 1226 | AUDIT-0409-T | TODO | Report | Guild | src/Notify/__Libraries/StellaOps.Notify.Models/StellaOps.Notify.Models.csproj - TEST | | 1227 | AUDIT-0409-A | TODO | Approval | Guild | src/Notify/__Libraries/StellaOps.Notify.Models/StellaOps.Notify.Models.csproj - APPLY | | 1228 | AUDIT-0410-M | TODO | Report | Guild | src/Notify/__Tests/StellaOps.Notify.Models.Tests/StellaOps.Notify.Models.Tests.csproj - MAINT | | 1229 | AUDIT-0410-T | TODO | Report | Guild | src/Notify/__Tests/StellaOps.Notify.Models.Tests/StellaOps.Notify.Models.Tests.csproj - TEST | -| 1230 | AUDIT-0410-A | TODO | Approval | Guild | src/Notify/__Tests/StellaOps.Notify.Models.Tests/StellaOps.Notify.Models.Tests.csproj - APPLY | +| 1230 | AUDIT-0410-A | DONE | Waived (test project) | Guild | src/Notify/__Tests/StellaOps.Notify.Models.Tests/StellaOps.Notify.Models.Tests.csproj - APPLY | | 1231 | AUDIT-0411-M | TODO | Report | Guild | src/Notify/__Libraries/StellaOps.Notify.Persistence/StellaOps.Notify.Persistence.csproj - MAINT | | 1232 | AUDIT-0411-T | TODO | Report | Guild | src/Notify/__Libraries/StellaOps.Notify.Persistence/StellaOps.Notify.Persistence.csproj - TEST | | 1233 | AUDIT-0411-A | TODO | Approval | Guild | src/Notify/__Libraries/StellaOps.Notify.Persistence/StellaOps.Notify.Persistence.csproj - APPLY | | 1234 | AUDIT-0412-M | TODO | Report | Guild | src/Notify/__Tests/StellaOps.Notify.Persistence.Tests/StellaOps.Notify.Persistence.Tests.csproj - MAINT | | 1235 | AUDIT-0412-T | TODO | Report | Guild | src/Notify/__Tests/StellaOps.Notify.Persistence.Tests/StellaOps.Notify.Persistence.Tests.csproj - TEST | -| 1236 | AUDIT-0412-A | TODO | Approval | Guild | src/Notify/__Tests/StellaOps.Notify.Persistence.Tests/StellaOps.Notify.Persistence.Tests.csproj - APPLY | +| 1236 | AUDIT-0412-A | DONE | Waived (test project) | Guild | src/Notify/__Tests/StellaOps.Notify.Persistence.Tests/StellaOps.Notify.Persistence.Tests.csproj - APPLY | | 1237 | AUDIT-0413-M | TODO | Report | Guild | src/Notify/__Libraries/StellaOps.Notify.Queue/StellaOps.Notify.Queue.csproj - MAINT | | 1238 | AUDIT-0413-T | TODO | Report | Guild | src/Notify/__Libraries/StellaOps.Notify.Queue/StellaOps.Notify.Queue.csproj - TEST | | 1239 | AUDIT-0413-A | TODO | Approval | Guild | src/Notify/__Libraries/StellaOps.Notify.Queue/StellaOps.Notify.Queue.csproj - APPLY | | 1240 | AUDIT-0414-M | TODO | Report | Guild | src/Notify/__Tests/StellaOps.Notify.Queue.Tests/StellaOps.Notify.Queue.Tests.csproj - MAINT | | 1241 | AUDIT-0414-T | TODO | Report | Guild | src/Notify/__Tests/StellaOps.Notify.Queue.Tests/StellaOps.Notify.Queue.Tests.csproj - TEST | -| 1242 | AUDIT-0414-A | TODO | Approval | Guild | src/Notify/__Tests/StellaOps.Notify.Queue.Tests/StellaOps.Notify.Queue.Tests.csproj - APPLY | +| 1242 | AUDIT-0414-A | DONE | Waived (test project) | Guild | src/Notify/__Tests/StellaOps.Notify.Queue.Tests/StellaOps.Notify.Queue.Tests.csproj - APPLY | | 1243 | AUDIT-0415-M | TODO | Report | Guild | src/Notify/__Libraries/StellaOps.Notify.Storage.InMemory/StellaOps.Notify.Storage.InMemory.csproj - MAINT | | 1244 | AUDIT-0415-T | TODO | Report | Guild | src/Notify/__Libraries/StellaOps.Notify.Storage.InMemory/StellaOps.Notify.Storage.InMemory.csproj - TEST | | 1245 | AUDIT-0415-A | TODO | Approval | Guild | src/Notify/__Libraries/StellaOps.Notify.Storage.InMemory/StellaOps.Notify.Storage.InMemory.csproj - APPLY | @@ -1270,16 +1270,16 @@ Bulk task definitions (applies to every project row below): | 1248 | AUDIT-0416-A | TODO | Approval | Guild | src/Notify/StellaOps.Notify.WebService/StellaOps.Notify.WebService.csproj - APPLY | | 1249 | AUDIT-0417-M | TODO | Report | Guild | src/Notify/__Tests/StellaOps.Notify.WebService.Tests/StellaOps.Notify.WebService.Tests.csproj - MAINT | | 1250 | AUDIT-0417-T | TODO | Report | Guild | src/Notify/__Tests/StellaOps.Notify.WebService.Tests/StellaOps.Notify.WebService.Tests.csproj - TEST | -| 1251 | AUDIT-0417-A | TODO | Approval | Guild | src/Notify/__Tests/StellaOps.Notify.WebService.Tests/StellaOps.Notify.WebService.Tests.csproj - APPLY | +| 1251 | AUDIT-0417-A | DONE | Waived (test project) | Guild | src/Notify/__Tests/StellaOps.Notify.WebService.Tests/StellaOps.Notify.WebService.Tests.csproj - APPLY | | 1252 | AUDIT-0418-M | TODO | Report | Guild | src/Notify/StellaOps.Notify.Worker/StellaOps.Notify.Worker.csproj - MAINT | | 1253 | AUDIT-0418-T | TODO | Report | Guild | src/Notify/StellaOps.Notify.Worker/StellaOps.Notify.Worker.csproj - TEST | | 1254 | AUDIT-0418-A | TODO | Approval | Guild | src/Notify/StellaOps.Notify.Worker/StellaOps.Notify.Worker.csproj - APPLY | | 1255 | AUDIT-0419-M | TODO | Report | Guild | src/Notify/__Tests/StellaOps.Notify.Worker.Tests/StellaOps.Notify.Worker.Tests.csproj - MAINT | | 1256 | AUDIT-0419-T | TODO | Report | Guild | src/Notify/__Tests/StellaOps.Notify.Worker.Tests/StellaOps.Notify.Worker.Tests.csproj - TEST | -| 1257 | AUDIT-0419-A | TODO | Approval | Guild | src/Notify/__Tests/StellaOps.Notify.Worker.Tests/StellaOps.Notify.Worker.Tests.csproj - APPLY | +| 1257 | AUDIT-0419-A | DONE | Waived (test project) | Guild | src/Notify/__Tests/StellaOps.Notify.Worker.Tests/StellaOps.Notify.Worker.Tests.csproj - APPLY | | 1258 | AUDIT-0420-M | TODO | Report | Guild | src/__Tests/offline/StellaOps.Offline.E2E.Tests/StellaOps.Offline.E2E.Tests.csproj - MAINT | | 1259 | AUDIT-0420-T | TODO | Report | Guild | src/__Tests/offline/StellaOps.Offline.E2E.Tests/StellaOps.Offline.E2E.Tests.csproj - TEST | -| 1260 | AUDIT-0420-A | TODO | Approval | Guild | src/__Tests/offline/StellaOps.Offline.E2E.Tests/StellaOps.Offline.E2E.Tests.csproj - APPLY | +| 1260 | AUDIT-0420-A | DONE | Waived (test project) | Guild | src/__Tests/offline/StellaOps.Offline.E2E.Tests/StellaOps.Offline.E2E.Tests.csproj - APPLY | | 1261 | AUDIT-0421-M | TODO | Report | Guild | src/Orchestrator/StellaOps.Orchestrator/StellaOps.Orchestrator.Core/StellaOps.Orchestrator.Core.csproj - MAINT | | 1262 | AUDIT-0421-T | TODO | Report | Guild | src/Orchestrator/StellaOps.Orchestrator/StellaOps.Orchestrator.Core/StellaOps.Orchestrator.Core.csproj - TEST | | 1263 | AUDIT-0421-A | TODO | Approval | Guild | src/Orchestrator/StellaOps.Orchestrator/StellaOps.Orchestrator.Core/StellaOps.Orchestrator.Core.csproj - APPLY | @@ -1291,7 +1291,7 @@ Bulk task definitions (applies to every project row below): | 1269 | AUDIT-0423-A | TODO | Approval | Guild | src/__Libraries/StellaOps.Orchestrator.Schemas/StellaOps.Orchestrator.Schemas.csproj - APPLY | | 1270 | AUDIT-0424-M | TODO | Report | Guild | src/Orchestrator/StellaOps.Orchestrator/StellaOps.Orchestrator.Tests/StellaOps.Orchestrator.Tests.csproj - MAINT | | 1271 | AUDIT-0424-T | TODO | Report | Guild | src/Orchestrator/StellaOps.Orchestrator/StellaOps.Orchestrator.Tests/StellaOps.Orchestrator.Tests.csproj - TEST | -| 1272 | AUDIT-0424-A | TODO | Approval | Guild | src/Orchestrator/StellaOps.Orchestrator/StellaOps.Orchestrator.Tests/StellaOps.Orchestrator.Tests.csproj - APPLY | +| 1272 | AUDIT-0424-A | DONE | Waived (test project) | Guild | src/Orchestrator/StellaOps.Orchestrator/StellaOps.Orchestrator.Tests/StellaOps.Orchestrator.Tests.csproj - APPLY | | 1273 | AUDIT-0425-M | TODO | Report | Guild | src/Orchestrator/StellaOps.Orchestrator/StellaOps.Orchestrator.WebService/StellaOps.Orchestrator.WebService.csproj - MAINT | | 1274 | AUDIT-0425-T | TODO | Report | Guild | src/Orchestrator/StellaOps.Orchestrator/StellaOps.Orchestrator.WebService/StellaOps.Orchestrator.WebService.csproj - TEST | | 1275 | AUDIT-0425-A | TODO | Approval | Guild | src/Orchestrator/StellaOps.Orchestrator/StellaOps.Orchestrator.WebService/StellaOps.Orchestrator.WebService.csproj - APPLY | @@ -1312,10 +1312,10 @@ Bulk task definitions (applies to every project row below): | 1290 | AUDIT-0430-A | TODO | Approval | Guild | src/PacksRegistry/StellaOps.PacksRegistry/StellaOps.PacksRegistry.Persistence.EfCore/StellaOps.PacksRegistry.Persistence.EfCore.csproj - APPLY | | 1291 | AUDIT-0431-M | TODO | Report | Guild | src/PacksRegistry/__Tests/StellaOps.PacksRegistry.Persistence.Tests/StellaOps.PacksRegistry.Persistence.Tests.csproj - MAINT | | 1292 | AUDIT-0431-T | TODO | Report | Guild | src/PacksRegistry/__Tests/StellaOps.PacksRegistry.Persistence.Tests/StellaOps.PacksRegistry.Persistence.Tests.csproj - TEST | -| 1293 | AUDIT-0431-A | TODO | Approval | Guild | src/PacksRegistry/__Tests/StellaOps.PacksRegistry.Persistence.Tests/StellaOps.PacksRegistry.Persistence.Tests.csproj - APPLY | +| 1293 | AUDIT-0431-A | DONE | Waived (test project) | Guild | src/PacksRegistry/__Tests/StellaOps.PacksRegistry.Persistence.Tests/StellaOps.PacksRegistry.Persistence.Tests.csproj - APPLY | | 1294 | AUDIT-0432-M | TODO | Report | Guild | src/PacksRegistry/StellaOps.PacksRegistry/StellaOps.PacksRegistry.Tests/StellaOps.PacksRegistry.Tests.csproj - MAINT | | 1295 | AUDIT-0432-T | TODO | Report | Guild | src/PacksRegistry/StellaOps.PacksRegistry/StellaOps.PacksRegistry.Tests/StellaOps.PacksRegistry.Tests.csproj - TEST | -| 1296 | AUDIT-0432-A | TODO | Approval | Guild | src/PacksRegistry/StellaOps.PacksRegistry/StellaOps.PacksRegistry.Tests/StellaOps.PacksRegistry.Tests.csproj - APPLY | +| 1296 | AUDIT-0432-A | DONE | Waived (test project) | Guild | src/PacksRegistry/StellaOps.PacksRegistry/StellaOps.PacksRegistry.Tests/StellaOps.PacksRegistry.Tests.csproj - APPLY | | 1297 | AUDIT-0433-M | TODO | Report | Guild | src/PacksRegistry/StellaOps.PacksRegistry/StellaOps.PacksRegistry.WebService/StellaOps.PacksRegistry.WebService.csproj - MAINT | | 1298 | AUDIT-0433-T | TODO | Report | Guild | src/PacksRegistry/StellaOps.PacksRegistry/StellaOps.PacksRegistry.WebService/StellaOps.PacksRegistry.WebService.csproj - TEST | | 1299 | AUDIT-0433-A | TODO | Approval | Guild | src/PacksRegistry/StellaOps.PacksRegistry/StellaOps.PacksRegistry.WebService/StellaOps.PacksRegistry.WebService.csproj - APPLY | @@ -1324,13 +1324,13 @@ Bulk task definitions (applies to every project row below): | 1302 | AUDIT-0434-A | TODO | Approval | Guild | src/PacksRegistry/StellaOps.PacksRegistry/StellaOps.PacksRegistry.Worker/StellaOps.PacksRegistry.Worker.csproj - APPLY | | 1303 | AUDIT-0435-M | TODO | Report | Guild | src/__Tests/parity/StellaOps.Parity.Tests/StellaOps.Parity.Tests.csproj - MAINT | | 1304 | AUDIT-0435-T | TODO | Report | Guild | src/__Tests/parity/StellaOps.Parity.Tests/StellaOps.Parity.Tests.csproj - TEST | -| 1305 | AUDIT-0435-A | TODO | Approval | Guild | src/__Tests/parity/StellaOps.Parity.Tests/StellaOps.Parity.Tests.csproj - APPLY | +| 1305 | AUDIT-0435-A | DONE | Waived (test project) | Guild | src/__Tests/parity/StellaOps.Parity.Tests/StellaOps.Parity.Tests.csproj - APPLY | | 1306 | AUDIT-0436-M | TODO | Report | Guild | src/__Libraries/StellaOps.Plugin/StellaOps.Plugin.csproj - MAINT | | 1307 | AUDIT-0436-T | TODO | Report | Guild | src/__Libraries/StellaOps.Plugin/StellaOps.Plugin.csproj - TEST | | 1308 | AUDIT-0436-A | TODO | Approval | Guild | src/__Libraries/StellaOps.Plugin/StellaOps.Plugin.csproj - APPLY | | 1309 | AUDIT-0437-M | TODO | Report | Guild | src/__Libraries/__Tests/StellaOps.Plugin.Tests/StellaOps.Plugin.Tests.csproj - MAINT | | 1310 | AUDIT-0437-T | TODO | Report | Guild | src/__Libraries/__Tests/StellaOps.Plugin.Tests/StellaOps.Plugin.Tests.csproj - TEST | -| 1311 | AUDIT-0437-A | TODO | Approval | Guild | src/__Libraries/__Tests/StellaOps.Plugin.Tests/StellaOps.Plugin.Tests.csproj - APPLY | +| 1311 | AUDIT-0437-A | DONE | Waived (test project) | Guild | src/__Libraries/__Tests/StellaOps.Plugin.Tests/StellaOps.Plugin.Tests.csproj - APPLY | | 1312 | AUDIT-0438-M | TODO | Report | Guild | src/Policy/__Libraries/StellaOps.Policy/StellaOps.Policy.csproj - MAINT | | 1313 | AUDIT-0438-T | TODO | Report | Guild | src/Policy/__Libraries/StellaOps.Policy/StellaOps.Policy.csproj - TEST | | 1314 | AUDIT-0438-A | TODO | Approval | Guild | src/Policy/__Libraries/StellaOps.Policy/StellaOps.Policy.csproj - APPLY | @@ -1342,31 +1342,31 @@ Bulk task definitions (applies to every project row below): | 1320 | AUDIT-0440-A | TODO | Approval | Guild | src/Policy/StellaOps.Policy.Engine/StellaOps.Policy.Engine.csproj - APPLY | | 1321 | AUDIT-0441-M | TODO | Report | Guild | src/Policy/__Tests/StellaOps.Policy.Engine.Contract.Tests/StellaOps.Policy.Engine.Contract.Tests.csproj - MAINT | | 1322 | AUDIT-0441-T | TODO | Report | Guild | src/Policy/__Tests/StellaOps.Policy.Engine.Contract.Tests/StellaOps.Policy.Engine.Contract.Tests.csproj - TEST | -| 1323 | AUDIT-0441-A | TODO | Approval | Guild | src/Policy/__Tests/StellaOps.Policy.Engine.Contract.Tests/StellaOps.Policy.Engine.Contract.Tests.csproj - APPLY | +| 1323 | AUDIT-0441-A | DONE | Waived (test project) | Guild | src/Policy/__Tests/StellaOps.Policy.Engine.Contract.Tests/StellaOps.Policy.Engine.Contract.Tests.csproj - APPLY | | 1324 | AUDIT-0442-M | TODO | Report | Guild | src/Policy/__Tests/StellaOps.Policy.Engine.Tests/StellaOps.Policy.Engine.Tests.csproj - MAINT | | 1325 | AUDIT-0442-T | TODO | Report | Guild | src/Policy/__Tests/StellaOps.Policy.Engine.Tests/StellaOps.Policy.Engine.Tests.csproj - TEST | -| 1326 | AUDIT-0442-A | TODO | Approval | Guild | src/Policy/__Tests/StellaOps.Policy.Engine.Tests/StellaOps.Policy.Engine.Tests.csproj - APPLY | +| 1326 | AUDIT-0442-A | DONE | Waived (test project) | Guild | src/Policy/__Tests/StellaOps.Policy.Engine.Tests/StellaOps.Policy.Engine.Tests.csproj - APPLY | | 1327 | AUDIT-0443-M | TODO | Report | Guild | src/Policy/__Libraries/StellaOps.Policy.Exceptions/StellaOps.Policy.Exceptions.csproj - MAINT | | 1328 | AUDIT-0443-T | TODO | Report | Guild | src/Policy/__Libraries/StellaOps.Policy.Exceptions/StellaOps.Policy.Exceptions.csproj - TEST | | 1329 | AUDIT-0443-A | TODO | Approval | Guild | src/Policy/__Libraries/StellaOps.Policy.Exceptions/StellaOps.Policy.Exceptions.csproj - APPLY | | 1330 | AUDIT-0444-M | TODO | Report | Guild | src/Policy/__Tests/StellaOps.Policy.Exceptions.Tests/StellaOps.Policy.Exceptions.Tests.csproj - MAINT | | 1331 | AUDIT-0444-T | TODO | Report | Guild | src/Policy/__Tests/StellaOps.Policy.Exceptions.Tests/StellaOps.Policy.Exceptions.Tests.csproj - TEST | -| 1332 | AUDIT-0444-A | TODO | Approval | Guild | src/Policy/__Tests/StellaOps.Policy.Exceptions.Tests/StellaOps.Policy.Exceptions.Tests.csproj - APPLY | +| 1332 | AUDIT-0444-A | DONE | Waived (test project) | Guild | src/Policy/__Tests/StellaOps.Policy.Exceptions.Tests/StellaOps.Policy.Exceptions.Tests.csproj - APPLY | | 1333 | AUDIT-0445-M | TODO | Report | Guild | src/Policy/StellaOps.Policy.Gateway/StellaOps.Policy.Gateway.csproj - MAINT | | 1334 | AUDIT-0445-T | TODO | Report | Guild | src/Policy/StellaOps.Policy.Gateway/StellaOps.Policy.Gateway.csproj - TEST | | 1335 | AUDIT-0445-A | TODO | Approval | Guild | src/Policy/StellaOps.Policy.Gateway/StellaOps.Policy.Gateway.csproj - APPLY | | 1336 | AUDIT-0446-M | TODO | Report | Guild | src/Policy/__Tests/StellaOps.Policy.Gateway.Tests/StellaOps.Policy.Gateway.Tests.csproj - MAINT | | 1337 | AUDIT-0446-T | TODO | Report | Guild | src/Policy/__Tests/StellaOps.Policy.Gateway.Tests/StellaOps.Policy.Gateway.Tests.csproj - TEST | -| 1338 | AUDIT-0446-A | TODO | Approval | Guild | src/Policy/__Tests/StellaOps.Policy.Gateway.Tests/StellaOps.Policy.Gateway.Tests.csproj - APPLY | +| 1338 | AUDIT-0446-A | DONE | Waived (test project) | Guild | src/Policy/__Tests/StellaOps.Policy.Gateway.Tests/StellaOps.Policy.Gateway.Tests.csproj - APPLY | | 1339 | AUDIT-0447-M | TODO | Report | Guild | src/Policy/__Tests/StellaOps.Policy.Pack.Tests/StellaOps.Policy.Pack.Tests.csproj - MAINT | | 1340 | AUDIT-0447-T | TODO | Report | Guild | src/Policy/__Tests/StellaOps.Policy.Pack.Tests/StellaOps.Policy.Pack.Tests.csproj - TEST | -| 1341 | AUDIT-0447-A | TODO | Approval | Guild | src/Policy/__Tests/StellaOps.Policy.Pack.Tests/StellaOps.Policy.Pack.Tests.csproj - APPLY | +| 1341 | AUDIT-0447-A | DONE | Waived (test project) | Guild | src/Policy/__Tests/StellaOps.Policy.Pack.Tests/StellaOps.Policy.Pack.Tests.csproj - APPLY | | 1342 | AUDIT-0448-M | TODO | Report | Guild | src/Policy/__Libraries/StellaOps.Policy.Persistence/StellaOps.Policy.Persistence.csproj - MAINT | | 1343 | AUDIT-0448-T | TODO | Report | Guild | src/Policy/__Libraries/StellaOps.Policy.Persistence/StellaOps.Policy.Persistence.csproj - TEST | | 1344 | AUDIT-0448-A | TODO | Approval | Guild | src/Policy/__Libraries/StellaOps.Policy.Persistence/StellaOps.Policy.Persistence.csproj - APPLY | | 1345 | AUDIT-0449-M | TODO | Report | Guild | src/Policy/__Tests/StellaOps.Policy.Persistence.Tests/StellaOps.Policy.Persistence.Tests.csproj - MAINT | | 1346 | AUDIT-0449-T | TODO | Report | Guild | src/Policy/__Tests/StellaOps.Policy.Persistence.Tests/StellaOps.Policy.Persistence.Tests.csproj - TEST | -| 1347 | AUDIT-0449-A | TODO | Approval | Guild | src/Policy/__Tests/StellaOps.Policy.Persistence.Tests/StellaOps.Policy.Persistence.Tests.csproj - APPLY | +| 1347 | AUDIT-0449-A | DONE | Waived (test project) | Guild | src/Policy/__Tests/StellaOps.Policy.Persistence.Tests/StellaOps.Policy.Persistence.Tests.csproj - APPLY | | 1348 | AUDIT-0450-M | TODO | Report | Guild | src/Policy/StellaOps.Policy.Registry/StellaOps.Policy.Registry.csproj - MAINT | | 1349 | AUDIT-0450-T | TODO | Report | Guild | src/Policy/StellaOps.Policy.Registry/StellaOps.Policy.Registry.csproj - TEST | | 1350 | AUDIT-0450-A | TODO | Approval | Guild | src/Policy/StellaOps.Policy.Registry/StellaOps.Policy.Registry.csproj - APPLY | @@ -1375,22 +1375,22 @@ Bulk task definitions (applies to every project row below): | 1353 | AUDIT-0451-A | TODO | Approval | Guild | src/Policy/StellaOps.Policy.RiskProfile/StellaOps.Policy.RiskProfile.csproj - APPLY | | 1354 | AUDIT-0452-M | TODO | Report | Guild | src/Policy/__Tests/StellaOps.Policy.RiskProfile.Tests/StellaOps.Policy.RiskProfile.Tests.csproj - MAINT | | 1355 | AUDIT-0452-T | TODO | Report | Guild | src/Policy/__Tests/StellaOps.Policy.RiskProfile.Tests/StellaOps.Policy.RiskProfile.Tests.csproj - TEST | -| 1356 | AUDIT-0452-A | TODO | Approval | Guild | src/Policy/__Tests/StellaOps.Policy.RiskProfile.Tests/StellaOps.Policy.RiskProfile.Tests.csproj - APPLY | +| 1356 | AUDIT-0452-A | DONE | Waived (test project) | Guild | src/Policy/__Tests/StellaOps.Policy.RiskProfile.Tests/StellaOps.Policy.RiskProfile.Tests.csproj - APPLY | | 1357 | AUDIT-0453-M | TODO | Report | Guild | src/Policy/StellaOps.Policy.Scoring/StellaOps.Policy.Scoring.csproj - MAINT | | 1358 | AUDIT-0453-T | TODO | Report | Guild | src/Policy/StellaOps.Policy.Scoring/StellaOps.Policy.Scoring.csproj - TEST | | 1359 | AUDIT-0453-A | TODO | Approval | Guild | src/Policy/StellaOps.Policy.Scoring/StellaOps.Policy.Scoring.csproj - APPLY | | 1360 | AUDIT-0454-M | TODO | Report | Guild | src/Policy/__Tests/StellaOps.Policy.Scoring.Tests/StellaOps.Policy.Scoring.Tests.csproj - MAINT | | 1361 | AUDIT-0454-T | TODO | Report | Guild | src/Policy/__Tests/StellaOps.Policy.Scoring.Tests/StellaOps.Policy.Scoring.Tests.csproj - TEST | -| 1362 | AUDIT-0454-A | TODO | Approval | Guild | src/Policy/__Tests/StellaOps.Policy.Scoring.Tests/StellaOps.Policy.Scoring.Tests.csproj - APPLY | +| 1362 | AUDIT-0454-A | DONE | Waived (test project) | Guild | src/Policy/__Tests/StellaOps.Policy.Scoring.Tests/StellaOps.Policy.Scoring.Tests.csproj - APPLY | | 1363 | AUDIT-0455-M | TODO | Report | Guild | src/Policy/__Tests/StellaOps.Policy.Tests/StellaOps.Policy.Tests.csproj - MAINT | | 1364 | AUDIT-0455-T | TODO | Report | Guild | src/Policy/__Tests/StellaOps.Policy.Tests/StellaOps.Policy.Tests.csproj - TEST | -| 1365 | AUDIT-0455-A | TODO | Approval | Guild | src/Policy/__Tests/StellaOps.Policy.Tests/StellaOps.Policy.Tests.csproj - APPLY | +| 1365 | AUDIT-0455-A | DONE | Waived (test project) | Guild | src/Policy/__Tests/StellaOps.Policy.Tests/StellaOps.Policy.Tests.csproj - APPLY | | 1366 | AUDIT-0456-M | TODO | Report | Guild | src/Policy/__Libraries/StellaOps.Policy.Unknowns/StellaOps.Policy.Unknowns.csproj - MAINT | | 1367 | AUDIT-0456-T | TODO | Report | Guild | src/Policy/__Libraries/StellaOps.Policy.Unknowns/StellaOps.Policy.Unknowns.csproj - TEST | | 1368 | AUDIT-0456-A | TODO | Approval | Guild | src/Policy/__Libraries/StellaOps.Policy.Unknowns/StellaOps.Policy.Unknowns.csproj - APPLY | | 1369 | AUDIT-0457-M | TODO | Report | Guild | src/Policy/__Tests/StellaOps.Policy.Unknowns.Tests/StellaOps.Policy.Unknowns.Tests.csproj - MAINT | | 1370 | AUDIT-0457-T | TODO | Report | Guild | src/Policy/__Tests/StellaOps.Policy.Unknowns.Tests/StellaOps.Policy.Unknowns.Tests.csproj - TEST | -| 1371 | AUDIT-0457-A | TODO | Approval | Guild | src/Policy/__Tests/StellaOps.Policy.Unknowns.Tests/StellaOps.Policy.Unknowns.Tests.csproj - APPLY | +| 1371 | AUDIT-0457-A | DONE | Waived (test project) | Guild | src/Policy/__Tests/StellaOps.Policy.Unknowns.Tests/StellaOps.Policy.Unknowns.Tests.csproj - APPLY | | 1372 | AUDIT-0458-M | TODO | Report | Guild | src/__Libraries/StellaOps.PolicyAuthoritySignals.Contracts/StellaOps.PolicyAuthoritySignals.Contracts.csproj - MAINT | | 1373 | AUDIT-0458-T | TODO | Report | Guild | src/__Libraries/StellaOps.PolicyAuthoritySignals.Contracts/StellaOps.PolicyAuthoritySignals.Contracts.csproj - TEST | | 1374 | AUDIT-0458-A | TODO | Approval | Guild | src/__Libraries/StellaOps.PolicyAuthoritySignals.Contracts/StellaOps.PolicyAuthoritySignals.Contracts.csproj - APPLY | @@ -1399,7 +1399,7 @@ Bulk task definitions (applies to every project row below): | 1377 | AUDIT-0459-A | TODO | Approval | Guild | src/Policy/StellaOps.PolicyDsl/StellaOps.PolicyDsl.csproj - APPLY | | 1378 | AUDIT-0460-M | TODO | Report | Guild | src/Policy/__Tests/StellaOps.PolicyDsl.Tests/StellaOps.PolicyDsl.Tests.csproj - MAINT | | 1379 | AUDIT-0460-T | TODO | Report | Guild | src/Policy/__Tests/StellaOps.PolicyDsl.Tests/StellaOps.PolicyDsl.Tests.csproj - TEST | -| 1380 | AUDIT-0460-A | TODO | Approval | Guild | src/Policy/__Tests/StellaOps.PolicyDsl.Tests/StellaOps.PolicyDsl.Tests.csproj - APPLY | +| 1380 | AUDIT-0460-A | DONE | Waived (test project) | Guild | src/Policy/__Tests/StellaOps.PolicyDsl.Tests/StellaOps.PolicyDsl.Tests.csproj - APPLY | | 1381 | AUDIT-0461-M | TODO | Report | Guild | src/__Libraries/StellaOps.Provcache/StellaOps.Provcache.csproj - MAINT | | 1382 | AUDIT-0461-T | TODO | Report | Guild | src/__Libraries/StellaOps.Provcache/StellaOps.Provcache.csproj - TEST | | 1383 | AUDIT-0461-A | TODO | Approval | Guild | src/__Libraries/StellaOps.Provcache/StellaOps.Provcache.csproj - APPLY | @@ -1411,7 +1411,7 @@ Bulk task definitions (applies to every project row below): | 1389 | AUDIT-0463-A | TODO | Approval | Guild | src/__Libraries/StellaOps.Provcache.Postgres/StellaOps.Provcache.Postgres.csproj - APPLY | | 1390 | AUDIT-0464-M | TODO | Report | Guild | src/__Libraries/__Tests/StellaOps.Provcache.Tests/StellaOps.Provcache.Tests.csproj - MAINT | | 1391 | AUDIT-0464-T | TODO | Report | Guild | src/__Libraries/__Tests/StellaOps.Provcache.Tests/StellaOps.Provcache.Tests.csproj - TEST | -| 1392 | AUDIT-0464-A | TODO | Approval | Guild | src/__Libraries/__Tests/StellaOps.Provcache.Tests/StellaOps.Provcache.Tests.csproj - APPLY | +| 1392 | AUDIT-0464-A | DONE | Waived (test project) | Guild | src/__Libraries/__Tests/StellaOps.Provcache.Tests/StellaOps.Provcache.Tests.csproj - APPLY | | 1393 | AUDIT-0465-M | TODO | Report | Guild | src/__Libraries/StellaOps.Provcache.Valkey/StellaOps.Provcache.Valkey.csproj - MAINT | | 1394 | AUDIT-0465-T | TODO | Report | Guild | src/__Libraries/StellaOps.Provcache.Valkey/StellaOps.Provcache.Valkey.csproj - TEST | | 1395 | AUDIT-0465-A | TODO | Approval | Guild | src/__Libraries/StellaOps.Provcache.Valkey/StellaOps.Provcache.Valkey.csproj - APPLY | @@ -1423,13 +1423,13 @@ Bulk task definitions (applies to every project row below): | 1401 | AUDIT-0467-A | TODO | Approval | Guild | src/Provenance/StellaOps.Provenance.Attestation/StellaOps.Provenance.Attestation.csproj - APPLY | | 1402 | AUDIT-0468-M | TODO | Report | Guild | src/Provenance/__Tests/StellaOps.Provenance.Attestation.Tests/StellaOps.Provenance.Attestation.Tests.csproj - MAINT | | 1403 | AUDIT-0468-T | TODO | Report | Guild | src/Provenance/__Tests/StellaOps.Provenance.Attestation.Tests/StellaOps.Provenance.Attestation.Tests.csproj - TEST | -| 1404 | AUDIT-0468-A | TODO | Approval | Guild | src/Provenance/__Tests/StellaOps.Provenance.Attestation.Tests/StellaOps.Provenance.Attestation.Tests.csproj - APPLY | +| 1404 | AUDIT-0468-A | DONE | Waived (test project) | Guild | src/Provenance/__Tests/StellaOps.Provenance.Attestation.Tests/StellaOps.Provenance.Attestation.Tests.csproj - APPLY | | 1405 | AUDIT-0469-M | TODO | Report | Guild | src/Provenance/StellaOps.Provenance.Attestation.Tool/StellaOps.Provenance.Attestation.Tool.csproj - MAINT | | 1406 | AUDIT-0469-T | TODO | Report | Guild | src/Provenance/StellaOps.Provenance.Attestation.Tool/StellaOps.Provenance.Attestation.Tool.csproj - TEST | | 1407 | AUDIT-0469-A | TODO | Approval | Guild | src/Provenance/StellaOps.Provenance.Attestation.Tool/StellaOps.Provenance.Attestation.Tool.csproj - APPLY | | 1408 | AUDIT-0470-M | TODO | Report | Guild | src/__Libraries/__Tests/StellaOps.Provenance.Tests/StellaOps.Provenance.Tests.csproj - MAINT | | 1409 | AUDIT-0470-T | TODO | Report | Guild | src/__Libraries/__Tests/StellaOps.Provenance.Tests/StellaOps.Provenance.Tests.csproj - TEST | -| 1410 | AUDIT-0470-A | TODO | Approval | Guild | src/__Libraries/__Tests/StellaOps.Provenance.Tests/StellaOps.Provenance.Tests.csproj - APPLY | +| 1410 | AUDIT-0470-A | DONE | Waived (test project) | Guild | src/__Libraries/__Tests/StellaOps.Provenance.Tests/StellaOps.Provenance.Tests.csproj - APPLY | | 1411 | AUDIT-0471-M | TODO | Report | Guild | src/__Libraries/StellaOps.ReachGraph/StellaOps.ReachGraph.csproj - MAINT | | 1412 | AUDIT-0471-T | TODO | Report | Guild | src/__Libraries/StellaOps.ReachGraph/StellaOps.ReachGraph.csproj - TEST | | 1413 | AUDIT-0471-A | TODO | Approval | Guild | src/__Libraries/StellaOps.ReachGraph/StellaOps.ReachGraph.csproj - APPLY | @@ -1441,22 +1441,22 @@ Bulk task definitions (applies to every project row below): | 1419 | AUDIT-0473-A | TODO | Approval | Guild | src/__Libraries/StellaOps.ReachGraph.Persistence/StellaOps.ReachGraph.Persistence.csproj - APPLY | | 1420 | AUDIT-0474-M | TODO | Report | Guild | src/__Libraries/__Tests/StellaOps.ReachGraph.Tests/StellaOps.ReachGraph.Tests.csproj - MAINT | | 1421 | AUDIT-0474-T | TODO | Report | Guild | src/__Libraries/__Tests/StellaOps.ReachGraph.Tests/StellaOps.ReachGraph.Tests.csproj - TEST | -| 1422 | AUDIT-0474-A | TODO | Approval | Guild | src/__Libraries/__Tests/StellaOps.ReachGraph.Tests/StellaOps.ReachGraph.Tests.csproj - APPLY | +| 1422 | AUDIT-0474-A | DONE | Waived (test project) | Guild | src/__Libraries/__Tests/StellaOps.ReachGraph.Tests/StellaOps.ReachGraph.Tests.csproj - APPLY | | 1423 | AUDIT-0475-M | TODO | Report | Guild | src/ReachGraph/StellaOps.ReachGraph.WebService/StellaOps.ReachGraph.WebService.csproj - MAINT | | 1424 | AUDIT-0475-T | TODO | Report | Guild | src/ReachGraph/StellaOps.ReachGraph.WebService/StellaOps.ReachGraph.WebService.csproj - TEST | | 1425 | AUDIT-0475-A | TODO | Approval | Guild | src/ReachGraph/StellaOps.ReachGraph.WebService/StellaOps.ReachGraph.WebService.csproj - APPLY | | 1426 | AUDIT-0476-M | TODO | Report | Guild | src/ReachGraph/__Tests/StellaOps.ReachGraph.WebService.Tests/StellaOps.ReachGraph.WebService.Tests.csproj - MAINT | | 1427 | AUDIT-0476-T | TODO | Report | Guild | src/ReachGraph/__Tests/StellaOps.ReachGraph.WebService.Tests/StellaOps.ReachGraph.WebService.Tests.csproj - TEST | -| 1428 | AUDIT-0476-A | TODO | Approval | Guild | src/ReachGraph/__Tests/StellaOps.ReachGraph.WebService.Tests/StellaOps.ReachGraph.WebService.Tests.csproj - APPLY | +| 1428 | AUDIT-0476-A | DONE | Waived (test project) | Guild | src/ReachGraph/__Tests/StellaOps.ReachGraph.WebService.Tests/StellaOps.ReachGraph.WebService.Tests.csproj - APPLY | | 1429 | AUDIT-0477-M | TODO | Report | Guild | src/__Tests/reachability/StellaOps.Reachability.FixtureTests/StellaOps.Reachability.FixtureTests.csproj - MAINT | | 1430 | AUDIT-0477-T | TODO | Report | Guild | src/__Tests/reachability/StellaOps.Reachability.FixtureTests/StellaOps.Reachability.FixtureTests.csproj - TEST | -| 1431 | AUDIT-0477-A | TODO | Approval | Guild | src/__Tests/reachability/StellaOps.Reachability.FixtureTests/StellaOps.Reachability.FixtureTests.csproj - APPLY | +| 1431 | AUDIT-0477-A | DONE | Waived (test project) | Guild | src/__Tests/reachability/StellaOps.Reachability.FixtureTests/StellaOps.Reachability.FixtureTests.csproj - APPLY | | 1432 | AUDIT-0478-M | TODO | Report | Guild | src/Registry/StellaOps.Registry.TokenService/StellaOps.Registry.TokenService.csproj - MAINT | | 1433 | AUDIT-0478-T | TODO | Report | Guild | src/Registry/StellaOps.Registry.TokenService/StellaOps.Registry.TokenService.csproj - TEST | | 1434 | AUDIT-0478-A | TODO | Approval | Guild | src/Registry/StellaOps.Registry.TokenService/StellaOps.Registry.TokenService.csproj - APPLY | | 1435 | AUDIT-0479-M | TODO | Report | Guild | src/Registry/__Tests/StellaOps.Registry.TokenService.Tests/StellaOps.Registry.TokenService.Tests.csproj - MAINT | | 1436 | AUDIT-0479-T | TODO | Report | Guild | src/Registry/__Tests/StellaOps.Registry.TokenService.Tests/StellaOps.Registry.TokenService.Tests.csproj - TEST | -| 1437 | AUDIT-0479-A | TODO | Approval | Guild | src/Registry/__Tests/StellaOps.Registry.TokenService.Tests/StellaOps.Registry.TokenService.Tests.csproj - APPLY | +| 1437 | AUDIT-0479-A | DONE | Waived (test project) | Guild | src/Registry/__Tests/StellaOps.Registry.TokenService.Tests/StellaOps.Registry.TokenService.Tests.csproj - APPLY | | 1438 | AUDIT-0480-M | TODO | Report | Guild | src/__Libraries/StellaOps.Replay/StellaOps.Replay.csproj - MAINT | | 1439 | AUDIT-0480-T | TODO | Report | Guild | src/__Libraries/StellaOps.Replay/StellaOps.Replay.csproj - TEST | | 1440 | AUDIT-0480-A | TODO | Approval | Guild | src/__Libraries/StellaOps.Replay/StellaOps.Replay.csproj - APPLY | @@ -1465,19 +1465,19 @@ Bulk task definitions (applies to every project row below): | 1443 | AUDIT-0481-A | TODO | Approval | Guild | src/__Libraries/StellaOps.Replay.Core/StellaOps.Replay.Core.csproj - APPLY | | 1444 | AUDIT-0482-M | TODO | Report | Guild | src/__Libraries/__Tests/StellaOps.Replay.Core.Tests/StellaOps.Replay.Core.Tests.csproj - MAINT | | 1445 | AUDIT-0482-T | TODO | Report | Guild | src/__Libraries/__Tests/StellaOps.Replay.Core.Tests/StellaOps.Replay.Core.Tests.csproj - TEST | -| 1446 | AUDIT-0482-A | TODO | Approval | Guild | src/__Libraries/__Tests/StellaOps.Replay.Core.Tests/StellaOps.Replay.Core.Tests.csproj - APPLY | +| 1446 | AUDIT-0482-A | DONE | Waived (test project) | Guild | src/__Libraries/__Tests/StellaOps.Replay.Core.Tests/StellaOps.Replay.Core.Tests.csproj - APPLY | | 1447 | AUDIT-0483-M | TODO | Report | Guild | src/__Libraries/StellaOps.Replay.Core.Tests/StellaOps.Replay.Core.Tests.csproj - MAINT | | 1448 | AUDIT-0483-T | TODO | Report | Guild | src/__Libraries/StellaOps.Replay.Core.Tests/StellaOps.Replay.Core.Tests.csproj - TEST | -| 1449 | AUDIT-0483-A | TODO | Approval | Guild | src/__Libraries/StellaOps.Replay.Core.Tests/StellaOps.Replay.Core.Tests.csproj - APPLY | +| 1449 | AUDIT-0483-A | DONE | Waived (test project) | Guild | src/__Libraries/StellaOps.Replay.Core.Tests/StellaOps.Replay.Core.Tests.csproj - APPLY | | 1450 | AUDIT-0484-M | TODO | Report | Guild | src/__Tests/reachability/StellaOps.Replay.Core.Tests/StellaOps.Replay.Core.Tests.csproj - MAINT | | 1451 | AUDIT-0484-T | TODO | Report | Guild | src/__Tests/reachability/StellaOps.Replay.Core.Tests/StellaOps.Replay.Core.Tests.csproj - TEST | -| 1452 | AUDIT-0484-A | TODO | Approval | Guild | src/__Tests/reachability/StellaOps.Replay.Core.Tests/StellaOps.Replay.Core.Tests.csproj - APPLY | +| 1452 | AUDIT-0484-A | DONE | Waived (test project) | Guild | src/__Tests/reachability/StellaOps.Replay.Core.Tests/StellaOps.Replay.Core.Tests.csproj - APPLY | | 1453 | AUDIT-0485-M | TODO | Report | Guild | src/Replay/__Tests/StellaOps.Replay.Core.Tests/StellaOps.Replay.Core.Tests.csproj - MAINT | | 1454 | AUDIT-0485-T | TODO | Report | Guild | src/Replay/__Tests/StellaOps.Replay.Core.Tests/StellaOps.Replay.Core.Tests.csproj - TEST | -| 1455 | AUDIT-0485-A | TODO | Approval | Guild | src/Replay/__Tests/StellaOps.Replay.Core.Tests/StellaOps.Replay.Core.Tests.csproj - APPLY | +| 1455 | AUDIT-0485-A | DONE | Waived (test project) | Guild | src/Replay/__Tests/StellaOps.Replay.Core.Tests/StellaOps.Replay.Core.Tests.csproj - APPLY | | 1456 | AUDIT-0486-M | TODO | Report | Guild | src/__Libraries/__Tests/StellaOps.Replay.Tests/StellaOps.Replay.Tests.csproj - MAINT | | 1457 | AUDIT-0486-T | TODO | Report | Guild | src/__Libraries/__Tests/StellaOps.Replay.Tests/StellaOps.Replay.Tests.csproj - TEST | -| 1458 | AUDIT-0486-A | TODO | Approval | Guild | src/__Libraries/__Tests/StellaOps.Replay.Tests/StellaOps.Replay.Tests.csproj - APPLY | +| 1458 | AUDIT-0486-A | DONE | Waived (test project) | Guild | src/__Libraries/__Tests/StellaOps.Replay.Tests/StellaOps.Replay.Tests.csproj - APPLY | | 1459 | AUDIT-0487-M | TODO | Report | Guild | src/Replay/StellaOps.Replay.WebService/StellaOps.Replay.WebService.csproj - MAINT | | 1460 | AUDIT-0487-T | TODO | Report | Guild | src/Replay/StellaOps.Replay.WebService/StellaOps.Replay.WebService.csproj - TEST | | 1461 | AUDIT-0487-A | TODO | Approval | Guild | src/Replay/StellaOps.Replay.WebService/StellaOps.Replay.WebService.csproj - APPLY | @@ -1486,7 +1486,7 @@ Bulk task definitions (applies to every project row below): | 1464 | AUDIT-0488-A | TODO | Approval | Guild | src/__Libraries/StellaOps.Resolver/StellaOps.Resolver.csproj - APPLY | | 1465 | AUDIT-0489-M | TODO | Report | Guild | src/__Libraries/StellaOps.Resolver.Tests/StellaOps.Resolver.Tests.csproj - MAINT | | 1466 | AUDIT-0489-T | TODO | Report | Guild | src/__Libraries/StellaOps.Resolver.Tests/StellaOps.Resolver.Tests.csproj - TEST | -| 1467 | AUDIT-0489-A | TODO | Approval | Guild | src/__Libraries/StellaOps.Resolver.Tests/StellaOps.Resolver.Tests.csproj - APPLY | +| 1467 | AUDIT-0489-A | DONE | Waived (test project) | Guild | src/__Libraries/StellaOps.Resolver.Tests/StellaOps.Resolver.Tests.csproj - APPLY | | 1468 | AUDIT-0490-M | TODO | Report | Guild | src/RiskEngine/StellaOps.RiskEngine/StellaOps.RiskEngine.Core/StellaOps.RiskEngine.Core.csproj - MAINT | | 1469 | AUDIT-0490-T | TODO | Report | Guild | src/RiskEngine/StellaOps.RiskEngine/StellaOps.RiskEngine.Core/StellaOps.RiskEngine.Core.csproj - TEST | | 1470 | AUDIT-0490-A | TODO | Approval | Guild | src/RiskEngine/StellaOps.RiskEngine/StellaOps.RiskEngine.Core/StellaOps.RiskEngine.Core.csproj - APPLY | @@ -1495,7 +1495,7 @@ Bulk task definitions (applies to every project row below): | 1473 | AUDIT-0491-A | TODO | Approval | Guild | src/RiskEngine/StellaOps.RiskEngine/StellaOps.RiskEngine.Infrastructure/StellaOps.RiskEngine.Infrastructure.csproj - APPLY | | 1474 | AUDIT-0492-M | TODO | Report | Guild | src/RiskEngine/StellaOps.RiskEngine/StellaOps.RiskEngine.Tests/StellaOps.RiskEngine.Tests.csproj - MAINT | | 1475 | AUDIT-0492-T | TODO | Report | Guild | src/RiskEngine/StellaOps.RiskEngine/StellaOps.RiskEngine.Tests/StellaOps.RiskEngine.Tests.csproj - TEST | -| 1476 | AUDIT-0492-A | TODO | Approval | Guild | src/RiskEngine/StellaOps.RiskEngine/StellaOps.RiskEngine.Tests/StellaOps.RiskEngine.Tests.csproj - APPLY | +| 1476 | AUDIT-0492-A | DONE | Waived (test project) | Guild | src/RiskEngine/StellaOps.RiskEngine/StellaOps.RiskEngine.Tests/StellaOps.RiskEngine.Tests.csproj - APPLY | | 1477 | AUDIT-0493-M | TODO | Report | Guild | src/RiskEngine/StellaOps.RiskEngine/StellaOps.RiskEngine.WebService/StellaOps.RiskEngine.WebService.csproj - MAINT | | 1478 | AUDIT-0493-T | TODO | Report | Guild | src/RiskEngine/StellaOps.RiskEngine/StellaOps.RiskEngine.WebService/StellaOps.RiskEngine.WebService.csproj - TEST | | 1479 | AUDIT-0493-A | TODO | Approval | Guild | src/RiskEngine/StellaOps.RiskEngine/StellaOps.RiskEngine.WebService/StellaOps.RiskEngine.WebService.csproj - APPLY | @@ -1510,28 +1510,28 @@ Bulk task definitions (applies to every project row below): | 1488 | AUDIT-0496-A | TODO | Approval | Guild | src/Router/__Libraries/StellaOps.Router.Common/StellaOps.Router.Common.csproj - APPLY | | 1489 | AUDIT-0497-M | TODO | Report | Guild | src/Router/__Tests/StellaOps.Router.Common.Tests/StellaOps.Router.Common.Tests.csproj - MAINT | | 1490 | AUDIT-0497-T | TODO | Report | Guild | src/Router/__Tests/StellaOps.Router.Common.Tests/StellaOps.Router.Common.Tests.csproj - TEST | -| 1491 | AUDIT-0497-A | TODO | Approval | Guild | src/Router/__Tests/StellaOps.Router.Common.Tests/StellaOps.Router.Common.Tests.csproj - APPLY | +| 1491 | AUDIT-0497-A | DONE | Waived (test project) | Guild | src/Router/__Tests/StellaOps.Router.Common.Tests/StellaOps.Router.Common.Tests.csproj - APPLY | | 1492 | AUDIT-0498-M | TODO | Report | Guild | src/Router/__Libraries/StellaOps.Router.Config/StellaOps.Router.Config.csproj - MAINT | | 1493 | AUDIT-0498-T | TODO | Report | Guild | src/Router/__Libraries/StellaOps.Router.Config/StellaOps.Router.Config.csproj - TEST | | 1494 | AUDIT-0498-A | TODO | Approval | Guild | src/Router/__Libraries/StellaOps.Router.Config/StellaOps.Router.Config.csproj - APPLY | | 1495 | AUDIT-0499-M | TODO | Report | Guild | src/Router/__Tests/StellaOps.Router.Config.Tests/StellaOps.Router.Config.Tests.csproj - MAINT | | 1496 | AUDIT-0499-T | TODO | Report | Guild | src/Router/__Tests/StellaOps.Router.Config.Tests/StellaOps.Router.Config.Tests.csproj - TEST | -| 1497 | AUDIT-0499-A | TODO | Approval | Guild | src/Router/__Tests/StellaOps.Router.Config.Tests/StellaOps.Router.Config.Tests.csproj - APPLY | +| 1497 | AUDIT-0499-A | DONE | Waived (test project) | Guild | src/Router/__Tests/StellaOps.Router.Config.Tests/StellaOps.Router.Config.Tests.csproj - APPLY | | 1498 | AUDIT-0500-M | TODO | Report | Guild | src/Router/__Libraries/StellaOps.Router.Gateway/StellaOps.Router.Gateway.csproj - MAINT | | 1499 | AUDIT-0500-T | TODO | Report | Guild | src/Router/__Libraries/StellaOps.Router.Gateway/StellaOps.Router.Gateway.csproj - TEST | | 1500 | AUDIT-0500-A | TODO | Approval | Guild | src/Router/__Libraries/StellaOps.Router.Gateway/StellaOps.Router.Gateway.csproj - APPLY | | 1501 | AUDIT-0501-M | TODO | Report | Guild | src/Router/__Tests/StellaOps.Router.Integration.Tests/StellaOps.Router.Integration.Tests.csproj - MAINT | | 1502 | AUDIT-0501-T | TODO | Report | Guild | src/Router/__Tests/StellaOps.Router.Integration.Tests/StellaOps.Router.Integration.Tests.csproj - TEST | -| 1503 | AUDIT-0501-A | TODO | Approval | Guild | src/Router/__Tests/StellaOps.Router.Integration.Tests/StellaOps.Router.Integration.Tests.csproj - APPLY | +| 1503 | AUDIT-0501-A | DONE | Waived (test project) | Guild | src/Router/__Tests/StellaOps.Router.Integration.Tests/StellaOps.Router.Integration.Tests.csproj - APPLY | | 1504 | AUDIT-0502-M | TODO | Report | Guild | src/Router/__Tests/__Libraries/StellaOps.Router.Testing/StellaOps.Router.Testing.csproj - MAINT | | 1505 | AUDIT-0502-T | TODO | Report | Guild | src/Router/__Tests/__Libraries/StellaOps.Router.Testing/StellaOps.Router.Testing.csproj - TEST | -| 1506 | AUDIT-0502-A | TODO | Approval | Guild | src/Router/__Tests/__Libraries/StellaOps.Router.Testing/StellaOps.Router.Testing.csproj - APPLY | +| 1506 | AUDIT-0502-A | DONE | Waived (test project) | Guild | src/Router/__Tests/__Libraries/StellaOps.Router.Testing/StellaOps.Router.Testing.csproj - APPLY | | 1507 | AUDIT-0503-M | TODO | Report | Guild | src/Router/__Libraries/StellaOps.Router.Transport.InMemory/StellaOps.Router.Transport.InMemory.csproj - MAINT | | 1508 | AUDIT-0503-T | TODO | Report | Guild | src/Router/__Libraries/StellaOps.Router.Transport.InMemory/StellaOps.Router.Transport.InMemory.csproj - TEST | | 1509 | AUDIT-0503-A | TODO | Approval | Guild | src/Router/__Libraries/StellaOps.Router.Transport.InMemory/StellaOps.Router.Transport.InMemory.csproj - APPLY | | 1510 | AUDIT-0504-M | TODO | Report | Guild | src/Router/__Tests/StellaOps.Router.Transport.InMemory.Tests/StellaOps.Router.Transport.InMemory.Tests.csproj - MAINT | | 1511 | AUDIT-0504-T | TODO | Report | Guild | src/Router/__Tests/StellaOps.Router.Transport.InMemory.Tests/StellaOps.Router.Transport.InMemory.Tests.csproj - TEST | -| 1512 | AUDIT-0504-A | TODO | Approval | Guild | src/Router/__Tests/StellaOps.Router.Transport.InMemory.Tests/StellaOps.Router.Transport.InMemory.Tests.csproj - APPLY | +| 1512 | AUDIT-0504-A | DONE | Waived (test project) | Guild | src/Router/__Tests/StellaOps.Router.Transport.InMemory.Tests/StellaOps.Router.Transport.InMemory.Tests.csproj - APPLY | | 1513 | AUDIT-0505-M | TODO | Report | Guild | src/Router/__Libraries/StellaOps.Router.Transport.Messaging/StellaOps.Router.Transport.Messaging.csproj - MAINT | | 1514 | AUDIT-0505-T | TODO | Report | Guild | src/Router/__Libraries/StellaOps.Router.Transport.Messaging/StellaOps.Router.Transport.Messaging.csproj - TEST | | 1515 | AUDIT-0505-A | TODO | Approval | Guild | src/Router/__Libraries/StellaOps.Router.Transport.Messaging/StellaOps.Router.Transport.Messaging.csproj - APPLY | @@ -1540,25 +1540,25 @@ Bulk task definitions (applies to every project row below): | 1518 | AUDIT-0506-A | TODO | Approval | Guild | src/Router/__Libraries/StellaOps.Router.Transport.RabbitMq/StellaOps.Router.Transport.RabbitMq.csproj - APPLY | | 1519 | AUDIT-0507-M | TODO | Report | Guild | src/Router/__Tests/StellaOps.Router.Transport.RabbitMq.Tests/StellaOps.Router.Transport.RabbitMq.Tests.csproj - MAINT | | 1520 | AUDIT-0507-T | TODO | Report | Guild | src/Router/__Tests/StellaOps.Router.Transport.RabbitMq.Tests/StellaOps.Router.Transport.RabbitMq.Tests.csproj - TEST | -| 1521 | AUDIT-0507-A | TODO | Approval | Guild | src/Router/__Tests/StellaOps.Router.Transport.RabbitMq.Tests/StellaOps.Router.Transport.RabbitMq.Tests.csproj - APPLY | +| 1521 | AUDIT-0507-A | DONE | Waived (test project) | Guild | src/Router/__Tests/StellaOps.Router.Transport.RabbitMq.Tests/StellaOps.Router.Transport.RabbitMq.Tests.csproj - APPLY | | 1522 | AUDIT-0508-M | TODO | Report | Guild | src/Router/__Libraries/StellaOps.Router.Transport.Tcp/StellaOps.Router.Transport.Tcp.csproj - MAINT | | 1523 | AUDIT-0508-T | TODO | Report | Guild | src/Router/__Libraries/StellaOps.Router.Transport.Tcp/StellaOps.Router.Transport.Tcp.csproj - TEST | | 1524 | AUDIT-0508-A | TODO | Approval | Guild | src/Router/__Libraries/StellaOps.Router.Transport.Tcp/StellaOps.Router.Transport.Tcp.csproj - APPLY | | 1525 | AUDIT-0509-M | TODO | Report | Guild | src/Router/__Tests/StellaOps.Router.Transport.Tcp.Tests/StellaOps.Router.Transport.Tcp.Tests.csproj - MAINT | | 1526 | AUDIT-0509-T | TODO | Report | Guild | src/Router/__Tests/StellaOps.Router.Transport.Tcp.Tests/StellaOps.Router.Transport.Tcp.Tests.csproj - TEST | -| 1527 | AUDIT-0509-A | TODO | Approval | Guild | src/Router/__Tests/StellaOps.Router.Transport.Tcp.Tests/StellaOps.Router.Transport.Tcp.Tests.csproj - APPLY | +| 1527 | AUDIT-0509-A | DONE | Waived (test project) | Guild | src/Router/__Tests/StellaOps.Router.Transport.Tcp.Tests/StellaOps.Router.Transport.Tcp.Tests.csproj - APPLY | | 1528 | AUDIT-0510-M | TODO | Report | Guild | src/Router/__Libraries/StellaOps.Router.Transport.Tls/StellaOps.Router.Transport.Tls.csproj - MAINT | | 1529 | AUDIT-0510-T | TODO | Report | Guild | src/Router/__Libraries/StellaOps.Router.Transport.Tls/StellaOps.Router.Transport.Tls.csproj - TEST | | 1530 | AUDIT-0510-A | TODO | Approval | Guild | src/Router/__Libraries/StellaOps.Router.Transport.Tls/StellaOps.Router.Transport.Tls.csproj - APPLY | | 1531 | AUDIT-0511-M | TODO | Report | Guild | src/Router/__Tests/StellaOps.Router.Transport.Tls.Tests/StellaOps.Router.Transport.Tls.Tests.csproj - MAINT | | 1532 | AUDIT-0511-T | TODO | Report | Guild | src/Router/__Tests/StellaOps.Router.Transport.Tls.Tests/StellaOps.Router.Transport.Tls.Tests.csproj - TEST | -| 1533 | AUDIT-0511-A | TODO | Approval | Guild | src/Router/__Tests/StellaOps.Router.Transport.Tls.Tests/StellaOps.Router.Transport.Tls.Tests.csproj - APPLY | +| 1533 | AUDIT-0511-A | DONE | Waived (test project) | Guild | src/Router/__Tests/StellaOps.Router.Transport.Tls.Tests/StellaOps.Router.Transport.Tls.Tests.csproj - APPLY | | 1534 | AUDIT-0512-M | TODO | Report | Guild | src/Router/__Libraries/StellaOps.Router.Transport.Udp/StellaOps.Router.Transport.Udp.csproj - MAINT | | 1535 | AUDIT-0512-T | TODO | Report | Guild | src/Router/__Libraries/StellaOps.Router.Transport.Udp/StellaOps.Router.Transport.Udp.csproj - TEST | | 1536 | AUDIT-0512-A | TODO | Approval | Guild | src/Router/__Libraries/StellaOps.Router.Transport.Udp/StellaOps.Router.Transport.Udp.csproj - APPLY | | 1537 | AUDIT-0513-M | TODO | Report | Guild | src/Router/__Tests/StellaOps.Router.Transport.Udp.Tests/StellaOps.Router.Transport.Udp.Tests.csproj - MAINT | | 1538 | AUDIT-0513-T | TODO | Report | Guild | src/Router/__Tests/StellaOps.Router.Transport.Udp.Tests/StellaOps.Router.Transport.Udp.Tests.csproj - TEST | -| 1539 | AUDIT-0513-A | TODO | Approval | Guild | src/Router/__Tests/StellaOps.Router.Transport.Udp.Tests/StellaOps.Router.Transport.Udp.Tests.csproj - APPLY | +| 1539 | AUDIT-0513-A | DONE | Waived (test project) | Guild | src/Router/__Tests/StellaOps.Router.Transport.Udp.Tests/StellaOps.Router.Transport.Udp.Tests.csproj - APPLY | | 1540 | AUDIT-0514-M | TODO | Report | Guild | src/SbomService/StellaOps.SbomService/StellaOps.SbomService.csproj - MAINT | | 1541 | AUDIT-0514-T | TODO | Report | Guild | src/SbomService/StellaOps.SbomService/StellaOps.SbomService.csproj - TEST | | 1542 | AUDIT-0514-A | TODO | Approval | Guild | src/SbomService/StellaOps.SbomService/StellaOps.SbomService.csproj - APPLY | @@ -1567,16 +1567,16 @@ Bulk task definitions (applies to every project row below): | 1545 | AUDIT-0515-A | TODO | Approval | Guild | src/SbomService/__Libraries/StellaOps.SbomService.Persistence/StellaOps.SbomService.Persistence.csproj - APPLY | | 1546 | AUDIT-0516-M | TODO | Report | Guild | src/SbomService/__Tests/StellaOps.SbomService.Persistence.Tests/StellaOps.SbomService.Persistence.Tests.csproj - MAINT | | 1547 | AUDIT-0516-T | TODO | Report | Guild | src/SbomService/__Tests/StellaOps.SbomService.Persistence.Tests/StellaOps.SbomService.Persistence.Tests.csproj - TEST | -| 1548 | AUDIT-0516-A | TODO | Approval | Guild | src/SbomService/__Tests/StellaOps.SbomService.Persistence.Tests/StellaOps.SbomService.Persistence.Tests.csproj - APPLY | +| 1548 | AUDIT-0516-A | DONE | Waived (test project) | Guild | src/SbomService/__Tests/StellaOps.SbomService.Persistence.Tests/StellaOps.SbomService.Persistence.Tests.csproj - APPLY | | 1549 | AUDIT-0517-M | TODO | Report | Guild | src/SbomService/StellaOps.SbomService.Tests/StellaOps.SbomService.Tests.csproj - MAINT | | 1550 | AUDIT-0517-T | TODO | Report | Guild | src/SbomService/StellaOps.SbomService.Tests/StellaOps.SbomService.Tests.csproj - TEST | -| 1551 | AUDIT-0517-A | TODO | Approval | Guild | src/SbomService/StellaOps.SbomService.Tests/StellaOps.SbomService.Tests.csproj - APPLY | +| 1551 | AUDIT-0517-A | DONE | Waived (test project) | Guild | src/SbomService/StellaOps.SbomService.Tests/StellaOps.SbomService.Tests.csproj - APPLY | | 1552 | AUDIT-0518-M | TODO | Report | Guild | src/Scanner/__Libraries/StellaOps.Scanner.Advisory/StellaOps.Scanner.Advisory.csproj - MAINT | | 1553 | AUDIT-0518-T | TODO | Report | Guild | src/Scanner/__Libraries/StellaOps.Scanner.Advisory/StellaOps.Scanner.Advisory.csproj - TEST | | 1554 | AUDIT-0518-A | TODO | Approval | Guild | src/Scanner/__Libraries/StellaOps.Scanner.Advisory/StellaOps.Scanner.Advisory.csproj - APPLY | | 1555 | AUDIT-0519-M | TODO | Report | Guild | src/Scanner/__Tests/StellaOps.Scanner.Advisory.Tests/StellaOps.Scanner.Advisory.Tests.csproj - MAINT | | 1556 | AUDIT-0519-T | TODO | Report | Guild | src/Scanner/__Tests/StellaOps.Scanner.Advisory.Tests/StellaOps.Scanner.Advisory.Tests.csproj - TEST | -| 1557 | AUDIT-0519-A | TODO | Approval | Guild | src/Scanner/__Tests/StellaOps.Scanner.Advisory.Tests/StellaOps.Scanner.Advisory.Tests.csproj - APPLY | +| 1557 | AUDIT-0519-A | DONE | Waived (test project) | Guild | src/Scanner/__Tests/StellaOps.Scanner.Advisory.Tests/StellaOps.Scanner.Advisory.Tests.csproj - APPLY | | 1558 | AUDIT-0520-M | TODO | Report | Guild | src/Scanner/__Libraries/StellaOps.Scanner.Analyzers.Lang/StellaOps.Scanner.Analyzers.Lang.csproj - MAINT | | 1559 | AUDIT-0520-T | TODO | Report | Guild | src/Scanner/__Libraries/StellaOps.Scanner.Analyzers.Lang/StellaOps.Scanner.Analyzers.Lang.csproj - TEST | | 1560 | AUDIT-0520-A | TODO | Approval | Guild | src/Scanner/__Libraries/StellaOps.Scanner.Analyzers.Lang/StellaOps.Scanner.Analyzers.Lang.csproj - APPLY | @@ -1585,73 +1585,73 @@ Bulk task definitions (applies to every project row below): | 1563 | AUDIT-0521-A | TODO | Approval | Guild | src/Scanner/__Libraries/StellaOps.Scanner.Analyzers.Lang.Bun/StellaOps.Scanner.Analyzers.Lang.Bun.csproj - APPLY | | 1564 | AUDIT-0522-M | TODO | Report | Guild | src/Scanner/__Tests/StellaOps.Scanner.Analyzers.Lang.Bun.Tests/StellaOps.Scanner.Analyzers.Lang.Bun.Tests.csproj - MAINT | | 1565 | AUDIT-0522-T | TODO | Report | Guild | src/Scanner/__Tests/StellaOps.Scanner.Analyzers.Lang.Bun.Tests/StellaOps.Scanner.Analyzers.Lang.Bun.Tests.csproj - TEST | -| 1566 | AUDIT-0522-A | TODO | Approval | Guild | src/Scanner/__Tests/StellaOps.Scanner.Analyzers.Lang.Bun.Tests/StellaOps.Scanner.Analyzers.Lang.Bun.Tests.csproj - APPLY | +| 1566 | AUDIT-0522-A | DONE | Waived (test project) | Guild | src/Scanner/__Tests/StellaOps.Scanner.Analyzers.Lang.Bun.Tests/StellaOps.Scanner.Analyzers.Lang.Bun.Tests.csproj - APPLY | | 1567 | AUDIT-0523-M | TODO | Report | Guild | src/Scanner/__Libraries/StellaOps.Scanner.Analyzers.Lang.Deno/StellaOps.Scanner.Analyzers.Lang.Deno.csproj - MAINT | | 1568 | AUDIT-0523-T | TODO | Report | Guild | src/Scanner/__Libraries/StellaOps.Scanner.Analyzers.Lang.Deno/StellaOps.Scanner.Analyzers.Lang.Deno.csproj - TEST | | 1569 | AUDIT-0523-A | TODO | Approval | Guild | src/Scanner/__Libraries/StellaOps.Scanner.Analyzers.Lang.Deno/StellaOps.Scanner.Analyzers.Lang.Deno.csproj - APPLY | | 1570 | AUDIT-0524-M | TODO | Report | Guild | src/Scanner/__Benchmarks/StellaOps.Scanner.Analyzers.Lang.Deno.Benchmarks/StellaOps.Scanner.Analyzers.Lang.Deno.Benchmarks.csproj - MAINT | | 1571 | AUDIT-0524-T | TODO | Report | Guild | src/Scanner/__Benchmarks/StellaOps.Scanner.Analyzers.Lang.Deno.Benchmarks/StellaOps.Scanner.Analyzers.Lang.Deno.Benchmarks.csproj - TEST | -| 1572 | AUDIT-0524-A | TODO | Approval | Guild | src/Scanner/__Benchmarks/StellaOps.Scanner.Analyzers.Lang.Deno.Benchmarks/StellaOps.Scanner.Analyzers.Lang.Deno.Benchmarks.csproj - APPLY | +| 1572 | AUDIT-0524-A | DONE | Waived (benchmark/sample project) | Guild | src/Scanner/__Benchmarks/StellaOps.Scanner.Analyzers.Lang.Deno.Benchmarks/StellaOps.Scanner.Analyzers.Lang.Deno.Benchmarks.csproj - APPLY | | 1573 | AUDIT-0525-M | TODO | Report | Guild | src/Scanner/__Tests/StellaOps.Scanner.Analyzers.Lang.Deno.Tests/StellaOps.Scanner.Analyzers.Lang.Deno.Tests.csproj - MAINT | | 1574 | AUDIT-0525-T | TODO | Report | Guild | src/Scanner/__Tests/StellaOps.Scanner.Analyzers.Lang.Deno.Tests/StellaOps.Scanner.Analyzers.Lang.Deno.Tests.csproj - TEST | -| 1575 | AUDIT-0525-A | TODO | Approval | Guild | src/Scanner/__Tests/StellaOps.Scanner.Analyzers.Lang.Deno.Tests/StellaOps.Scanner.Analyzers.Lang.Deno.Tests.csproj - APPLY | +| 1575 | AUDIT-0525-A | DONE | Waived (test project) | Guild | src/Scanner/__Tests/StellaOps.Scanner.Analyzers.Lang.Deno.Tests/StellaOps.Scanner.Analyzers.Lang.Deno.Tests.csproj - APPLY | | 1576 | AUDIT-0526-M | TODO | Report | Guild | src/Scanner/__Libraries/StellaOps.Scanner.Analyzers.Lang.DotNet/StellaOps.Scanner.Analyzers.Lang.DotNet.csproj - MAINT | | 1577 | AUDIT-0526-T | TODO | Report | Guild | src/Scanner/__Libraries/StellaOps.Scanner.Analyzers.Lang.DotNet/StellaOps.Scanner.Analyzers.Lang.DotNet.csproj - TEST | | 1578 | AUDIT-0526-A | TODO | Approval | Guild | src/Scanner/__Libraries/StellaOps.Scanner.Analyzers.Lang.DotNet/StellaOps.Scanner.Analyzers.Lang.DotNet.csproj - APPLY | | 1579 | AUDIT-0527-M | TODO | Report | Guild | src/Scanner/__Tests/StellaOps.Scanner.Analyzers.Lang.DotNet.Tests/StellaOps.Scanner.Analyzers.Lang.DotNet.Tests.csproj - MAINT | | 1580 | AUDIT-0527-T | TODO | Report | Guild | src/Scanner/__Tests/StellaOps.Scanner.Analyzers.Lang.DotNet.Tests/StellaOps.Scanner.Analyzers.Lang.DotNet.Tests.csproj - TEST | -| 1581 | AUDIT-0527-A | TODO | Approval | Guild | src/Scanner/__Tests/StellaOps.Scanner.Analyzers.Lang.DotNet.Tests/StellaOps.Scanner.Analyzers.Lang.DotNet.Tests.csproj - APPLY | +| 1581 | AUDIT-0527-A | DONE | Waived (test project) | Guild | src/Scanner/__Tests/StellaOps.Scanner.Analyzers.Lang.DotNet.Tests/StellaOps.Scanner.Analyzers.Lang.DotNet.Tests.csproj - APPLY | | 1582 | AUDIT-0528-M | TODO | Report | Guild | src/Scanner/__Libraries/StellaOps.Scanner.Analyzers.Lang.Go/StellaOps.Scanner.Analyzers.Lang.Go.csproj - MAINT | | 1583 | AUDIT-0528-T | TODO | Report | Guild | src/Scanner/__Libraries/StellaOps.Scanner.Analyzers.Lang.Go/StellaOps.Scanner.Analyzers.Lang.Go.csproj - TEST | | 1584 | AUDIT-0528-A | TODO | Approval | Guild | src/Scanner/__Libraries/StellaOps.Scanner.Analyzers.Lang.Go/StellaOps.Scanner.Analyzers.Lang.Go.csproj - APPLY | | 1585 | AUDIT-0529-M | TODO | Report | Guild | src/Scanner/__Tests/StellaOps.Scanner.Analyzers.Lang.Go.Tests/StellaOps.Scanner.Analyzers.Lang.Go.Tests.csproj - MAINT | | 1586 | AUDIT-0529-T | TODO | Report | Guild | src/Scanner/__Tests/StellaOps.Scanner.Analyzers.Lang.Go.Tests/StellaOps.Scanner.Analyzers.Lang.Go.Tests.csproj - TEST | -| 1587 | AUDIT-0529-A | TODO | Approval | Guild | src/Scanner/__Tests/StellaOps.Scanner.Analyzers.Lang.Go.Tests/StellaOps.Scanner.Analyzers.Lang.Go.Tests.csproj - APPLY | +| 1587 | AUDIT-0529-A | DONE | Waived (test project) | Guild | src/Scanner/__Tests/StellaOps.Scanner.Analyzers.Lang.Go.Tests/StellaOps.Scanner.Analyzers.Lang.Go.Tests.csproj - APPLY | | 1588 | AUDIT-0530-M | TODO | Report | Guild | src/Scanner/__Libraries/StellaOps.Scanner.Analyzers.Lang.Java/StellaOps.Scanner.Analyzers.Lang.Java.csproj - MAINT | | 1589 | AUDIT-0530-T | TODO | Report | Guild | src/Scanner/__Libraries/StellaOps.Scanner.Analyzers.Lang.Java/StellaOps.Scanner.Analyzers.Lang.Java.csproj - TEST | | 1590 | AUDIT-0530-A | TODO | Approval | Guild | src/Scanner/__Libraries/StellaOps.Scanner.Analyzers.Lang.Java/StellaOps.Scanner.Analyzers.Lang.Java.csproj - APPLY | | 1591 | AUDIT-0531-M | TODO | Report | Guild | src/Scanner/__Tests/StellaOps.Scanner.Analyzers.Lang.Java.Tests/StellaOps.Scanner.Analyzers.Lang.Java.Tests.csproj - MAINT | | 1592 | AUDIT-0531-T | TODO | Report | Guild | src/Scanner/__Tests/StellaOps.Scanner.Analyzers.Lang.Java.Tests/StellaOps.Scanner.Analyzers.Lang.Java.Tests.csproj - TEST | -| 1593 | AUDIT-0531-A | TODO | Approval | Guild | src/Scanner/__Tests/StellaOps.Scanner.Analyzers.Lang.Java.Tests/StellaOps.Scanner.Analyzers.Lang.Java.Tests.csproj - APPLY | +| 1593 | AUDIT-0531-A | DONE | Waived (test project) | Guild | src/Scanner/__Tests/StellaOps.Scanner.Analyzers.Lang.Java.Tests/StellaOps.Scanner.Analyzers.Lang.Java.Tests.csproj - APPLY | | 1594 | AUDIT-0532-M | TODO | Report | Guild | src/Scanner/__Libraries/StellaOps.Scanner.Analyzers.Lang.Node/StellaOps.Scanner.Analyzers.Lang.Node.csproj - MAINT | | 1595 | AUDIT-0532-T | TODO | Report | Guild | src/Scanner/__Libraries/StellaOps.Scanner.Analyzers.Lang.Node/StellaOps.Scanner.Analyzers.Lang.Node.csproj - TEST | | 1596 | AUDIT-0532-A | TODO | Approval | Guild | src/Scanner/__Libraries/StellaOps.Scanner.Analyzers.Lang.Node/StellaOps.Scanner.Analyzers.Lang.Node.csproj - APPLY | | 1597 | AUDIT-0533-M | TODO | Report | Guild | src/Scanner/__Tests/StellaOps.Scanner.Analyzers.Lang.Node.SmokeTests/StellaOps.Scanner.Analyzers.Lang.Node.SmokeTests.csproj - MAINT | | 1598 | AUDIT-0533-T | TODO | Report | Guild | src/Scanner/__Tests/StellaOps.Scanner.Analyzers.Lang.Node.SmokeTests/StellaOps.Scanner.Analyzers.Lang.Node.SmokeTests.csproj - TEST | -| 1599 | AUDIT-0533-A | TODO | Approval | Guild | src/Scanner/__Tests/StellaOps.Scanner.Analyzers.Lang.Node.SmokeTests/StellaOps.Scanner.Analyzers.Lang.Node.SmokeTests.csproj - APPLY | +| 1599 | AUDIT-0533-A | DONE | Waived (test project) | Guild | src/Scanner/__Tests/StellaOps.Scanner.Analyzers.Lang.Node.SmokeTests/StellaOps.Scanner.Analyzers.Lang.Node.SmokeTests.csproj - APPLY | | 1600 | AUDIT-0534-M | TODO | Report | Guild | src/Scanner/__Tests/StellaOps.Scanner.Analyzers.Lang.Node.Tests/StellaOps.Scanner.Analyzers.Lang.Node.Tests.csproj - MAINT | | 1601 | AUDIT-0534-T | TODO | Report | Guild | src/Scanner/__Tests/StellaOps.Scanner.Analyzers.Lang.Node.Tests/StellaOps.Scanner.Analyzers.Lang.Node.Tests.csproj - TEST | -| 1602 | AUDIT-0534-A | TODO | Approval | Guild | src/Scanner/__Tests/StellaOps.Scanner.Analyzers.Lang.Node.Tests/StellaOps.Scanner.Analyzers.Lang.Node.Tests.csproj - APPLY | +| 1602 | AUDIT-0534-A | DONE | Waived (test project) | Guild | src/Scanner/__Tests/StellaOps.Scanner.Analyzers.Lang.Node.Tests/StellaOps.Scanner.Analyzers.Lang.Node.Tests.csproj - APPLY | | 1603 | AUDIT-0535-M | TODO | Report | Guild | src/Scanner/__Libraries/StellaOps.Scanner.Analyzers.Lang.Php/StellaOps.Scanner.Analyzers.Lang.Php.csproj - MAINT | | 1604 | AUDIT-0535-T | TODO | Report | Guild | src/Scanner/__Libraries/StellaOps.Scanner.Analyzers.Lang.Php/StellaOps.Scanner.Analyzers.Lang.Php.csproj - TEST | | 1605 | AUDIT-0535-A | TODO | Approval | Guild | src/Scanner/__Libraries/StellaOps.Scanner.Analyzers.Lang.Php/StellaOps.Scanner.Analyzers.Lang.Php.csproj - APPLY | | 1606 | AUDIT-0536-M | TODO | Report | Guild | src/Scanner/__Benchmarks/StellaOps.Scanner.Analyzers.Lang.Php.Benchmarks/StellaOps.Scanner.Analyzers.Lang.Php.Benchmarks.csproj - MAINT | | 1607 | AUDIT-0536-T | TODO | Report | Guild | src/Scanner/__Benchmarks/StellaOps.Scanner.Analyzers.Lang.Php.Benchmarks/StellaOps.Scanner.Analyzers.Lang.Php.Benchmarks.csproj - TEST | -| 1608 | AUDIT-0536-A | TODO | Approval | Guild | src/Scanner/__Benchmarks/StellaOps.Scanner.Analyzers.Lang.Php.Benchmarks/StellaOps.Scanner.Analyzers.Lang.Php.Benchmarks.csproj - APPLY | +| 1608 | AUDIT-0536-A | DONE | Waived (benchmark/sample project) | Guild | src/Scanner/__Benchmarks/StellaOps.Scanner.Analyzers.Lang.Php.Benchmarks/StellaOps.Scanner.Analyzers.Lang.Php.Benchmarks.csproj - APPLY | | 1609 | AUDIT-0537-M | TODO | Report | Guild | src/Scanner/__Tests/StellaOps.Scanner.Analyzers.Lang.Php.Tests/StellaOps.Scanner.Analyzers.Lang.Php.Tests.csproj - MAINT | | 1610 | AUDIT-0537-T | TODO | Report | Guild | src/Scanner/__Tests/StellaOps.Scanner.Analyzers.Lang.Php.Tests/StellaOps.Scanner.Analyzers.Lang.Php.Tests.csproj - TEST | -| 1611 | AUDIT-0537-A | TODO | Approval | Guild | src/Scanner/__Tests/StellaOps.Scanner.Analyzers.Lang.Php.Tests/StellaOps.Scanner.Analyzers.Lang.Php.Tests.csproj - APPLY | +| 1611 | AUDIT-0537-A | DONE | Waived (test project) | Guild | src/Scanner/__Tests/StellaOps.Scanner.Analyzers.Lang.Php.Tests/StellaOps.Scanner.Analyzers.Lang.Php.Tests.csproj - APPLY | | 1612 | AUDIT-0538-M | TODO | Report | Guild | src/Scanner/__Libraries/StellaOps.Scanner.Analyzers.Lang.Python/StellaOps.Scanner.Analyzers.Lang.Python.csproj - MAINT | | 1613 | AUDIT-0538-T | TODO | Report | Guild | src/Scanner/__Libraries/StellaOps.Scanner.Analyzers.Lang.Python/StellaOps.Scanner.Analyzers.Lang.Python.csproj - TEST | | 1614 | AUDIT-0538-A | TODO | Approval | Guild | src/Scanner/__Libraries/StellaOps.Scanner.Analyzers.Lang.Python/StellaOps.Scanner.Analyzers.Lang.Python.csproj - APPLY | | 1615 | AUDIT-0539-M | TODO | Report | Guild | src/Scanner/__Tests/StellaOps.Scanner.Analyzers.Lang.Python.Tests/StellaOps.Scanner.Analyzers.Lang.Python.Tests.csproj - MAINT | | 1616 | AUDIT-0539-T | TODO | Report | Guild | src/Scanner/__Tests/StellaOps.Scanner.Analyzers.Lang.Python.Tests/StellaOps.Scanner.Analyzers.Lang.Python.Tests.csproj - TEST | -| 1617 | AUDIT-0539-A | TODO | Approval | Guild | src/Scanner/__Tests/StellaOps.Scanner.Analyzers.Lang.Python.Tests/StellaOps.Scanner.Analyzers.Lang.Python.Tests.csproj - APPLY | +| 1617 | AUDIT-0539-A | DONE | Waived (test project) | Guild | src/Scanner/__Tests/StellaOps.Scanner.Analyzers.Lang.Python.Tests/StellaOps.Scanner.Analyzers.Lang.Python.Tests.csproj - APPLY | | 1618 | AUDIT-0540-M | TODO | Report | Guild | src/Scanner/__Libraries/StellaOps.Scanner.Analyzers.Lang.Ruby/StellaOps.Scanner.Analyzers.Lang.Ruby.csproj - MAINT | | 1619 | AUDIT-0540-T | TODO | Report | Guild | src/Scanner/__Libraries/StellaOps.Scanner.Analyzers.Lang.Ruby/StellaOps.Scanner.Analyzers.Lang.Ruby.csproj - TEST | | 1620 | AUDIT-0540-A | TODO | Approval | Guild | src/Scanner/__Libraries/StellaOps.Scanner.Analyzers.Lang.Ruby/StellaOps.Scanner.Analyzers.Lang.Ruby.csproj - APPLY | | 1621 | AUDIT-0541-M | TODO | Report | Guild | src/Scanner/__Tests/StellaOps.Scanner.Analyzers.Lang.Ruby.Tests/StellaOps.Scanner.Analyzers.Lang.Ruby.Tests.csproj - MAINT | | 1622 | AUDIT-0541-T | TODO | Report | Guild | src/Scanner/__Tests/StellaOps.Scanner.Analyzers.Lang.Ruby.Tests/StellaOps.Scanner.Analyzers.Lang.Ruby.Tests.csproj - TEST | -| 1623 | AUDIT-0541-A | TODO | Approval | Guild | src/Scanner/__Tests/StellaOps.Scanner.Analyzers.Lang.Ruby.Tests/StellaOps.Scanner.Analyzers.Lang.Ruby.Tests.csproj - APPLY | +| 1623 | AUDIT-0541-A | DONE | Waived (test project) | Guild | src/Scanner/__Tests/StellaOps.Scanner.Analyzers.Lang.Ruby.Tests/StellaOps.Scanner.Analyzers.Lang.Ruby.Tests.csproj - APPLY | | 1624 | AUDIT-0542-M | TODO | Report | Guild | src/Scanner/__Libraries/StellaOps.Scanner.Analyzers.Lang.Rust/StellaOps.Scanner.Analyzers.Lang.Rust.csproj - MAINT | | 1625 | AUDIT-0542-T | TODO | Report | Guild | src/Scanner/__Libraries/StellaOps.Scanner.Analyzers.Lang.Rust/StellaOps.Scanner.Analyzers.Lang.Rust.csproj - TEST | | 1626 | AUDIT-0542-A | TODO | Approval | Guild | src/Scanner/__Libraries/StellaOps.Scanner.Analyzers.Lang.Rust/StellaOps.Scanner.Analyzers.Lang.Rust.csproj - APPLY | | 1627 | AUDIT-0543-M | TODO | Report | Guild | src/Scanner/__Benchmarks/StellaOps.Scanner.Analyzers.Lang.Rust.Benchmarks/StellaOps.Scanner.Analyzers.Lang.Rust.Benchmarks.csproj - MAINT | | 1628 | AUDIT-0543-T | TODO | Report | Guild | src/Scanner/__Benchmarks/StellaOps.Scanner.Analyzers.Lang.Rust.Benchmarks/StellaOps.Scanner.Analyzers.Lang.Rust.Benchmarks.csproj - TEST | -| 1629 | AUDIT-0543-A | TODO | Approval | Guild | src/Scanner/__Benchmarks/StellaOps.Scanner.Analyzers.Lang.Rust.Benchmarks/StellaOps.Scanner.Analyzers.Lang.Rust.Benchmarks.csproj - APPLY | +| 1629 | AUDIT-0543-A | DONE | Waived (benchmark/sample project) | Guild | src/Scanner/__Benchmarks/StellaOps.Scanner.Analyzers.Lang.Rust.Benchmarks/StellaOps.Scanner.Analyzers.Lang.Rust.Benchmarks.csproj - APPLY | | 1630 | AUDIT-0544-M | TODO | Report | Guild | src/Scanner/__Tests/StellaOps.Scanner.Analyzers.Lang.Tests/StellaOps.Scanner.Analyzers.Lang.Tests.csproj - MAINT | | 1631 | AUDIT-0544-T | TODO | Report | Guild | src/Scanner/__Tests/StellaOps.Scanner.Analyzers.Lang.Tests/StellaOps.Scanner.Analyzers.Lang.Tests.csproj - TEST | -| 1632 | AUDIT-0544-A | TODO | Approval | Guild | src/Scanner/__Tests/StellaOps.Scanner.Analyzers.Lang.Tests/StellaOps.Scanner.Analyzers.Lang.Tests.csproj - APPLY | +| 1632 | AUDIT-0544-A | DONE | Waived (test project) | Guild | src/Scanner/__Tests/StellaOps.Scanner.Analyzers.Lang.Tests/StellaOps.Scanner.Analyzers.Lang.Tests.csproj - APPLY | | 1633 | AUDIT-0545-M | TODO | Report | Guild | src/Scanner/__Libraries/StellaOps.Scanner.Analyzers.Native/StellaOps.Scanner.Analyzers.Native.csproj - MAINT | | 1634 | AUDIT-0545-T | TODO | Report | Guild | src/Scanner/__Libraries/StellaOps.Scanner.Analyzers.Native/StellaOps.Scanner.Analyzers.Native.csproj - TEST | | 1635 | AUDIT-0545-A | TODO | Approval | Guild | src/Scanner/__Libraries/StellaOps.Scanner.Analyzers.Native/StellaOps.Scanner.Analyzers.Native.csproj - APPLY | @@ -1660,7 +1660,7 @@ Bulk task definitions (applies to every project row below): | 1638 | AUDIT-0546-A | TODO | Approval | Guild | src/Scanner/StellaOps.Scanner.Analyzers.Native/StellaOps.Scanner.Analyzers.Native.csproj - APPLY | | 1639 | AUDIT-0547-M | TODO | Report | Guild | src/Scanner/__Tests/StellaOps.Scanner.Analyzers.Native.Tests/StellaOps.Scanner.Analyzers.Native.Tests.csproj - MAINT | | 1640 | AUDIT-0547-T | TODO | Report | Guild | src/Scanner/__Tests/StellaOps.Scanner.Analyzers.Native.Tests/StellaOps.Scanner.Analyzers.Native.Tests.csproj - TEST | -| 1641 | AUDIT-0547-A | TODO | Approval | Guild | src/Scanner/__Tests/StellaOps.Scanner.Analyzers.Native.Tests/StellaOps.Scanner.Analyzers.Native.Tests.csproj - APPLY | +| 1641 | AUDIT-0547-A | DONE | Waived (test project) | Guild | src/Scanner/__Tests/StellaOps.Scanner.Analyzers.Native.Tests/StellaOps.Scanner.Analyzers.Native.Tests.csproj - APPLY | | 1642 | AUDIT-0548-M | TODO | Report | Guild | src/Scanner/__Libraries/StellaOps.Scanner.Analyzers.OS/StellaOps.Scanner.Analyzers.OS.csproj - MAINT | | 1643 | AUDIT-0548-T | TODO | Report | Guild | src/Scanner/__Libraries/StellaOps.Scanner.Analyzers.OS/StellaOps.Scanner.Analyzers.OS.csproj - TEST | | 1644 | AUDIT-0548-A | TODO | Approval | Guild | src/Scanner/__Libraries/StellaOps.Scanner.Analyzers.OS/StellaOps.Scanner.Analyzers.OS.csproj - APPLY | @@ -1675,106 +1675,106 @@ Bulk task definitions (applies to every project row below): | 1653 | AUDIT-0551-A | TODO | Approval | Guild | src/Scanner/__Libraries/StellaOps.Scanner.Analyzers.OS.Homebrew/StellaOps.Scanner.Analyzers.OS.Homebrew.csproj - APPLY | | 1654 | AUDIT-0552-M | TODO | Report | Guild | src/Scanner/__Tests/StellaOps.Scanner.Analyzers.OS.Homebrew.Tests/StellaOps.Scanner.Analyzers.OS.Homebrew.Tests.csproj - MAINT | | 1655 | AUDIT-0552-T | TODO | Report | Guild | src/Scanner/__Tests/StellaOps.Scanner.Analyzers.OS.Homebrew.Tests/StellaOps.Scanner.Analyzers.OS.Homebrew.Tests.csproj - TEST | -| 1656 | AUDIT-0552-A | TODO | Approval | Guild | src/Scanner/__Tests/StellaOps.Scanner.Analyzers.OS.Homebrew.Tests/StellaOps.Scanner.Analyzers.OS.Homebrew.Tests.csproj - APPLY | +| 1656 | AUDIT-0552-A | DONE | Waived (test project) | Guild | src/Scanner/__Tests/StellaOps.Scanner.Analyzers.OS.Homebrew.Tests/StellaOps.Scanner.Analyzers.OS.Homebrew.Tests.csproj - APPLY | | 1657 | AUDIT-0553-M | TODO | Report | Guild | src/Scanner/__Libraries/StellaOps.Scanner.Analyzers.OS.MacOsBundle/StellaOps.Scanner.Analyzers.OS.MacOsBundle.csproj - MAINT | | 1658 | AUDIT-0553-T | TODO | Report | Guild | src/Scanner/__Libraries/StellaOps.Scanner.Analyzers.OS.MacOsBundle/StellaOps.Scanner.Analyzers.OS.MacOsBundle.csproj - TEST | | 1659 | AUDIT-0553-A | TODO | Approval | Guild | src/Scanner/__Libraries/StellaOps.Scanner.Analyzers.OS.MacOsBundle/StellaOps.Scanner.Analyzers.OS.MacOsBundle.csproj - APPLY | | 1660 | AUDIT-0554-M | TODO | Report | Guild | src/Scanner/__Tests/StellaOps.Scanner.Analyzers.OS.MacOsBundle.Tests/StellaOps.Scanner.Analyzers.OS.MacOsBundle.Tests.csproj - MAINT | | 1661 | AUDIT-0554-T | TODO | Report | Guild | src/Scanner/__Tests/StellaOps.Scanner.Analyzers.OS.MacOsBundle.Tests/StellaOps.Scanner.Analyzers.OS.MacOsBundle.Tests.csproj - TEST | -| 1662 | AUDIT-0554-A | TODO | Approval | Guild | src/Scanner/__Tests/StellaOps.Scanner.Analyzers.OS.MacOsBundle.Tests/StellaOps.Scanner.Analyzers.OS.MacOsBundle.Tests.csproj - APPLY | +| 1662 | AUDIT-0554-A | DONE | Waived (test project) | Guild | src/Scanner/__Tests/StellaOps.Scanner.Analyzers.OS.MacOsBundle.Tests/StellaOps.Scanner.Analyzers.OS.MacOsBundle.Tests.csproj - APPLY | | 1663 | AUDIT-0555-M | TODO | Report | Guild | src/Scanner/__Libraries/StellaOps.Scanner.Analyzers.OS.Pkgutil/StellaOps.Scanner.Analyzers.OS.Pkgutil.csproj - MAINT | | 1664 | AUDIT-0555-T | TODO | Report | Guild | src/Scanner/__Libraries/StellaOps.Scanner.Analyzers.OS.Pkgutil/StellaOps.Scanner.Analyzers.OS.Pkgutil.csproj - TEST | | 1665 | AUDIT-0555-A | TODO | Approval | Guild | src/Scanner/__Libraries/StellaOps.Scanner.Analyzers.OS.Pkgutil/StellaOps.Scanner.Analyzers.OS.Pkgutil.csproj - APPLY | | 1666 | AUDIT-0556-M | TODO | Report | Guild | src/Scanner/__Tests/StellaOps.Scanner.Analyzers.OS.Pkgutil.Tests/StellaOps.Scanner.Analyzers.OS.Pkgutil.Tests.csproj - MAINT | | 1667 | AUDIT-0556-T | TODO | Report | Guild | src/Scanner/__Tests/StellaOps.Scanner.Analyzers.OS.Pkgutil.Tests/StellaOps.Scanner.Analyzers.OS.Pkgutil.Tests.csproj - TEST | -| 1668 | AUDIT-0556-A | TODO | Approval | Guild | src/Scanner/__Tests/StellaOps.Scanner.Analyzers.OS.Pkgutil.Tests/StellaOps.Scanner.Analyzers.OS.Pkgutil.Tests.csproj - APPLY | +| 1668 | AUDIT-0556-A | DONE | Waived (test project) | Guild | src/Scanner/__Tests/StellaOps.Scanner.Analyzers.OS.Pkgutil.Tests/StellaOps.Scanner.Analyzers.OS.Pkgutil.Tests.csproj - APPLY | | 1669 | AUDIT-0557-M | TODO | Report | Guild | src/Scanner/__Libraries/StellaOps.Scanner.Analyzers.OS.Rpm/StellaOps.Scanner.Analyzers.OS.Rpm.csproj - MAINT | | 1670 | AUDIT-0557-T | TODO | Report | Guild | src/Scanner/__Libraries/StellaOps.Scanner.Analyzers.OS.Rpm/StellaOps.Scanner.Analyzers.OS.Rpm.csproj - TEST | | 1671 | AUDIT-0557-A | TODO | Approval | Guild | src/Scanner/__Libraries/StellaOps.Scanner.Analyzers.OS.Rpm/StellaOps.Scanner.Analyzers.OS.Rpm.csproj - APPLY | | 1672 | AUDIT-0558-M | TODO | Report | Guild | src/Scanner/__Tests/StellaOps.Scanner.Analyzers.OS.Tests/StellaOps.Scanner.Analyzers.OS.Tests.csproj - MAINT | | 1673 | AUDIT-0558-T | TODO | Report | Guild | src/Scanner/__Tests/StellaOps.Scanner.Analyzers.OS.Tests/StellaOps.Scanner.Analyzers.OS.Tests.csproj - TEST | -| 1674 | AUDIT-0558-A | TODO | Approval | Guild | src/Scanner/__Tests/StellaOps.Scanner.Analyzers.OS.Tests/StellaOps.Scanner.Analyzers.OS.Tests.csproj - APPLY | +| 1674 | AUDIT-0558-A | DONE | Waived (test project) | Guild | src/Scanner/__Tests/StellaOps.Scanner.Analyzers.OS.Tests/StellaOps.Scanner.Analyzers.OS.Tests.csproj - APPLY | | 1675 | AUDIT-0559-M | TODO | Report | Guild | src/Scanner/__Libraries/StellaOps.Scanner.Analyzers.OS.Windows.Chocolatey/StellaOps.Scanner.Analyzers.OS.Windows.Chocolatey.csproj - MAINT | | 1676 | AUDIT-0559-T | TODO | Report | Guild | src/Scanner/__Libraries/StellaOps.Scanner.Analyzers.OS.Windows.Chocolatey/StellaOps.Scanner.Analyzers.OS.Windows.Chocolatey.csproj - TEST | | 1677 | AUDIT-0559-A | TODO | Approval | Guild | src/Scanner/__Libraries/StellaOps.Scanner.Analyzers.OS.Windows.Chocolatey/StellaOps.Scanner.Analyzers.OS.Windows.Chocolatey.csproj - APPLY | | 1678 | AUDIT-0560-M | TODO | Report | Guild | src/Scanner/__Tests/StellaOps.Scanner.Analyzers.OS.Windows.Chocolatey.Tests/StellaOps.Scanner.Analyzers.OS.Windows.Chocolatey.Tests.csproj - MAINT | | 1679 | AUDIT-0560-T | TODO | Report | Guild | src/Scanner/__Tests/StellaOps.Scanner.Analyzers.OS.Windows.Chocolatey.Tests/StellaOps.Scanner.Analyzers.OS.Windows.Chocolatey.Tests.csproj - TEST | -| 1680 | AUDIT-0560-A | TODO | Approval | Guild | src/Scanner/__Tests/StellaOps.Scanner.Analyzers.OS.Windows.Chocolatey.Tests/StellaOps.Scanner.Analyzers.OS.Windows.Chocolatey.Tests.csproj - APPLY | +| 1680 | AUDIT-0560-A | DONE | Waived (test project) | Guild | src/Scanner/__Tests/StellaOps.Scanner.Analyzers.OS.Windows.Chocolatey.Tests/StellaOps.Scanner.Analyzers.OS.Windows.Chocolatey.Tests.csproj - APPLY | | 1681 | AUDIT-0561-M | TODO | Report | Guild | src/Scanner/__Libraries/StellaOps.Scanner.Analyzers.OS.Windows.Msi/StellaOps.Scanner.Analyzers.OS.Windows.Msi.csproj - MAINT | | 1682 | AUDIT-0561-T | TODO | Report | Guild | src/Scanner/__Libraries/StellaOps.Scanner.Analyzers.OS.Windows.Msi/StellaOps.Scanner.Analyzers.OS.Windows.Msi.csproj - TEST | | 1683 | AUDIT-0561-A | TODO | Approval | Guild | src/Scanner/__Libraries/StellaOps.Scanner.Analyzers.OS.Windows.Msi/StellaOps.Scanner.Analyzers.OS.Windows.Msi.csproj - APPLY | | 1684 | AUDIT-0562-M | TODO | Report | Guild | src/Scanner/__Tests/StellaOps.Scanner.Analyzers.OS.Windows.Msi.Tests/StellaOps.Scanner.Analyzers.OS.Windows.Msi.Tests.csproj - MAINT | | 1685 | AUDIT-0562-T | TODO | Report | Guild | src/Scanner/__Tests/StellaOps.Scanner.Analyzers.OS.Windows.Msi.Tests/StellaOps.Scanner.Analyzers.OS.Windows.Msi.Tests.csproj - TEST | -| 1686 | AUDIT-0562-A | TODO | Approval | Guild | src/Scanner/__Tests/StellaOps.Scanner.Analyzers.OS.Windows.Msi.Tests/StellaOps.Scanner.Analyzers.OS.Windows.Msi.Tests.csproj - APPLY | +| 1686 | AUDIT-0562-A | DONE | Waived (test project) | Guild | src/Scanner/__Tests/StellaOps.Scanner.Analyzers.OS.Windows.Msi.Tests/StellaOps.Scanner.Analyzers.OS.Windows.Msi.Tests.csproj - APPLY | | 1687 | AUDIT-0563-M | TODO | Report | Guild | src/Scanner/__Libraries/StellaOps.Scanner.Analyzers.OS.Windows.WinSxS/StellaOps.Scanner.Analyzers.OS.Windows.WinSxS.csproj - MAINT | | 1688 | AUDIT-0563-T | TODO | Report | Guild | src/Scanner/__Libraries/StellaOps.Scanner.Analyzers.OS.Windows.WinSxS/StellaOps.Scanner.Analyzers.OS.Windows.WinSxS.csproj - TEST | | 1689 | AUDIT-0563-A | TODO | Approval | Guild | src/Scanner/__Libraries/StellaOps.Scanner.Analyzers.OS.Windows.WinSxS/StellaOps.Scanner.Analyzers.OS.Windows.WinSxS.csproj - APPLY | | 1690 | AUDIT-0564-M | TODO | Report | Guild | src/Scanner/__Tests/StellaOps.Scanner.Analyzers.OS.Windows.WinSxS.Tests/StellaOps.Scanner.Analyzers.OS.Windows.WinSxS.Tests.csproj - MAINT | | 1691 | AUDIT-0564-T | TODO | Report | Guild | src/Scanner/__Tests/StellaOps.Scanner.Analyzers.OS.Windows.WinSxS.Tests/StellaOps.Scanner.Analyzers.OS.Windows.WinSxS.Tests.csproj - TEST | -| 1692 | AUDIT-0564-A | TODO | Approval | Guild | src/Scanner/__Tests/StellaOps.Scanner.Analyzers.OS.Windows.WinSxS.Tests/StellaOps.Scanner.Analyzers.OS.Windows.WinSxS.Tests.csproj - APPLY | +| 1692 | AUDIT-0564-A | DONE | Waived (test project) | Guild | src/Scanner/__Tests/StellaOps.Scanner.Analyzers.OS.Windows.WinSxS.Tests/StellaOps.Scanner.Analyzers.OS.Windows.WinSxS.Tests.csproj - APPLY | | 1693 | AUDIT-0565-M | TODO | Report | Guild | src/Scanner/__Libraries/StellaOps.Scanner.Benchmark/StellaOps.Scanner.Benchmark.csproj - MAINT | | 1694 | AUDIT-0565-T | TODO | Report | Guild | src/Scanner/__Libraries/StellaOps.Scanner.Benchmark/StellaOps.Scanner.Benchmark.csproj - TEST | -| 1695 | AUDIT-0565-A | TODO | Approval | Guild | src/Scanner/__Libraries/StellaOps.Scanner.Benchmark/StellaOps.Scanner.Benchmark.csproj - APPLY | +| 1695 | AUDIT-0565-A | DONE | Waived (benchmark/sample project) | Guild | src/Scanner/__Libraries/StellaOps.Scanner.Benchmark/StellaOps.Scanner.Benchmark.csproj - APPLY | | 1696 | AUDIT-0566-M | TODO | Report | Guild | src/Scanner/__Libraries/StellaOps.Scanner.Benchmarks/StellaOps.Scanner.Benchmarks.csproj - MAINT | | 1697 | AUDIT-0566-T | TODO | Report | Guild | src/Scanner/__Libraries/StellaOps.Scanner.Benchmarks/StellaOps.Scanner.Benchmarks.csproj - TEST | -| 1698 | AUDIT-0566-A | TODO | Approval | Guild | src/Scanner/__Libraries/StellaOps.Scanner.Benchmarks/StellaOps.Scanner.Benchmarks.csproj - APPLY | +| 1698 | AUDIT-0566-A | DONE | Waived (benchmark/sample project) | Guild | src/Scanner/__Libraries/StellaOps.Scanner.Benchmarks/StellaOps.Scanner.Benchmarks.csproj - APPLY | | 1699 | AUDIT-0567-M | TODO | Report | Guild | src/Scanner/__Tests/StellaOps.Scanner.Benchmarks.Tests/StellaOps.Scanner.Benchmarks.Tests.csproj - MAINT | | 1700 | AUDIT-0567-T | TODO | Report | Guild | src/Scanner/__Tests/StellaOps.Scanner.Benchmarks.Tests/StellaOps.Scanner.Benchmarks.Tests.csproj - TEST | -| 1701 | AUDIT-0567-A | TODO | Approval | Guild | src/Scanner/__Tests/StellaOps.Scanner.Benchmarks.Tests/StellaOps.Scanner.Benchmarks.Tests.csproj - APPLY | +| 1701 | AUDIT-0567-A | DONE | Waived (test project) | Guild | src/Scanner/__Tests/StellaOps.Scanner.Benchmarks.Tests/StellaOps.Scanner.Benchmarks.Tests.csproj - APPLY | | 1702 | AUDIT-0568-M | TODO | Report | Guild | src/Scanner/__Libraries/StellaOps.Scanner.Cache/StellaOps.Scanner.Cache.csproj - MAINT | | 1703 | AUDIT-0568-T | TODO | Report | Guild | src/Scanner/__Libraries/StellaOps.Scanner.Cache/StellaOps.Scanner.Cache.csproj - TEST | | 1704 | AUDIT-0568-A | TODO | Approval | Guild | src/Scanner/__Libraries/StellaOps.Scanner.Cache/StellaOps.Scanner.Cache.csproj - APPLY | | 1705 | AUDIT-0569-M | TODO | Report | Guild | src/Scanner/__Tests/StellaOps.Scanner.Cache.Tests/StellaOps.Scanner.Cache.Tests.csproj - MAINT | | 1706 | AUDIT-0569-T | TODO | Report | Guild | src/Scanner/__Tests/StellaOps.Scanner.Cache.Tests/StellaOps.Scanner.Cache.Tests.csproj - TEST | -| 1707 | AUDIT-0569-A | TODO | Approval | Guild | src/Scanner/__Tests/StellaOps.Scanner.Cache.Tests/StellaOps.Scanner.Cache.Tests.csproj - APPLY | +| 1707 | AUDIT-0569-A | DONE | Waived (test project) | Guild | src/Scanner/__Tests/StellaOps.Scanner.Cache.Tests/StellaOps.Scanner.Cache.Tests.csproj - APPLY | | 1708 | AUDIT-0570-M | TODO | Report | Guild | src/Scanner/__Libraries/StellaOps.Scanner.CallGraph/StellaOps.Scanner.CallGraph.csproj - MAINT | | 1709 | AUDIT-0570-T | TODO | Report | Guild | src/Scanner/__Libraries/StellaOps.Scanner.CallGraph/StellaOps.Scanner.CallGraph.csproj - TEST | | 1710 | AUDIT-0570-A | TODO | Approval | Guild | src/Scanner/__Libraries/StellaOps.Scanner.CallGraph/StellaOps.Scanner.CallGraph.csproj - APPLY | | 1711 | AUDIT-0571-M | TODO | Report | Guild | src/Scanner/__Tests/StellaOps.Scanner.CallGraph.Tests/StellaOps.Scanner.CallGraph.Tests.csproj - MAINT | | 1712 | AUDIT-0571-T | TODO | Report | Guild | src/Scanner/__Tests/StellaOps.Scanner.CallGraph.Tests/StellaOps.Scanner.CallGraph.Tests.csproj - TEST | -| 1713 | AUDIT-0571-A | TODO | Approval | Guild | src/Scanner/__Tests/StellaOps.Scanner.CallGraph.Tests/StellaOps.Scanner.CallGraph.Tests.csproj - APPLY | +| 1713 | AUDIT-0571-A | DONE | Waived (test project) | Guild | src/Scanner/__Tests/StellaOps.Scanner.CallGraph.Tests/StellaOps.Scanner.CallGraph.Tests.csproj - APPLY | | 1714 | AUDIT-0572-M | TODO | Report | Guild | src/Scanner/__Libraries/StellaOps.Scanner.Core/StellaOps.Scanner.Core.csproj - MAINT | | 1715 | AUDIT-0572-T | TODO | Report | Guild | src/Scanner/__Libraries/StellaOps.Scanner.Core/StellaOps.Scanner.Core.csproj - TEST | | 1716 | AUDIT-0572-A | TODO | Approval | Guild | src/Scanner/__Libraries/StellaOps.Scanner.Core/StellaOps.Scanner.Core.csproj - APPLY | | 1717 | AUDIT-0573-M | TODO | Report | Guild | src/Scanner/__Tests/StellaOps.Scanner.Core.Tests/StellaOps.Scanner.Core.Tests.csproj - MAINT | | 1718 | AUDIT-0573-T | TODO | Report | Guild | src/Scanner/__Tests/StellaOps.Scanner.Core.Tests/StellaOps.Scanner.Core.Tests.csproj - TEST | -| 1719 | AUDIT-0573-A | TODO | Approval | Guild | src/Scanner/__Tests/StellaOps.Scanner.Core.Tests/StellaOps.Scanner.Core.Tests.csproj - APPLY | +| 1719 | AUDIT-0573-A | DONE | Waived (test project) | Guild | src/Scanner/__Tests/StellaOps.Scanner.Core.Tests/StellaOps.Scanner.Core.Tests.csproj - APPLY | | 1720 | AUDIT-0574-M | TODO | Report | Guild | src/Scanner/__Libraries/StellaOps.Scanner.Diff/StellaOps.Scanner.Diff.csproj - MAINT | | 1721 | AUDIT-0574-T | TODO | Report | Guild | src/Scanner/__Libraries/StellaOps.Scanner.Diff/StellaOps.Scanner.Diff.csproj - TEST | | 1722 | AUDIT-0574-A | TODO | Approval | Guild | src/Scanner/__Libraries/StellaOps.Scanner.Diff/StellaOps.Scanner.Diff.csproj - APPLY | | 1723 | AUDIT-0575-M | TODO | Report | Guild | src/Scanner/__Tests/StellaOps.Scanner.Diff.Tests/StellaOps.Scanner.Diff.Tests.csproj - MAINT | | 1724 | AUDIT-0575-T | TODO | Report | Guild | src/Scanner/__Tests/StellaOps.Scanner.Diff.Tests/StellaOps.Scanner.Diff.Tests.csproj - TEST | -| 1725 | AUDIT-0575-A | TODO | Approval | Guild | src/Scanner/__Tests/StellaOps.Scanner.Diff.Tests/StellaOps.Scanner.Diff.Tests.csproj - APPLY | +| 1725 | AUDIT-0575-A | DONE | Waived (test project) | Guild | src/Scanner/__Tests/StellaOps.Scanner.Diff.Tests/StellaOps.Scanner.Diff.Tests.csproj - APPLY | | 1726 | AUDIT-0576-M | TODO | Report | Guild | src/Scanner/__Libraries/StellaOps.Scanner.Emit/StellaOps.Scanner.Emit.csproj - MAINT | | 1727 | AUDIT-0576-T | TODO | Report | Guild | src/Scanner/__Libraries/StellaOps.Scanner.Emit/StellaOps.Scanner.Emit.csproj - TEST | | 1728 | AUDIT-0576-A | TODO | Approval | Guild | src/Scanner/__Libraries/StellaOps.Scanner.Emit/StellaOps.Scanner.Emit.csproj - APPLY | | 1729 | AUDIT-0577-M | TODO | Report | Guild | src/Scanner/__Tests/StellaOps.Scanner.Emit.Lineage.Tests/StellaOps.Scanner.Emit.Lineage.Tests.csproj - MAINT | | 1730 | AUDIT-0577-T | TODO | Report | Guild | src/Scanner/__Tests/StellaOps.Scanner.Emit.Lineage.Tests/StellaOps.Scanner.Emit.Lineage.Tests.csproj - TEST | -| 1731 | AUDIT-0577-A | TODO | Approval | Guild | src/Scanner/__Tests/StellaOps.Scanner.Emit.Lineage.Tests/StellaOps.Scanner.Emit.Lineage.Tests.csproj - APPLY | +| 1731 | AUDIT-0577-A | DONE | Waived (test project) | Guild | src/Scanner/__Tests/StellaOps.Scanner.Emit.Lineage.Tests/StellaOps.Scanner.Emit.Lineage.Tests.csproj - APPLY | | 1732 | AUDIT-0578-M | TODO | Report | Guild | src/Scanner/__Tests/StellaOps.Scanner.Emit.Tests/StellaOps.Scanner.Emit.Tests.csproj - MAINT | | 1733 | AUDIT-0578-T | TODO | Report | Guild | src/Scanner/__Tests/StellaOps.Scanner.Emit.Tests/StellaOps.Scanner.Emit.Tests.csproj - TEST | -| 1734 | AUDIT-0578-A | TODO | Approval | Guild | src/Scanner/__Tests/StellaOps.Scanner.Emit.Tests/StellaOps.Scanner.Emit.Tests.csproj - APPLY | +| 1734 | AUDIT-0578-A | DONE | Waived (test project) | Guild | src/Scanner/__Tests/StellaOps.Scanner.Emit.Tests/StellaOps.Scanner.Emit.Tests.csproj - APPLY | | 1735 | AUDIT-0579-M | TODO | Report | Guild | src/Scanner/__Libraries/StellaOps.Scanner.EntryTrace/StellaOps.Scanner.EntryTrace.csproj - MAINT | | 1736 | AUDIT-0579-T | TODO | Report | Guild | src/Scanner/__Libraries/StellaOps.Scanner.EntryTrace/StellaOps.Scanner.EntryTrace.csproj - TEST | | 1737 | AUDIT-0579-A | TODO | Approval | Guild | src/Scanner/__Libraries/StellaOps.Scanner.EntryTrace/StellaOps.Scanner.EntryTrace.csproj - APPLY | | 1738 | AUDIT-0580-M | TODO | Report | Guild | src/Scanner/__Tests/StellaOps.Scanner.EntryTrace.Tests/StellaOps.Scanner.EntryTrace.Tests.csproj - MAINT | | 1739 | AUDIT-0580-T | TODO | Report | Guild | src/Scanner/__Tests/StellaOps.Scanner.EntryTrace.Tests/StellaOps.Scanner.EntryTrace.Tests.csproj - TEST | -| 1740 | AUDIT-0580-A | TODO | Approval | Guild | src/Scanner/__Tests/StellaOps.Scanner.EntryTrace.Tests/StellaOps.Scanner.EntryTrace.Tests.csproj - APPLY | +| 1740 | AUDIT-0580-A | DONE | Waived (test project) | Guild | src/Scanner/__Tests/StellaOps.Scanner.EntryTrace.Tests/StellaOps.Scanner.EntryTrace.Tests.csproj - APPLY | | 1741 | AUDIT-0581-M | TODO | Report | Guild | src/Scanner/__Libraries/StellaOps.Scanner.Evidence/StellaOps.Scanner.Evidence.csproj - MAINT | | 1742 | AUDIT-0581-T | TODO | Report | Guild | src/Scanner/__Libraries/StellaOps.Scanner.Evidence/StellaOps.Scanner.Evidence.csproj - TEST | | 1743 | AUDIT-0581-A | TODO | Approval | Guild | src/Scanner/__Libraries/StellaOps.Scanner.Evidence/StellaOps.Scanner.Evidence.csproj - APPLY | | 1744 | AUDIT-0582-M | TODO | Report | Guild | src/Scanner/__Tests/StellaOps.Scanner.Evidence.Tests/StellaOps.Scanner.Evidence.Tests.csproj - MAINT | | 1745 | AUDIT-0582-T | TODO | Report | Guild | src/Scanner/__Tests/StellaOps.Scanner.Evidence.Tests/StellaOps.Scanner.Evidence.Tests.csproj - TEST | -| 1746 | AUDIT-0582-A | TODO | Approval | Guild | src/Scanner/__Tests/StellaOps.Scanner.Evidence.Tests/StellaOps.Scanner.Evidence.Tests.csproj - APPLY | +| 1746 | AUDIT-0582-A | DONE | Waived (test project) | Guild | src/Scanner/__Tests/StellaOps.Scanner.Evidence.Tests/StellaOps.Scanner.Evidence.Tests.csproj - APPLY | | 1747 | AUDIT-0583-M | TODO | Report | Guild | src/Scanner/__Libraries/StellaOps.Scanner.Explainability/StellaOps.Scanner.Explainability.csproj - MAINT | | 1748 | AUDIT-0583-T | TODO | Report | Guild | src/Scanner/__Libraries/StellaOps.Scanner.Explainability/StellaOps.Scanner.Explainability.csproj - TEST | | 1749 | AUDIT-0583-A | TODO | Approval | Guild | src/Scanner/__Libraries/StellaOps.Scanner.Explainability/StellaOps.Scanner.Explainability.csproj - APPLY | | 1750 | AUDIT-0584-M | TODO | Report | Guild | src/Scanner/__Tests/StellaOps.Scanner.Explainability.Tests/StellaOps.Scanner.Explainability.Tests.csproj - MAINT | | 1751 | AUDIT-0584-T | TODO | Report | Guild | src/Scanner/__Tests/StellaOps.Scanner.Explainability.Tests/StellaOps.Scanner.Explainability.Tests.csproj - TEST | -| 1752 | AUDIT-0584-A | TODO | Approval | Guild | src/Scanner/__Tests/StellaOps.Scanner.Explainability.Tests/StellaOps.Scanner.Explainability.Tests.csproj - APPLY | +| 1752 | AUDIT-0584-A | DONE | Waived (test project) | Guild | src/Scanner/__Tests/StellaOps.Scanner.Explainability.Tests/StellaOps.Scanner.Explainability.Tests.csproj - APPLY | | 1753 | AUDIT-0585-M | TODO | Report | Guild | src/Scanner/__Tests/StellaOps.Scanner.Integration.Tests/StellaOps.Scanner.Integration.Tests.csproj - MAINT | | 1754 | AUDIT-0585-T | TODO | Report | Guild | src/Scanner/__Tests/StellaOps.Scanner.Integration.Tests/StellaOps.Scanner.Integration.Tests.csproj - TEST | -| 1755 | AUDIT-0585-A | TODO | Approval | Guild | src/Scanner/__Tests/StellaOps.Scanner.Integration.Tests/StellaOps.Scanner.Integration.Tests.csproj - APPLY | +| 1755 | AUDIT-0585-A | DONE | Waived (test project) | Guild | src/Scanner/__Tests/StellaOps.Scanner.Integration.Tests/StellaOps.Scanner.Integration.Tests.csproj - APPLY | | 1756 | AUDIT-0586-M | TODO | Report | Guild | src/Scanner/__Libraries/StellaOps.Scanner.Orchestration/StellaOps.Scanner.Orchestration.csproj - MAINT | | 1757 | AUDIT-0586-T | TODO | Report | Guild | src/Scanner/__Libraries/StellaOps.Scanner.Orchestration/StellaOps.Scanner.Orchestration.csproj - TEST | | 1758 | AUDIT-0586-A | TODO | Approval | Guild | src/Scanner/__Libraries/StellaOps.Scanner.Orchestration/StellaOps.Scanner.Orchestration.csproj - APPLY | @@ -1786,55 +1786,55 @@ Bulk task definitions (applies to every project row below): | 1764 | AUDIT-0588-A | TODO | Approval | Guild | src/Scanner/__Libraries/StellaOps.Scanner.ProofSpine/StellaOps.Scanner.ProofSpine.csproj - APPLY | | 1765 | AUDIT-0589-M | TODO | Report | Guild | src/Scanner/__Tests/StellaOps.Scanner.ProofSpine.Tests/StellaOps.Scanner.ProofSpine.Tests.csproj - MAINT | | 1766 | AUDIT-0589-T | TODO | Report | Guild | src/Scanner/__Tests/StellaOps.Scanner.ProofSpine.Tests/StellaOps.Scanner.ProofSpine.Tests.csproj - TEST | -| 1767 | AUDIT-0589-A | TODO | Approval | Guild | src/Scanner/__Tests/StellaOps.Scanner.ProofSpine.Tests/StellaOps.Scanner.ProofSpine.Tests.csproj - APPLY | +| 1767 | AUDIT-0589-A | DONE | Waived (test project) | Guild | src/Scanner/__Tests/StellaOps.Scanner.ProofSpine.Tests/StellaOps.Scanner.ProofSpine.Tests.csproj - APPLY | | 1768 | AUDIT-0590-M | TODO | Report | Guild | src/Scanner/__Libraries/StellaOps.Scanner.Queue/StellaOps.Scanner.Queue.csproj - MAINT | | 1769 | AUDIT-0590-T | TODO | Report | Guild | src/Scanner/__Libraries/StellaOps.Scanner.Queue/StellaOps.Scanner.Queue.csproj - TEST | | 1770 | AUDIT-0590-A | TODO | Approval | Guild | src/Scanner/__Libraries/StellaOps.Scanner.Queue/StellaOps.Scanner.Queue.csproj - APPLY | | 1771 | AUDIT-0591-M | TODO | Report | Guild | src/Scanner/__Tests/StellaOps.Scanner.Queue.Tests/StellaOps.Scanner.Queue.Tests.csproj - MAINT | | 1772 | AUDIT-0591-T | TODO | Report | Guild | src/Scanner/__Tests/StellaOps.Scanner.Queue.Tests/StellaOps.Scanner.Queue.Tests.csproj - TEST | -| 1773 | AUDIT-0591-A | TODO | Approval | Guild | src/Scanner/__Tests/StellaOps.Scanner.Queue.Tests/StellaOps.Scanner.Queue.Tests.csproj - APPLY | +| 1773 | AUDIT-0591-A | DONE | Waived (test project) | Guild | src/Scanner/__Tests/StellaOps.Scanner.Queue.Tests/StellaOps.Scanner.Queue.Tests.csproj - APPLY | | 1774 | AUDIT-0592-M | TODO | Report | Guild | src/Scanner/__Libraries/StellaOps.Scanner.Reachability/StellaOps.Scanner.Reachability.csproj - MAINT | | 1775 | AUDIT-0592-T | TODO | Report | Guild | src/Scanner/__Libraries/StellaOps.Scanner.Reachability/StellaOps.Scanner.Reachability.csproj - TEST | | 1776 | AUDIT-0592-A | TODO | Approval | Guild | src/Scanner/__Libraries/StellaOps.Scanner.Reachability/StellaOps.Scanner.Reachability.csproj - APPLY | | 1777 | AUDIT-0593-M | TODO | Report | Guild | src/Scanner/__Tests/StellaOps.Scanner.Reachability.Stack.Tests/StellaOps.Scanner.Reachability.Stack.Tests.csproj - MAINT | | 1778 | AUDIT-0593-T | TODO | Report | Guild | src/Scanner/__Tests/StellaOps.Scanner.Reachability.Stack.Tests/StellaOps.Scanner.Reachability.Stack.Tests.csproj - TEST | -| 1779 | AUDIT-0593-A | TODO | Approval | Guild | src/Scanner/__Tests/StellaOps.Scanner.Reachability.Stack.Tests/StellaOps.Scanner.Reachability.Stack.Tests.csproj - APPLY | +| 1779 | AUDIT-0593-A | DONE | Waived (test project) | Guild | src/Scanner/__Tests/StellaOps.Scanner.Reachability.Stack.Tests/StellaOps.Scanner.Reachability.Stack.Tests.csproj - APPLY | | 1780 | AUDIT-0594-M | TODO | Report | Guild | src/Scanner/__Tests/StellaOps.Scanner.Reachability.Tests/StellaOps.Scanner.Reachability.Tests.csproj - MAINT | | 1781 | AUDIT-0594-T | TODO | Report | Guild | src/Scanner/__Tests/StellaOps.Scanner.Reachability.Tests/StellaOps.Scanner.Reachability.Tests.csproj - TEST | -| 1782 | AUDIT-0594-A | TODO | Approval | Guild | src/Scanner/__Tests/StellaOps.Scanner.Reachability.Tests/StellaOps.Scanner.Reachability.Tests.csproj - APPLY | +| 1782 | AUDIT-0594-A | DONE | Waived (test project) | Guild | src/Scanner/__Tests/StellaOps.Scanner.Reachability.Tests/StellaOps.Scanner.Reachability.Tests.csproj - APPLY | | 1783 | AUDIT-0595-M | TODO | Report | Guild | src/Scanner/__Libraries/StellaOps.Scanner.ReachabilityDrift/StellaOps.Scanner.ReachabilityDrift.csproj - MAINT | | 1784 | AUDIT-0595-T | TODO | Report | Guild | src/Scanner/__Libraries/StellaOps.Scanner.ReachabilityDrift/StellaOps.Scanner.ReachabilityDrift.csproj - TEST | | 1785 | AUDIT-0595-A | TODO | Approval | Guild | src/Scanner/__Libraries/StellaOps.Scanner.ReachabilityDrift/StellaOps.Scanner.ReachabilityDrift.csproj - APPLY | | 1786 | AUDIT-0596-M | TODO | Report | Guild | src/Scanner/__Tests/StellaOps.Scanner.ReachabilityDrift.Tests/StellaOps.Scanner.ReachabilityDrift.Tests.csproj - MAINT | | 1787 | AUDIT-0596-T | TODO | Report | Guild | src/Scanner/__Tests/StellaOps.Scanner.ReachabilityDrift.Tests/StellaOps.Scanner.ReachabilityDrift.Tests.csproj - TEST | -| 1788 | AUDIT-0596-A | TODO | Approval | Guild | src/Scanner/__Tests/StellaOps.Scanner.ReachabilityDrift.Tests/StellaOps.Scanner.ReachabilityDrift.Tests.csproj - APPLY | +| 1788 | AUDIT-0596-A | DONE | Waived (test project) | Guild | src/Scanner/__Tests/StellaOps.Scanner.ReachabilityDrift.Tests/StellaOps.Scanner.ReachabilityDrift.Tests.csproj - APPLY | | 1789 | AUDIT-0597-M | TODO | Report | Guild | src/Scanner/StellaOps.Scanner.Sbomer.BuildXPlugin/StellaOps.Scanner.Sbomer.BuildXPlugin.csproj - MAINT | | 1790 | AUDIT-0597-T | TODO | Report | Guild | src/Scanner/StellaOps.Scanner.Sbomer.BuildXPlugin/StellaOps.Scanner.Sbomer.BuildXPlugin.csproj - TEST | | 1791 | AUDIT-0597-A | TODO | Approval | Guild | src/Scanner/StellaOps.Scanner.Sbomer.BuildXPlugin/StellaOps.Scanner.Sbomer.BuildXPlugin.csproj - APPLY | | 1792 | AUDIT-0598-M | TODO | Report | Guild | src/Scanner/__Tests/StellaOps.Scanner.Sbomer.BuildXPlugin.Tests/StellaOps.Scanner.Sbomer.BuildXPlugin.Tests.csproj - MAINT | | 1793 | AUDIT-0598-T | TODO | Report | Guild | src/Scanner/__Tests/StellaOps.Scanner.Sbomer.BuildXPlugin.Tests/StellaOps.Scanner.Sbomer.BuildXPlugin.Tests.csproj - TEST | -| 1794 | AUDIT-0598-A | TODO | Approval | Guild | src/Scanner/__Tests/StellaOps.Scanner.Sbomer.BuildXPlugin.Tests/StellaOps.Scanner.Sbomer.BuildXPlugin.Tests.csproj - APPLY | +| 1794 | AUDIT-0598-A | DONE | Waived (test project) | Guild | src/Scanner/__Tests/StellaOps.Scanner.Sbomer.BuildXPlugin.Tests/StellaOps.Scanner.Sbomer.BuildXPlugin.Tests.csproj - APPLY | | 1795 | AUDIT-0599-M | TODO | Report | Guild | src/Scanner/__Libraries/StellaOps.Scanner.SmartDiff/StellaOps.Scanner.SmartDiff.csproj - MAINT | | 1796 | AUDIT-0599-T | TODO | Report | Guild | src/Scanner/__Libraries/StellaOps.Scanner.SmartDiff/StellaOps.Scanner.SmartDiff.csproj - TEST | | 1797 | AUDIT-0599-A | TODO | Approval | Guild | src/Scanner/__Libraries/StellaOps.Scanner.SmartDiff/StellaOps.Scanner.SmartDiff.csproj - APPLY | | 1798 | AUDIT-0600-M | TODO | Report | Guild | src/Scanner/__Tests/StellaOps.Scanner.SmartDiff.Tests/StellaOps.Scanner.SmartDiff.Tests.csproj - MAINT | | 1799 | AUDIT-0600-T | TODO | Report | Guild | src/Scanner/__Tests/StellaOps.Scanner.SmartDiff.Tests/StellaOps.Scanner.SmartDiff.Tests.csproj - TEST | -| 1800 | AUDIT-0600-A | TODO | Approval | Guild | src/Scanner/__Tests/StellaOps.Scanner.SmartDiff.Tests/StellaOps.Scanner.SmartDiff.Tests.csproj - APPLY | +| 1800 | AUDIT-0600-A | DONE | Waived (test project) | Guild | src/Scanner/__Tests/StellaOps.Scanner.SmartDiff.Tests/StellaOps.Scanner.SmartDiff.Tests.csproj - APPLY | | 1801 | AUDIT-0601-M | TODO | Report | Guild | src/Scanner/__Libraries/StellaOps.Scanner.Storage/StellaOps.Scanner.Storage.csproj - MAINT | | 1802 | AUDIT-0601-T | TODO | Report | Guild | src/Scanner/__Libraries/StellaOps.Scanner.Storage/StellaOps.Scanner.Storage.csproj - TEST | | 1803 | AUDIT-0601-A | TODO | Approval | Guild | src/Scanner/__Libraries/StellaOps.Scanner.Storage/StellaOps.Scanner.Storage.csproj - APPLY | | 1804 | AUDIT-0602-M | TODO | Report | Guild | src/Scanner/__Benchmarks/StellaOps.Scanner.Storage.Epss.Perf/StellaOps.Scanner.Storage.Epss.Perf.csproj - MAINT | | 1805 | AUDIT-0602-T | TODO | Report | Guild | src/Scanner/__Benchmarks/StellaOps.Scanner.Storage.Epss.Perf/StellaOps.Scanner.Storage.Epss.Perf.csproj - TEST | -| 1806 | AUDIT-0602-A | TODO | Approval | Guild | src/Scanner/__Benchmarks/StellaOps.Scanner.Storage.Epss.Perf/StellaOps.Scanner.Storage.Epss.Perf.csproj - APPLY | +| 1806 | AUDIT-0602-A | DONE | Waived (benchmark/sample project) | Guild | src/Scanner/__Benchmarks/StellaOps.Scanner.Storage.Epss.Perf/StellaOps.Scanner.Storage.Epss.Perf.csproj - APPLY | | 1807 | AUDIT-0603-M | TODO | Report | Guild | src/Scanner/__Libraries/StellaOps.Scanner.Storage.Oci/StellaOps.Scanner.Storage.Oci.csproj - MAINT | | 1808 | AUDIT-0603-T | TODO | Report | Guild | src/Scanner/__Libraries/StellaOps.Scanner.Storage.Oci/StellaOps.Scanner.Storage.Oci.csproj - TEST | | 1809 | AUDIT-0603-A | TODO | Approval | Guild | src/Scanner/__Libraries/StellaOps.Scanner.Storage.Oci/StellaOps.Scanner.Storage.Oci.csproj - APPLY | | 1810 | AUDIT-0604-M | TODO | Report | Guild | src/Scanner/__Tests/StellaOps.Scanner.Storage.Oci.Tests/StellaOps.Scanner.Storage.Oci.Tests.csproj - MAINT | | 1811 | AUDIT-0604-T | TODO | Report | Guild | src/Scanner/__Tests/StellaOps.Scanner.Storage.Oci.Tests/StellaOps.Scanner.Storage.Oci.Tests.csproj - TEST | -| 1812 | AUDIT-0604-A | TODO | Approval | Guild | src/Scanner/__Tests/StellaOps.Scanner.Storage.Oci.Tests/StellaOps.Scanner.Storage.Oci.Tests.csproj - APPLY | +| 1812 | AUDIT-0604-A | DONE | Waived (test project) | Guild | src/Scanner/__Tests/StellaOps.Scanner.Storage.Oci.Tests/StellaOps.Scanner.Storage.Oci.Tests.csproj - APPLY | | 1813 | AUDIT-0605-M | TODO | Report | Guild | src/Scanner/__Tests/StellaOps.Scanner.Storage.Tests/StellaOps.Scanner.Storage.Tests.csproj - MAINT | | 1814 | AUDIT-0605-T | TODO | Report | Guild | src/Scanner/__Tests/StellaOps.Scanner.Storage.Tests/StellaOps.Scanner.Storage.Tests.csproj - TEST | -| 1815 | AUDIT-0605-A | TODO | Approval | Guild | src/Scanner/__Tests/StellaOps.Scanner.Storage.Tests/StellaOps.Scanner.Storage.Tests.csproj - APPLY | +| 1815 | AUDIT-0605-A | DONE | Waived (test project) | Guild | src/Scanner/__Tests/StellaOps.Scanner.Storage.Tests/StellaOps.Scanner.Storage.Tests.csproj - APPLY | | 1816 | AUDIT-0606-M | TODO | Report | Guild | src/Scanner/__Libraries/StellaOps.Scanner.Surface/StellaOps.Scanner.Surface.csproj - MAINT | | 1817 | AUDIT-0606-T | TODO | Report | Guild | src/Scanner/__Libraries/StellaOps.Scanner.Surface/StellaOps.Scanner.Surface.csproj - TEST | | 1818 | AUDIT-0606-A | TODO | Approval | Guild | src/Scanner/__Libraries/StellaOps.Scanner.Surface/StellaOps.Scanner.Surface.csproj - APPLY | @@ -1843,88 +1843,88 @@ Bulk task definitions (applies to every project row below): | 1821 | AUDIT-0607-A | TODO | Approval | Guild | src/Scanner/__Libraries/StellaOps.Scanner.Surface.Env/StellaOps.Scanner.Surface.Env.csproj - APPLY | | 1822 | AUDIT-0608-M | TODO | Report | Guild | src/Scanner/__Tests/StellaOps.Scanner.Surface.Env.Tests/StellaOps.Scanner.Surface.Env.Tests.csproj - MAINT | | 1823 | AUDIT-0608-T | TODO | Report | Guild | src/Scanner/__Tests/StellaOps.Scanner.Surface.Env.Tests/StellaOps.Scanner.Surface.Env.Tests.csproj - TEST | -| 1824 | AUDIT-0608-A | TODO | Approval | Guild | src/Scanner/__Tests/StellaOps.Scanner.Surface.Env.Tests/StellaOps.Scanner.Surface.Env.Tests.csproj - APPLY | +| 1824 | AUDIT-0608-A | DONE | Waived (test project) | Guild | src/Scanner/__Tests/StellaOps.Scanner.Surface.Env.Tests/StellaOps.Scanner.Surface.Env.Tests.csproj - APPLY | | 1825 | AUDIT-0609-M | TODO | Report | Guild | src/Scanner/__Libraries/StellaOps.Scanner.Surface.FS/StellaOps.Scanner.Surface.FS.csproj - MAINT | | 1826 | AUDIT-0609-T | TODO | Report | Guild | src/Scanner/__Libraries/StellaOps.Scanner.Surface.FS/StellaOps.Scanner.Surface.FS.csproj - TEST | | 1827 | AUDIT-0609-A | TODO | Approval | Guild | src/Scanner/__Libraries/StellaOps.Scanner.Surface.FS/StellaOps.Scanner.Surface.FS.csproj - APPLY | | 1828 | AUDIT-0610-M | TODO | Report | Guild | src/Scanner/__Tests/StellaOps.Scanner.Surface.FS.Tests/StellaOps.Scanner.Surface.FS.Tests.csproj - MAINT | | 1829 | AUDIT-0610-T | TODO | Report | Guild | src/Scanner/__Tests/StellaOps.Scanner.Surface.FS.Tests/StellaOps.Scanner.Surface.FS.Tests.csproj - TEST | -| 1830 | AUDIT-0610-A | TODO | Approval | Guild | src/Scanner/__Tests/StellaOps.Scanner.Surface.FS.Tests/StellaOps.Scanner.Surface.FS.Tests.csproj - APPLY | +| 1830 | AUDIT-0610-A | DONE | Waived (test project) | Guild | src/Scanner/__Tests/StellaOps.Scanner.Surface.FS.Tests/StellaOps.Scanner.Surface.FS.Tests.csproj - APPLY | | 1831 | AUDIT-0611-M | TODO | Report | Guild | src/Scanner/__Libraries/StellaOps.Scanner.Surface.Secrets/StellaOps.Scanner.Surface.Secrets.csproj - MAINT | | 1832 | AUDIT-0611-T | TODO | Report | Guild | src/Scanner/__Libraries/StellaOps.Scanner.Surface.Secrets/StellaOps.Scanner.Surface.Secrets.csproj - TEST | | 1833 | AUDIT-0611-A | TODO | Approval | Guild | src/Scanner/__Libraries/StellaOps.Scanner.Surface.Secrets/StellaOps.Scanner.Surface.Secrets.csproj - APPLY | | 1834 | AUDIT-0612-M | TODO | Report | Guild | src/Scanner/__Tests/StellaOps.Scanner.Surface.Secrets.Tests/StellaOps.Scanner.Surface.Secrets.Tests.csproj - MAINT | | 1835 | AUDIT-0612-T | TODO | Report | Guild | src/Scanner/__Tests/StellaOps.Scanner.Surface.Secrets.Tests/StellaOps.Scanner.Surface.Secrets.Tests.csproj - TEST | -| 1836 | AUDIT-0612-A | TODO | Approval | Guild | src/Scanner/__Tests/StellaOps.Scanner.Surface.Secrets.Tests/StellaOps.Scanner.Surface.Secrets.Tests.csproj - APPLY | +| 1836 | AUDIT-0612-A | DONE | Waived (test project) | Guild | src/Scanner/__Tests/StellaOps.Scanner.Surface.Secrets.Tests/StellaOps.Scanner.Surface.Secrets.Tests.csproj - APPLY | | 1837 | AUDIT-0613-M | TODO | Report | Guild | src/Scanner/__Tests/StellaOps.Scanner.Surface.Tests/StellaOps.Scanner.Surface.Tests.csproj - MAINT | | 1838 | AUDIT-0613-T | TODO | Report | Guild | src/Scanner/__Tests/StellaOps.Scanner.Surface.Tests/StellaOps.Scanner.Surface.Tests.csproj - TEST | -| 1839 | AUDIT-0613-A | TODO | Approval | Guild | src/Scanner/__Tests/StellaOps.Scanner.Surface.Tests/StellaOps.Scanner.Surface.Tests.csproj - APPLY | +| 1839 | AUDIT-0613-A | DONE | Waived (test project) | Guild | src/Scanner/__Tests/StellaOps.Scanner.Surface.Tests/StellaOps.Scanner.Surface.Tests.csproj - APPLY | | 1840 | AUDIT-0614-M | TODO | Report | Guild | src/Scanner/__Libraries/StellaOps.Scanner.Surface.Validation/StellaOps.Scanner.Surface.Validation.csproj - MAINT | | 1841 | AUDIT-0614-T | TODO | Report | Guild | src/Scanner/__Libraries/StellaOps.Scanner.Surface.Validation/StellaOps.Scanner.Surface.Validation.csproj - TEST | | 1842 | AUDIT-0614-A | TODO | Approval | Guild | src/Scanner/__Libraries/StellaOps.Scanner.Surface.Validation/StellaOps.Scanner.Surface.Validation.csproj - APPLY | | 1843 | AUDIT-0615-M | TODO | Report | Guild | src/Scanner/__Tests/StellaOps.Scanner.Surface.Validation.Tests/StellaOps.Scanner.Surface.Validation.Tests.csproj - MAINT | | 1844 | AUDIT-0615-T | TODO | Report | Guild | src/Scanner/__Tests/StellaOps.Scanner.Surface.Validation.Tests/StellaOps.Scanner.Surface.Validation.Tests.csproj - TEST | -| 1845 | AUDIT-0615-A | TODO | Approval | Guild | src/Scanner/__Tests/StellaOps.Scanner.Surface.Validation.Tests/StellaOps.Scanner.Surface.Validation.Tests.csproj - APPLY | +| 1845 | AUDIT-0615-A | DONE | Waived (test project) | Guild | src/Scanner/__Tests/StellaOps.Scanner.Surface.Validation.Tests/StellaOps.Scanner.Surface.Validation.Tests.csproj - APPLY | | 1846 | AUDIT-0616-M | TODO | Report | Guild | src/Scanner/__Libraries/StellaOps.Scanner.Triage/StellaOps.Scanner.Triage.csproj - MAINT | | 1847 | AUDIT-0616-T | TODO | Report | Guild | src/Scanner/__Libraries/StellaOps.Scanner.Triage/StellaOps.Scanner.Triage.csproj - TEST | | 1848 | AUDIT-0616-A | TODO | Approval | Guild | src/Scanner/__Libraries/StellaOps.Scanner.Triage/StellaOps.Scanner.Triage.csproj - APPLY | | 1849 | AUDIT-0617-M | TODO | Report | Guild | src/Scanner/__Tests/StellaOps.Scanner.Triage.Tests/StellaOps.Scanner.Triage.Tests.csproj - MAINT | | 1850 | AUDIT-0617-T | TODO | Report | Guild | src/Scanner/__Tests/StellaOps.Scanner.Triage.Tests/StellaOps.Scanner.Triage.Tests.csproj - TEST | -| 1851 | AUDIT-0617-A | TODO | Approval | Guild | src/Scanner/__Tests/StellaOps.Scanner.Triage.Tests/StellaOps.Scanner.Triage.Tests.csproj - APPLY | +| 1851 | AUDIT-0617-A | DONE | Waived (test project) | Guild | src/Scanner/__Tests/StellaOps.Scanner.Triage.Tests/StellaOps.Scanner.Triage.Tests.csproj - APPLY | | 1852 | AUDIT-0618-M | TODO | Report | Guild | src/Scanner/__Libraries/StellaOps.Scanner.VulnSurfaces/StellaOps.Scanner.VulnSurfaces.csproj - MAINT | | 1853 | AUDIT-0618-T | TODO | Report | Guild | src/Scanner/__Libraries/StellaOps.Scanner.VulnSurfaces/StellaOps.Scanner.VulnSurfaces.csproj - TEST | | 1854 | AUDIT-0618-A | TODO | Approval | Guild | src/Scanner/__Libraries/StellaOps.Scanner.VulnSurfaces/StellaOps.Scanner.VulnSurfaces.csproj - APPLY | | 1855 | AUDIT-0619-M | TODO | Report | Guild | src/Scanner/__Libraries/StellaOps.Scanner.VulnSurfaces.Tests/StellaOps.Scanner.VulnSurfaces.Tests.csproj - MAINT | | 1856 | AUDIT-0619-T | TODO | Report | Guild | src/Scanner/__Libraries/StellaOps.Scanner.VulnSurfaces.Tests/StellaOps.Scanner.VulnSurfaces.Tests.csproj - TEST | -| 1857 | AUDIT-0619-A | TODO | Approval | Guild | src/Scanner/__Libraries/StellaOps.Scanner.VulnSurfaces.Tests/StellaOps.Scanner.VulnSurfaces.Tests.csproj - APPLY | +| 1857 | AUDIT-0619-A | DONE | Waived (test project) | Guild | src/Scanner/__Libraries/StellaOps.Scanner.VulnSurfaces.Tests/StellaOps.Scanner.VulnSurfaces.Tests.csproj - APPLY | | 1858 | AUDIT-0620-M | TODO | Report | Guild | src/Scanner/StellaOps.Scanner.WebService/StellaOps.Scanner.WebService.csproj - MAINT | | 1859 | AUDIT-0620-T | TODO | Report | Guild | src/Scanner/StellaOps.Scanner.WebService/StellaOps.Scanner.WebService.csproj - TEST | | 1860 | AUDIT-0620-A | TODO | Approval | Guild | src/Scanner/StellaOps.Scanner.WebService/StellaOps.Scanner.WebService.csproj - APPLY | | 1861 | AUDIT-0621-M | TODO | Report | Guild | src/Scanner/__Tests/StellaOps.Scanner.WebService.Tests/StellaOps.Scanner.WebService.Tests.csproj - MAINT | | 1862 | AUDIT-0621-T | TODO | Report | Guild | src/Scanner/__Tests/StellaOps.Scanner.WebService.Tests/StellaOps.Scanner.WebService.Tests.csproj - TEST | -| 1863 | AUDIT-0621-A | TODO | Approval | Guild | src/Scanner/__Tests/StellaOps.Scanner.WebService.Tests/StellaOps.Scanner.WebService.Tests.csproj - APPLY | +| 1863 | AUDIT-0621-A | DONE | Waived (test project) | Guild | src/Scanner/__Tests/StellaOps.Scanner.WebService.Tests/StellaOps.Scanner.WebService.Tests.csproj - APPLY | | 1864 | AUDIT-0622-M | TODO | Report | Guild | src/Scanner/StellaOps.Scanner.Worker/StellaOps.Scanner.Worker.csproj - MAINT | | 1865 | AUDIT-0622-T | TODO | Report | Guild | src/Scanner/StellaOps.Scanner.Worker/StellaOps.Scanner.Worker.csproj - TEST | | 1866 | AUDIT-0622-A | TODO | Approval | Guild | src/Scanner/StellaOps.Scanner.Worker/StellaOps.Scanner.Worker.csproj - APPLY | | 1867 | AUDIT-0623-M | TODO | Report | Guild | src/Scanner/__Tests/StellaOps.Scanner.Worker.Tests/StellaOps.Scanner.Worker.Tests.csproj - MAINT | | 1868 | AUDIT-0623-T | TODO | Report | Guild | src/Scanner/__Tests/StellaOps.Scanner.Worker.Tests/StellaOps.Scanner.Worker.Tests.csproj - TEST | -| 1869 | AUDIT-0623-A | TODO | Approval | Guild | src/Scanner/__Tests/StellaOps.Scanner.Worker.Tests/StellaOps.Scanner.Worker.Tests.csproj - APPLY | +| 1869 | AUDIT-0623-A | DONE | Waived (test project) | Guild | src/Scanner/__Tests/StellaOps.Scanner.Worker.Tests/StellaOps.Scanner.Worker.Tests.csproj - APPLY | | 1870 | AUDIT-0624-M | TODO | Report | Guild | src/__Tests/reachability/StellaOps.ScannerSignals.IntegrationTests/StellaOps.ScannerSignals.IntegrationTests.csproj - MAINT | | 1871 | AUDIT-0624-T | TODO | Report | Guild | src/__Tests/reachability/StellaOps.ScannerSignals.IntegrationTests/StellaOps.ScannerSignals.IntegrationTests.csproj - TEST | -| 1872 | AUDIT-0624-A | TODO | Approval | Guild | src/__Tests/reachability/StellaOps.ScannerSignals.IntegrationTests/StellaOps.ScannerSignals.IntegrationTests.csproj - APPLY | +| 1872 | AUDIT-0624-A | DONE | Waived (test project) | Guild | src/__Tests/reachability/StellaOps.ScannerSignals.IntegrationTests/StellaOps.ScannerSignals.IntegrationTests.csproj - APPLY | | 1873 | AUDIT-0625-M | TODO | Report | Guild | src/Scheduler/__Tests/StellaOps.Scheduler.Backfill.Tests/StellaOps.Scheduler.Backfill.Tests.csproj - MAINT | | 1874 | AUDIT-0625-T | TODO | Report | Guild | src/Scheduler/__Tests/StellaOps.Scheduler.Backfill.Tests/StellaOps.Scheduler.Backfill.Tests.csproj - TEST | -| 1875 | AUDIT-0625-A | TODO | Approval | Guild | src/Scheduler/__Tests/StellaOps.Scheduler.Backfill.Tests/StellaOps.Scheduler.Backfill.Tests.csproj - APPLY | +| 1875 | AUDIT-0625-A | DONE | Waived (test project) | Guild | src/Scheduler/__Tests/StellaOps.Scheduler.Backfill.Tests/StellaOps.Scheduler.Backfill.Tests.csproj - APPLY | | 1876 | AUDIT-0626-M | TODO | Report | Guild | src/Scheduler/__Libraries/StellaOps.Scheduler.ImpactIndex/StellaOps.Scheduler.ImpactIndex.csproj - MAINT | | 1877 | AUDIT-0626-T | TODO | Report | Guild | src/Scheduler/__Libraries/StellaOps.Scheduler.ImpactIndex/StellaOps.Scheduler.ImpactIndex.csproj - TEST | | 1878 | AUDIT-0626-A | TODO | Approval | Guild | src/Scheduler/__Libraries/StellaOps.Scheduler.ImpactIndex/StellaOps.Scheduler.ImpactIndex.csproj - APPLY | | 1879 | AUDIT-0627-M | TODO | Report | Guild | src/Scheduler/__Tests/StellaOps.Scheduler.ImpactIndex.Tests/StellaOps.Scheduler.ImpactIndex.Tests.csproj - MAINT | | 1880 | AUDIT-0627-T | TODO | Report | Guild | src/Scheduler/__Tests/StellaOps.Scheduler.ImpactIndex.Tests/StellaOps.Scheduler.ImpactIndex.Tests.csproj - TEST | -| 1881 | AUDIT-0627-A | TODO | Approval | Guild | src/Scheduler/__Tests/StellaOps.Scheduler.ImpactIndex.Tests/StellaOps.Scheduler.ImpactIndex.Tests.csproj - APPLY | +| 1881 | AUDIT-0627-A | DONE | Waived (test project) | Guild | src/Scheduler/__Tests/StellaOps.Scheduler.ImpactIndex.Tests/StellaOps.Scheduler.ImpactIndex.Tests.csproj - APPLY | | 1882 | AUDIT-0628-M | TODO | Report | Guild | src/Scheduler/__Libraries/StellaOps.Scheduler.Models/StellaOps.Scheduler.Models.csproj - MAINT | | 1883 | AUDIT-0628-T | TODO | Report | Guild | src/Scheduler/__Libraries/StellaOps.Scheduler.Models/StellaOps.Scheduler.Models.csproj - TEST | | 1884 | AUDIT-0628-A | TODO | Approval | Guild | src/Scheduler/__Libraries/StellaOps.Scheduler.Models/StellaOps.Scheduler.Models.csproj - APPLY | | 1885 | AUDIT-0629-M | TODO | Report | Guild | src/Scheduler/__Tests/StellaOps.Scheduler.Models.Tests/StellaOps.Scheduler.Models.Tests.csproj - MAINT | | 1886 | AUDIT-0629-T | TODO | Report | Guild | src/Scheduler/__Tests/StellaOps.Scheduler.Models.Tests/StellaOps.Scheduler.Models.Tests.csproj - TEST | -| 1887 | AUDIT-0629-A | TODO | Approval | Guild | src/Scheduler/__Tests/StellaOps.Scheduler.Models.Tests/StellaOps.Scheduler.Models.Tests.csproj - APPLY | +| 1887 | AUDIT-0629-A | DONE | Waived (test project) | Guild | src/Scheduler/__Tests/StellaOps.Scheduler.Models.Tests/StellaOps.Scheduler.Models.Tests.csproj - APPLY | | 1888 | AUDIT-0630-M | TODO | Report | Guild | src/Scheduler/__Libraries/StellaOps.Scheduler.Persistence/StellaOps.Scheduler.Persistence.csproj - MAINT | | 1889 | AUDIT-0630-T | TODO | Report | Guild | src/Scheduler/__Libraries/StellaOps.Scheduler.Persistence/StellaOps.Scheduler.Persistence.csproj - TEST | | 1890 | AUDIT-0630-A | TODO | Approval | Guild | src/Scheduler/__Libraries/StellaOps.Scheduler.Persistence/StellaOps.Scheduler.Persistence.csproj - APPLY | | 1891 | AUDIT-0631-M | TODO | Report | Guild | src/Scheduler/__Tests/StellaOps.Scheduler.Persistence.Tests/StellaOps.Scheduler.Persistence.Tests.csproj - MAINT | | 1892 | AUDIT-0631-T | TODO | Report | Guild | src/Scheduler/__Tests/StellaOps.Scheduler.Persistence.Tests/StellaOps.Scheduler.Persistence.Tests.csproj - TEST | -| 1893 | AUDIT-0631-A | TODO | Approval | Guild | src/Scheduler/__Tests/StellaOps.Scheduler.Persistence.Tests/StellaOps.Scheduler.Persistence.Tests.csproj - APPLY | +| 1893 | AUDIT-0631-A | DONE | Waived (test project) | Guild | src/Scheduler/__Tests/StellaOps.Scheduler.Persistence.Tests/StellaOps.Scheduler.Persistence.Tests.csproj - APPLY | | 1894 | AUDIT-0632-M | TODO | Report | Guild | src/Scheduler/__Libraries/StellaOps.Scheduler.Queue/StellaOps.Scheduler.Queue.csproj - MAINT | | 1895 | AUDIT-0632-T | TODO | Report | Guild | src/Scheduler/__Libraries/StellaOps.Scheduler.Queue/StellaOps.Scheduler.Queue.csproj - TEST | | 1896 | AUDIT-0632-A | TODO | Approval | Guild | src/Scheduler/__Libraries/StellaOps.Scheduler.Queue/StellaOps.Scheduler.Queue.csproj - APPLY | | 1897 | AUDIT-0633-M | TODO | Report | Guild | src/Scheduler/__Tests/StellaOps.Scheduler.Queue.Tests/StellaOps.Scheduler.Queue.Tests.csproj - MAINT | | 1898 | AUDIT-0633-T | TODO | Report | Guild | src/Scheduler/__Tests/StellaOps.Scheduler.Queue.Tests/StellaOps.Scheduler.Queue.Tests.csproj - TEST | -| 1899 | AUDIT-0633-A | TODO | Approval | Guild | src/Scheduler/__Tests/StellaOps.Scheduler.Queue.Tests/StellaOps.Scheduler.Queue.Tests.csproj - APPLY | +| 1899 | AUDIT-0633-A | DONE | Waived (test project) | Guild | src/Scheduler/__Tests/StellaOps.Scheduler.Queue.Tests/StellaOps.Scheduler.Queue.Tests.csproj - APPLY | | 1900 | AUDIT-0634-M | TODO | Report | Guild | src/Scheduler/StellaOps.Scheduler.WebService/StellaOps.Scheduler.WebService.csproj - MAINT | | 1901 | AUDIT-0634-T | TODO | Report | Guild | src/Scheduler/StellaOps.Scheduler.WebService/StellaOps.Scheduler.WebService.csproj - TEST | | 1902 | AUDIT-0634-A | TODO | Approval | Guild | src/Scheduler/StellaOps.Scheduler.WebService/StellaOps.Scheduler.WebService.csproj - APPLY | | 1903 | AUDIT-0635-M | TODO | Report | Guild | src/Scheduler/__Tests/StellaOps.Scheduler.WebService.Tests/StellaOps.Scheduler.WebService.Tests.csproj - MAINT | | 1904 | AUDIT-0635-T | TODO | Report | Guild | src/Scheduler/__Tests/StellaOps.Scheduler.WebService.Tests/StellaOps.Scheduler.WebService.Tests.csproj - TEST | -| 1905 | AUDIT-0635-A | TODO | Approval | Guild | src/Scheduler/__Tests/StellaOps.Scheduler.WebService.Tests/StellaOps.Scheduler.WebService.Tests.csproj - APPLY | +| 1905 | AUDIT-0635-A | DONE | Waived (test project) | Guild | src/Scheduler/__Tests/StellaOps.Scheduler.WebService.Tests/StellaOps.Scheduler.WebService.Tests.csproj - APPLY | | 1906 | AUDIT-0636-M | TODO | Report | Guild | src/Scheduler/__Libraries/StellaOps.Scheduler.Worker/StellaOps.Scheduler.Worker.csproj - MAINT | | 1907 | AUDIT-0636-T | TODO | Report | Guild | src/Scheduler/__Libraries/StellaOps.Scheduler.Worker/StellaOps.Scheduler.Worker.csproj - TEST | | 1908 | AUDIT-0636-A | TODO | Approval | Guild | src/Scheduler/__Libraries/StellaOps.Scheduler.Worker/StellaOps.Scheduler.Worker.csproj - APPLY | @@ -1933,10 +1933,10 @@ Bulk task definitions (applies to every project row below): | 1911 | AUDIT-0637-A | TODO | Approval | Guild | src/Scheduler/StellaOps.Scheduler.Worker.Host/StellaOps.Scheduler.Worker.Host.csproj - APPLY | | 1912 | AUDIT-0638-M | TODO | Report | Guild | src/Scheduler/__Tests/StellaOps.Scheduler.Worker.Tests/StellaOps.Scheduler.Worker.Tests.csproj - MAINT | | 1913 | AUDIT-0638-T | TODO | Report | Guild | src/Scheduler/__Tests/StellaOps.Scheduler.Worker.Tests/StellaOps.Scheduler.Worker.Tests.csproj - TEST | -| 1914 | AUDIT-0638-A | TODO | Approval | Guild | src/Scheduler/__Tests/StellaOps.Scheduler.Worker.Tests/StellaOps.Scheduler.Worker.Tests.csproj - APPLY | +| 1914 | AUDIT-0638-A | DONE | Waived (test project) | Guild | src/Scheduler/__Tests/StellaOps.Scheduler.Worker.Tests/StellaOps.Scheduler.Worker.Tests.csproj - APPLY | | 1915 | AUDIT-0639-M | TODO | Report | Guild | src/__Tests/security/StellaOps.Security.Tests/StellaOps.Security.Tests.csproj - MAINT | | 1916 | AUDIT-0639-T | TODO | Report | Guild | src/__Tests/security/StellaOps.Security.Tests/StellaOps.Security.Tests.csproj - TEST | -| 1917 | AUDIT-0639-A | TODO | Approval | Guild | src/__Tests/security/StellaOps.Security.Tests/StellaOps.Security.Tests.csproj - APPLY | +| 1917 | AUDIT-0639-A | DONE | Waived (test project) | Guild | src/__Tests/security/StellaOps.Security.Tests/StellaOps.Security.Tests.csproj - APPLY | | 1918 | AUDIT-0640-M | TODO | Report | Guild | src/Signals/StellaOps.Signals/StellaOps.Signals.csproj - MAINT | | 1919 | AUDIT-0640-T | TODO | Report | Guild | src/Signals/StellaOps.Signals/StellaOps.Signals.csproj - TEST | | 1920 | AUDIT-0640-A | TODO | Approval | Guild | src/Signals/StellaOps.Signals/StellaOps.Signals.csproj - APPLY | @@ -1948,25 +1948,25 @@ Bulk task definitions (applies to every project row below): | 1926 | AUDIT-0642-A | TODO | Approval | Guild | src/Signals/__Libraries/StellaOps.Signals.Ebpf/StellaOps.Signals.Ebpf.csproj - APPLY | | 1927 | AUDIT-0643-M | TODO | Report | Guild | src/Signals/__Tests/StellaOps.Signals.Ebpf.Tests/StellaOps.Signals.Ebpf.Tests.csproj - MAINT | | 1928 | AUDIT-0643-T | TODO | Report | Guild | src/Signals/__Tests/StellaOps.Signals.Ebpf.Tests/StellaOps.Signals.Ebpf.Tests.csproj - TEST | -| 1929 | AUDIT-0643-A | TODO | Approval | Guild | src/Signals/__Tests/StellaOps.Signals.Ebpf.Tests/StellaOps.Signals.Ebpf.Tests.csproj - APPLY | +| 1929 | AUDIT-0643-A | DONE | Waived (test project) | Guild | src/Signals/__Tests/StellaOps.Signals.Ebpf.Tests/StellaOps.Signals.Ebpf.Tests.csproj - APPLY | | 1930 | AUDIT-0644-M | TODO | Report | Guild | src/Signals/__Libraries/StellaOps.Signals.Persistence/StellaOps.Signals.Persistence.csproj - MAINT | | 1931 | AUDIT-0644-T | TODO | Report | Guild | src/Signals/__Libraries/StellaOps.Signals.Persistence/StellaOps.Signals.Persistence.csproj - TEST | | 1932 | AUDIT-0644-A | TODO | Approval | Guild | src/Signals/__Libraries/StellaOps.Signals.Persistence/StellaOps.Signals.Persistence.csproj - APPLY | | 1933 | AUDIT-0645-M | TODO | Report | Guild | src/Signals/__Tests/StellaOps.Signals.Persistence.Tests/StellaOps.Signals.Persistence.Tests.csproj - MAINT | | 1934 | AUDIT-0645-T | TODO | Report | Guild | src/Signals/__Tests/StellaOps.Signals.Persistence.Tests/StellaOps.Signals.Persistence.Tests.csproj - TEST | -| 1935 | AUDIT-0645-A | TODO | Approval | Guild | src/Signals/__Tests/StellaOps.Signals.Persistence.Tests/StellaOps.Signals.Persistence.Tests.csproj - APPLY | +| 1935 | AUDIT-0645-A | DONE | Waived (test project) | Guild | src/Signals/__Tests/StellaOps.Signals.Persistence.Tests/StellaOps.Signals.Persistence.Tests.csproj - APPLY | | 1936 | AUDIT-0646-M | TODO | Report | Guild | src/__Tests/reachability/StellaOps.Signals.Reachability.Tests/StellaOps.Signals.Reachability.Tests.csproj - MAINT | | 1937 | AUDIT-0646-T | TODO | Report | Guild | src/__Tests/reachability/StellaOps.Signals.Reachability.Tests/StellaOps.Signals.Reachability.Tests.csproj - TEST | -| 1938 | AUDIT-0646-A | TODO | Approval | Guild | src/__Tests/reachability/StellaOps.Signals.Reachability.Tests/StellaOps.Signals.Reachability.Tests.csproj - APPLY | +| 1938 | AUDIT-0646-A | DONE | Waived (test project) | Guild | src/__Tests/reachability/StellaOps.Signals.Reachability.Tests/StellaOps.Signals.Reachability.Tests.csproj - APPLY | | 1939 | AUDIT-0647-M | TODO | Report | Guild | src/Signals/StellaOps.Signals.Scheduler/StellaOps.Signals.Scheduler.csproj - MAINT | | 1940 | AUDIT-0647-T | TODO | Report | Guild | src/Signals/StellaOps.Signals.Scheduler/StellaOps.Signals.Scheduler.csproj - TEST | | 1941 | AUDIT-0647-A | TODO | Approval | Guild | src/Signals/StellaOps.Signals.Scheduler/StellaOps.Signals.Scheduler.csproj - APPLY | | 1942 | AUDIT-0648-M | TODO | Report | Guild | src/__Libraries/__Tests/StellaOps.Signals.Tests/StellaOps.Signals.Tests.csproj - MAINT | | 1943 | AUDIT-0648-T | TODO | Report | Guild | src/__Libraries/__Tests/StellaOps.Signals.Tests/StellaOps.Signals.Tests.csproj - TEST | -| 1944 | AUDIT-0648-A | TODO | Approval | Guild | src/__Libraries/__Tests/StellaOps.Signals.Tests/StellaOps.Signals.Tests.csproj - APPLY | +| 1944 | AUDIT-0648-A | DONE | Waived (test project) | Guild | src/__Libraries/__Tests/StellaOps.Signals.Tests/StellaOps.Signals.Tests.csproj - APPLY | | 1945 | AUDIT-0649-M | TODO | Report | Guild | src/Signals/__Tests/StellaOps.Signals.Tests/StellaOps.Signals.Tests.csproj - MAINT | | 1946 | AUDIT-0649-T | TODO | Report | Guild | src/Signals/__Tests/StellaOps.Signals.Tests/StellaOps.Signals.Tests.csproj - TEST | -| 1947 | AUDIT-0649-A | TODO | Approval | Guild | src/Signals/__Tests/StellaOps.Signals.Tests/StellaOps.Signals.Tests.csproj - APPLY | +| 1947 | AUDIT-0649-A | DONE | Waived (test project) | Guild | src/Signals/__Tests/StellaOps.Signals.Tests/StellaOps.Signals.Tests.csproj - APPLY | | 1948 | AUDIT-0650-M | TODO | Report | Guild | src/Signer/StellaOps.Signer/StellaOps.Signer.Core/StellaOps.Signer.Core.csproj - MAINT | | 1949 | AUDIT-0650-T | TODO | Report | Guild | src/Signer/StellaOps.Signer/StellaOps.Signer.Core/StellaOps.Signer.Core.csproj - TEST | | 1950 | AUDIT-0650-A | TODO | Approval | Guild | src/Signer/StellaOps.Signer/StellaOps.Signer.Core/StellaOps.Signer.Core.csproj - APPLY | @@ -1981,7 +1981,7 @@ Bulk task definitions (applies to every project row below): | 1959 | AUDIT-0653-A | TODO | Approval | Guild | src/Signer/__Libraries/StellaOps.Signer.Keyless/StellaOps.Signer.Keyless.csproj - APPLY | | 1960 | AUDIT-0654-M | TODO | Report | Guild | src/Signer/StellaOps.Signer/StellaOps.Signer.Tests/StellaOps.Signer.Tests.csproj - MAINT | | 1961 | AUDIT-0654-T | TODO | Report | Guild | src/Signer/StellaOps.Signer/StellaOps.Signer.Tests/StellaOps.Signer.Tests.csproj - TEST | -| 1962 | AUDIT-0654-A | TODO | Approval | Guild | src/Signer/StellaOps.Signer/StellaOps.Signer.Tests/StellaOps.Signer.Tests.csproj - APPLY | +| 1962 | AUDIT-0654-A | DONE | Waived (test project) | Guild | src/Signer/StellaOps.Signer/StellaOps.Signer.Tests/StellaOps.Signer.Tests.csproj - APPLY | | 1963 | AUDIT-0655-M | TODO | Report | Guild | src/Signer/StellaOps.Signer/StellaOps.Signer.WebService/StellaOps.Signer.WebService.csproj - MAINT | | 1964 | AUDIT-0655-T | TODO | Report | Guild | src/Signer/StellaOps.Signer/StellaOps.Signer.WebService/StellaOps.Signer.WebService.csproj - TEST | | 1965 | AUDIT-0655-A | TODO | Approval | Guild | src/Signer/StellaOps.Signer/StellaOps.Signer.WebService/StellaOps.Signer.WebService.csproj - APPLY | @@ -2017,10 +2017,10 @@ Bulk task definitions (applies to every project row below): | 1995 | AUDIT-0665-A | TODO | Approval | Guild | src/TaskRunner/__Libraries/StellaOps.TaskRunner.Persistence/StellaOps.TaskRunner.Persistence.csproj - APPLY | | 1996 | AUDIT-0666-M | TODO | Report | Guild | src/TaskRunner/__Tests/StellaOps.TaskRunner.Persistence.Tests/StellaOps.TaskRunner.Persistence.Tests.csproj - MAINT | | 1997 | AUDIT-0666-T | TODO | Report | Guild | src/TaskRunner/__Tests/StellaOps.TaskRunner.Persistence.Tests/StellaOps.TaskRunner.Persistence.Tests.csproj - TEST | -| 1998 | AUDIT-0666-A | TODO | Approval | Guild | src/TaskRunner/__Tests/StellaOps.TaskRunner.Persistence.Tests/StellaOps.TaskRunner.Persistence.Tests.csproj - APPLY | +| 1998 | AUDIT-0666-A | DONE | Waived (test project) | Guild | src/TaskRunner/__Tests/StellaOps.TaskRunner.Persistence.Tests/StellaOps.TaskRunner.Persistence.Tests.csproj - APPLY | | 1999 | AUDIT-0667-M | TODO | Report | Guild | src/TaskRunner/StellaOps.TaskRunner/StellaOps.TaskRunner.Tests/StellaOps.TaskRunner.Tests.csproj - MAINT | | 2000 | AUDIT-0667-T | TODO | Report | Guild | src/TaskRunner/StellaOps.TaskRunner/StellaOps.TaskRunner.Tests/StellaOps.TaskRunner.Tests.csproj - TEST | -| 2001 | AUDIT-0667-A | TODO | Approval | Guild | src/TaskRunner/StellaOps.TaskRunner/StellaOps.TaskRunner.Tests/StellaOps.TaskRunner.Tests.csproj - APPLY | +| 2001 | AUDIT-0667-A | DONE | Waived (test project) | Guild | src/TaskRunner/StellaOps.TaskRunner/StellaOps.TaskRunner.Tests/StellaOps.TaskRunner.Tests.csproj - APPLY | | 2002 | AUDIT-0668-M | TODO | Report | Guild | src/TaskRunner/StellaOps.TaskRunner/StellaOps.TaskRunner.WebService/StellaOps.TaskRunner.WebService.csproj - MAINT | | 2003 | AUDIT-0668-T | TODO | Report | Guild | src/TaskRunner/StellaOps.TaskRunner/StellaOps.TaskRunner.WebService/StellaOps.TaskRunner.WebService.csproj - TEST | | 2004 | AUDIT-0668-A | TODO | Approval | Guild | src/TaskRunner/StellaOps.TaskRunner/StellaOps.TaskRunner.WebService/StellaOps.TaskRunner.WebService.csproj - APPLY | @@ -2032,37 +2032,37 @@ Bulk task definitions (applies to every project row below): | 2010 | AUDIT-0670-A | TODO | Approval | Guild | src/Telemetry/StellaOps.Telemetry.Analyzers/StellaOps.Telemetry.Analyzers.csproj - APPLY | | 2011 | AUDIT-0671-M | TODO | Report | Guild | src/Telemetry/StellaOps.Telemetry.Analyzers/StellaOps.Telemetry.Analyzers.Tests/StellaOps.Telemetry.Analyzers.Tests.csproj - MAINT | | 2012 | AUDIT-0671-T | TODO | Report | Guild | src/Telemetry/StellaOps.Telemetry.Analyzers/StellaOps.Telemetry.Analyzers.Tests/StellaOps.Telemetry.Analyzers.Tests.csproj - TEST | -| 2013 | AUDIT-0671-A | TODO | Approval | Guild | src/Telemetry/StellaOps.Telemetry.Analyzers/StellaOps.Telemetry.Analyzers.Tests/StellaOps.Telemetry.Analyzers.Tests.csproj - APPLY | +| 2013 | AUDIT-0671-A | DONE | Waived (test project) | Guild | src/Telemetry/StellaOps.Telemetry.Analyzers/StellaOps.Telemetry.Analyzers.Tests/StellaOps.Telemetry.Analyzers.Tests.csproj - APPLY | | 2014 | AUDIT-0672-M | TODO | Report | Guild | src/Telemetry/StellaOps.Telemetry.Core/StellaOps.Telemetry.Core/StellaOps.Telemetry.Core.csproj - MAINT | | 2015 | AUDIT-0672-T | TODO | Report | Guild | src/Telemetry/StellaOps.Telemetry.Core/StellaOps.Telemetry.Core/StellaOps.Telemetry.Core.csproj - TEST | | 2016 | AUDIT-0672-A | TODO | Approval | Guild | src/Telemetry/StellaOps.Telemetry.Core/StellaOps.Telemetry.Core/StellaOps.Telemetry.Core.csproj - APPLY | | 2017 | AUDIT-0673-M | TODO | Report | Guild | src/Telemetry/StellaOps.Telemetry.Core/StellaOps.Telemetry.Core.Tests/StellaOps.Telemetry.Core.Tests.csproj - MAINT | | 2018 | AUDIT-0673-T | TODO | Report | Guild | src/Telemetry/StellaOps.Telemetry.Core/StellaOps.Telemetry.Core.Tests/StellaOps.Telemetry.Core.Tests.csproj - TEST | -| 2019 | AUDIT-0673-A | TODO | Approval | Guild | src/Telemetry/StellaOps.Telemetry.Core/StellaOps.Telemetry.Core.Tests/StellaOps.Telemetry.Core.Tests.csproj - APPLY | +| 2019 | AUDIT-0673-A | DONE | Waived (test project) | Guild | src/Telemetry/StellaOps.Telemetry.Core/StellaOps.Telemetry.Core.Tests/StellaOps.Telemetry.Core.Tests.csproj - APPLY | | 2020 | AUDIT-0674-M | TODO | Report | Guild | src/__Libraries/StellaOps.TestKit/StellaOps.TestKit.csproj - MAINT | | 2021 | AUDIT-0674-T | TODO | Report | Guild | src/__Libraries/StellaOps.TestKit/StellaOps.TestKit.csproj - TEST | | 2022 | AUDIT-0674-A | TODO | Approval | Guild | src/__Libraries/StellaOps.TestKit/StellaOps.TestKit.csproj - APPLY | | 2023 | AUDIT-0675-M | TODO | Report | Guild | src/__Libraries/__Tests/StellaOps.TestKit.Tests/StellaOps.TestKit.Tests.csproj - MAINT | | 2024 | AUDIT-0675-T | TODO | Report | Guild | src/__Libraries/__Tests/StellaOps.TestKit.Tests/StellaOps.TestKit.Tests.csproj - TEST | -| 2025 | AUDIT-0675-A | TODO | Approval | Guild | src/__Libraries/__Tests/StellaOps.TestKit.Tests/StellaOps.TestKit.Tests.csproj - APPLY | +| 2025 | AUDIT-0675-A | DONE | Waived (test project) | Guild | src/__Libraries/__Tests/StellaOps.TestKit.Tests/StellaOps.TestKit.Tests.csproj - APPLY | | 2026 | AUDIT-0676-M | TODO | Report | Guild | src/__Tests/__Libraries/StellaOps.Testing.AirGap/StellaOps.Testing.AirGap.csproj - MAINT | | 2027 | AUDIT-0676-T | TODO | Report | Guild | src/__Tests/__Libraries/StellaOps.Testing.AirGap/StellaOps.Testing.AirGap.csproj - TEST | -| 2028 | AUDIT-0676-A | TODO | Approval | Guild | src/__Tests/__Libraries/StellaOps.Testing.AirGap/StellaOps.Testing.AirGap.csproj - APPLY | +| 2028 | AUDIT-0676-A | DONE | Waived (test project) | Guild | src/__Tests/__Libraries/StellaOps.Testing.AirGap/StellaOps.Testing.AirGap.csproj - APPLY | | 2029 | AUDIT-0677-M | TODO | Report | Guild | src/__Tests/__Libraries/StellaOps.Testing.Determinism/StellaOps.Testing.Determinism.csproj - MAINT | | 2030 | AUDIT-0677-T | TODO | Report | Guild | src/__Tests/__Libraries/StellaOps.Testing.Determinism/StellaOps.Testing.Determinism.csproj - TEST | -| 2031 | AUDIT-0677-A | TODO | Approval | Guild | src/__Tests/__Libraries/StellaOps.Testing.Determinism/StellaOps.Testing.Determinism.csproj - APPLY | +| 2031 | AUDIT-0677-A | DONE | Waived (test project) | Guild | src/__Tests/__Libraries/StellaOps.Testing.Determinism/StellaOps.Testing.Determinism.csproj - APPLY | | 2032 | AUDIT-0678-M | TODO | Report | Guild | src/__Tests/__Libraries/StellaOps.Testing.Determinism.Properties/StellaOps.Testing.Determinism.Properties.csproj - MAINT | | 2033 | AUDIT-0678-T | TODO | Report | Guild | src/__Tests/__Libraries/StellaOps.Testing.Determinism.Properties/StellaOps.Testing.Determinism.Properties.csproj - TEST | -| 2034 | AUDIT-0678-A | TODO | Approval | Guild | src/__Tests/__Libraries/StellaOps.Testing.Determinism.Properties/StellaOps.Testing.Determinism.Properties.csproj - APPLY | +| 2034 | AUDIT-0678-A | DONE | Waived (test project) | Guild | src/__Tests/__Libraries/StellaOps.Testing.Determinism.Properties/StellaOps.Testing.Determinism.Properties.csproj - APPLY | | 2035 | AUDIT-0679-M | TODO | Report | Guild | src/__Libraries/__Tests/StellaOps.Testing.Determinism.Tests/StellaOps.Testing.Determinism.Tests.csproj - MAINT | | 2036 | AUDIT-0679-T | TODO | Report | Guild | src/__Libraries/__Tests/StellaOps.Testing.Determinism.Tests/StellaOps.Testing.Determinism.Tests.csproj - TEST | -| 2037 | AUDIT-0679-A | TODO | Approval | Guild | src/__Libraries/__Tests/StellaOps.Testing.Determinism.Tests/StellaOps.Testing.Determinism.Tests.csproj - APPLY | +| 2037 | AUDIT-0679-A | DONE | Waived (test project) | Guild | src/__Libraries/__Tests/StellaOps.Testing.Determinism.Tests/StellaOps.Testing.Determinism.Tests.csproj - APPLY | | 2038 | AUDIT-0680-M | TODO | Report | Guild | src/__Tests/__Libraries/StellaOps.Testing.Manifests/StellaOps.Testing.Manifests.csproj - MAINT | | 2039 | AUDIT-0680-T | TODO | Report | Guild | src/__Tests/__Libraries/StellaOps.Testing.Manifests/StellaOps.Testing.Manifests.csproj - TEST | -| 2040 | AUDIT-0680-A | TODO | Approval | Guild | src/__Tests/__Libraries/StellaOps.Testing.Manifests/StellaOps.Testing.Manifests.csproj - APPLY | +| 2040 | AUDIT-0680-A | DONE | Waived (test project) | Guild | src/__Tests/__Libraries/StellaOps.Testing.Manifests/StellaOps.Testing.Manifests.csproj - APPLY | | 2041 | AUDIT-0681-M | TODO | Report | Guild | src/__Libraries/__Tests/StellaOps.Testing.Manifests.Tests/StellaOps.Testing.Manifests.Tests.csproj - MAINT | | 2042 | AUDIT-0681-T | TODO | Report | Guild | src/__Libraries/__Tests/StellaOps.Testing.Manifests.Tests/StellaOps.Testing.Manifests.Tests.csproj - TEST | -| 2043 | AUDIT-0681-A | TODO | Approval | Guild | src/__Libraries/__Tests/StellaOps.Testing.Manifests.Tests/StellaOps.Testing.Manifests.Tests.csproj - APPLY | +| 2043 | AUDIT-0681-A | DONE | Waived (test project) | Guild | src/__Libraries/__Tests/StellaOps.Testing.Manifests.Tests/StellaOps.Testing.Manifests.Tests.csproj - APPLY | | 2044 | AUDIT-0682-M | TODO | Report | Guild | src/TimelineIndexer/StellaOps.TimelineIndexer/StellaOps.TimelineIndexer.Core/StellaOps.TimelineIndexer.Core.csproj - MAINT | | 2045 | AUDIT-0682-T | TODO | Report | Guild | src/TimelineIndexer/StellaOps.TimelineIndexer/StellaOps.TimelineIndexer.Core/StellaOps.TimelineIndexer.Core.csproj - TEST | | 2046 | AUDIT-0682-A | TODO | Approval | Guild | src/TimelineIndexer/StellaOps.TimelineIndexer/StellaOps.TimelineIndexer.Core/StellaOps.TimelineIndexer.Core.csproj - APPLY | @@ -2071,7 +2071,7 @@ Bulk task definitions (applies to every project row below): | 2049 | AUDIT-0683-A | TODO | Approval | Guild | src/TimelineIndexer/StellaOps.TimelineIndexer/StellaOps.TimelineIndexer.Infrastructure/StellaOps.TimelineIndexer.Infrastructure.csproj - APPLY | | 2050 | AUDIT-0684-M | TODO | Report | Guild | src/TimelineIndexer/StellaOps.TimelineIndexer/StellaOps.TimelineIndexer.Tests/StellaOps.TimelineIndexer.Tests.csproj - MAINT | | 2051 | AUDIT-0684-T | TODO | Report | Guild | src/TimelineIndexer/StellaOps.TimelineIndexer/StellaOps.TimelineIndexer.Tests/StellaOps.TimelineIndexer.Tests.csproj - TEST | -| 2052 | AUDIT-0684-A | TODO | Approval | Guild | src/TimelineIndexer/StellaOps.TimelineIndexer/StellaOps.TimelineIndexer.Tests/StellaOps.TimelineIndexer.Tests.csproj - APPLY | +| 2052 | AUDIT-0684-A | DONE | Waived (test project) | Guild | src/TimelineIndexer/StellaOps.TimelineIndexer/StellaOps.TimelineIndexer.Tests/StellaOps.TimelineIndexer.Tests.csproj - APPLY | | 2053 | AUDIT-0685-M | TODO | Report | Guild | src/TimelineIndexer/StellaOps.TimelineIndexer/StellaOps.TimelineIndexer.WebService/StellaOps.TimelineIndexer.WebService.csproj - MAINT | | 2054 | AUDIT-0685-T | TODO | Report | Guild | src/TimelineIndexer/StellaOps.TimelineIndexer/StellaOps.TimelineIndexer.WebService/StellaOps.TimelineIndexer.WebService.csproj - TEST | | 2055 | AUDIT-0685-A | TODO | Approval | Guild | src/TimelineIndexer/StellaOps.TimelineIndexer/StellaOps.TimelineIndexer.WebService/StellaOps.TimelineIndexer.WebService.csproj - APPLY | @@ -2083,7 +2083,7 @@ Bulk task definitions (applies to every project row below): | 2061 | AUDIT-0687-A | TODO | Approval | Guild | src/Unknowns/__Libraries/StellaOps.Unknowns.Core/StellaOps.Unknowns.Core.csproj - APPLY | | 2062 | AUDIT-0688-M | TODO | Report | Guild | src/Unknowns/__Tests/StellaOps.Unknowns.Core.Tests/StellaOps.Unknowns.Core.Tests.csproj - MAINT | | 2063 | AUDIT-0688-T | TODO | Report | Guild | src/Unknowns/__Tests/StellaOps.Unknowns.Core.Tests/StellaOps.Unknowns.Core.Tests.csproj - TEST | -| 2064 | AUDIT-0688-A | TODO | Approval | Guild | src/Unknowns/__Tests/StellaOps.Unknowns.Core.Tests/StellaOps.Unknowns.Core.Tests.csproj - APPLY | +| 2064 | AUDIT-0688-A | DONE | Waived (test project) | Guild | src/Unknowns/__Tests/StellaOps.Unknowns.Core.Tests/StellaOps.Unknowns.Core.Tests.csproj - APPLY | | 2065 | AUDIT-0689-M | TODO | Report | Guild | src/Unknowns/__Libraries/StellaOps.Unknowns.Persistence/StellaOps.Unknowns.Persistence.csproj - MAINT | | 2066 | AUDIT-0689-T | TODO | Report | Guild | src/Unknowns/__Libraries/StellaOps.Unknowns.Persistence/StellaOps.Unknowns.Persistence.csproj - TEST | | 2067 | AUDIT-0689-A | TODO | Approval | Guild | src/Unknowns/__Libraries/StellaOps.Unknowns.Persistence/StellaOps.Unknowns.Persistence.csproj - APPLY | @@ -2092,7 +2092,7 @@ Bulk task definitions (applies to every project row below): | 2070 | AUDIT-0690-A | TODO | Approval | Guild | src/Unknowns/__Libraries/StellaOps.Unknowns.Persistence.EfCore/StellaOps.Unknowns.Persistence.EfCore.csproj - APPLY | | 2071 | AUDIT-0691-M | TODO | Report | Guild | src/Unknowns/__Tests/StellaOps.Unknowns.Persistence.Tests/StellaOps.Unknowns.Persistence.Tests.csproj - MAINT | | 2072 | AUDIT-0691-T | TODO | Report | Guild | src/Unknowns/__Tests/StellaOps.Unknowns.Persistence.Tests/StellaOps.Unknowns.Persistence.Tests.csproj - TEST | -| 2073 | AUDIT-0691-A | TODO | Approval | Guild | src/Unknowns/__Tests/StellaOps.Unknowns.Persistence.Tests/StellaOps.Unknowns.Persistence.Tests.csproj - APPLY | +| 2073 | AUDIT-0691-A | DONE | Waived (test project) | Guild | src/Unknowns/__Tests/StellaOps.Unknowns.Persistence.Tests/StellaOps.Unknowns.Persistence.Tests.csproj - APPLY | | 2074 | AUDIT-0692-M | TODO | Report | Guild | src/__Libraries/StellaOps.Verdict/StellaOps.Verdict.csproj - MAINT | | 2075 | AUDIT-0692-T | TODO | Report | Guild | src/__Libraries/StellaOps.Verdict/StellaOps.Verdict.csproj - TEST | | 2076 | AUDIT-0692-A | TODO | Approval | Guild | src/__Libraries/StellaOps.Verdict/StellaOps.Verdict.csproj - APPLY | @@ -2101,13 +2101,13 @@ Bulk task definitions (applies to every project row below): | 2079 | AUDIT-0693-A | TODO | Approval | Guild | src/__Libraries/StellaOps.VersionComparison/StellaOps.VersionComparison.csproj - APPLY | | 2080 | AUDIT-0694-M | TODO | Report | Guild | src/__Libraries/__Tests/StellaOps.VersionComparison.Tests/StellaOps.VersionComparison.Tests.csproj - MAINT | | 2081 | AUDIT-0694-T | TODO | Report | Guild | src/__Libraries/__Tests/StellaOps.VersionComparison.Tests/StellaOps.VersionComparison.Tests.csproj - TEST | -| 2082 | AUDIT-0694-A | TODO | Approval | Guild | src/__Libraries/__Tests/StellaOps.VersionComparison.Tests/StellaOps.VersionComparison.Tests.csproj - APPLY | +| 2082 | AUDIT-0694-A | DONE | Waived (test project) | Guild | src/__Libraries/__Tests/StellaOps.VersionComparison.Tests/StellaOps.VersionComparison.Tests.csproj - APPLY | | 2083 | AUDIT-0695-M | TODO | Report | Guild | src/VexHub/__Libraries/StellaOps.VexHub.Core/StellaOps.VexHub.Core.csproj - MAINT | | 2084 | AUDIT-0695-T | TODO | Report | Guild | src/VexHub/__Libraries/StellaOps.VexHub.Core/StellaOps.VexHub.Core.csproj - TEST | | 2085 | AUDIT-0695-A | TODO | Approval | Guild | src/VexHub/__Libraries/StellaOps.VexHub.Core/StellaOps.VexHub.Core.csproj - APPLY | | 2086 | AUDIT-0696-M | TODO | Report | Guild | src/VexHub/__Tests/StellaOps.VexHub.Core.Tests/StellaOps.VexHub.Core.Tests.csproj - MAINT | | 2087 | AUDIT-0696-T | TODO | Report | Guild | src/VexHub/__Tests/StellaOps.VexHub.Core.Tests/StellaOps.VexHub.Core.Tests.csproj - TEST | -| 2088 | AUDIT-0696-A | TODO | Approval | Guild | src/VexHub/__Tests/StellaOps.VexHub.Core.Tests/StellaOps.VexHub.Core.Tests.csproj - APPLY | +| 2088 | AUDIT-0696-A | DONE | Waived (test project) | Guild | src/VexHub/__Tests/StellaOps.VexHub.Core.Tests/StellaOps.VexHub.Core.Tests.csproj - APPLY | | 2089 | AUDIT-0697-M | TODO | Report | Guild | src/VexHub/__Libraries/StellaOps.VexHub.Persistence/StellaOps.VexHub.Persistence.csproj - MAINT | | 2090 | AUDIT-0697-T | TODO | Report | Guild | src/VexHub/__Libraries/StellaOps.VexHub.Persistence/StellaOps.VexHub.Persistence.csproj - TEST | | 2091 | AUDIT-0697-A | TODO | Approval | Guild | src/VexHub/__Libraries/StellaOps.VexHub.Persistence/StellaOps.VexHub.Persistence.csproj - APPLY | @@ -2116,7 +2116,7 @@ Bulk task definitions (applies to every project row below): | 2094 | AUDIT-0698-A | TODO | Approval | Guild | src/VexHub/StellaOps.VexHub.WebService/StellaOps.VexHub.WebService.csproj - APPLY | | 2095 | AUDIT-0699-M | TODO | Report | Guild | src/VexHub/__Tests/StellaOps.VexHub.WebService.Tests/StellaOps.VexHub.WebService.Tests.csproj - MAINT | | 2096 | AUDIT-0699-T | TODO | Report | Guild | src/VexHub/__Tests/StellaOps.VexHub.WebService.Tests/StellaOps.VexHub.WebService.Tests.csproj - TEST | -| 2097 | AUDIT-0699-A | TODO | Approval | Guild | src/VexHub/__Tests/StellaOps.VexHub.WebService.Tests/StellaOps.VexHub.WebService.Tests.csproj - APPLY | +| 2097 | AUDIT-0699-A | DONE | Waived (test project) | Guild | src/VexHub/__Tests/StellaOps.VexHub.WebService.Tests/StellaOps.VexHub.WebService.Tests.csproj - APPLY | | 2098 | AUDIT-0700-M | TODO | Report | Guild | src/VexLens/StellaOps.VexLens/StellaOps.VexLens.csproj - MAINT | | 2099 | AUDIT-0700-T | TODO | Report | Guild | src/VexLens/StellaOps.VexLens/StellaOps.VexLens.csproj - TEST | | 2100 | AUDIT-0700-A | TODO | Approval | Guild | src/VexLens/StellaOps.VexLens/StellaOps.VexLens.csproj - APPLY | @@ -2125,7 +2125,7 @@ Bulk task definitions (applies to every project row below): | 2103 | AUDIT-0701-A | TODO | Approval | Guild | src/VexLens/StellaOps.VexLens/StellaOps.VexLens.Core/StellaOps.VexLens.Core.csproj - APPLY | | 2104 | AUDIT-0702-M | TODO | Report | Guild | src/VexLens/StellaOps.VexLens/__Tests/StellaOps.VexLens.Core.Tests/StellaOps.VexLens.Core.Tests.csproj - MAINT | | 2105 | AUDIT-0702-T | TODO | Report | Guild | src/VexLens/StellaOps.VexLens/__Tests/StellaOps.VexLens.Core.Tests/StellaOps.VexLens.Core.Tests.csproj - TEST | -| 2106 | AUDIT-0702-A | TODO | Approval | Guild | src/VexLens/StellaOps.VexLens/__Tests/StellaOps.VexLens.Core.Tests/StellaOps.VexLens.Core.Tests.csproj - APPLY | +| 2106 | AUDIT-0702-A | DONE | Waived (test project) | Guild | src/VexLens/StellaOps.VexLens/__Tests/StellaOps.VexLens.Core.Tests/StellaOps.VexLens.Core.Tests.csproj - APPLY | | 2107 | AUDIT-0703-M | TODO | Report | Guild | src/VexLens/StellaOps.VexLens.Persistence/StellaOps.VexLens.Persistence.csproj - MAINT | | 2108 | AUDIT-0703-T | TODO | Report | Guild | src/VexLens/StellaOps.VexLens.Persistence/StellaOps.VexLens.Persistence.csproj - TEST | | 2109 | AUDIT-0703-A | TODO | Approval | Guild | src/VexLens/StellaOps.VexLens.Persistence/StellaOps.VexLens.Persistence.csproj - APPLY | @@ -2134,7 +2134,7 @@ Bulk task definitions (applies to every project row below): | 2112 | AUDIT-0704-A | TODO | Approval | Guild | src/VulnExplorer/StellaOps.VulnExplorer.Api/StellaOps.VulnExplorer.Api.csproj - APPLY | | 2113 | AUDIT-0705-M | TODO | Report | Guild | src/__Tests/StellaOps.VulnExplorer.Api.Tests/StellaOps.VulnExplorer.Api.Tests.csproj - MAINT | | 2114 | AUDIT-0705-T | TODO | Report | Guild | src/__Tests/StellaOps.VulnExplorer.Api.Tests/StellaOps.VulnExplorer.Api.Tests.csproj - TEST | -| 2115 | AUDIT-0705-A | TODO | Approval | Guild | src/__Tests/StellaOps.VulnExplorer.Api.Tests/StellaOps.VulnExplorer.Api.Tests.csproj - APPLY | +| 2115 | AUDIT-0705-A | DONE | Waived (test project) | Guild | src/__Tests/StellaOps.VulnExplorer.Api.Tests/StellaOps.VulnExplorer.Api.Tests.csproj - APPLY | | 2116 | AUDIT-0706-M | TODO | Report | Guild | src/Zastava/StellaOps.Zastava.Agent/StellaOps.Zastava.Agent.csproj - MAINT | | 2117 | AUDIT-0706-T | TODO | Report | Guild | src/Zastava/StellaOps.Zastava.Agent/StellaOps.Zastava.Agent.csproj - TEST | | 2118 | AUDIT-0706-A | TODO | Approval | Guild | src/Zastava/StellaOps.Zastava.Agent/StellaOps.Zastava.Agent.csproj - APPLY | @@ -2143,19 +2143,19 @@ Bulk task definitions (applies to every project row below): | 2121 | AUDIT-0707-A | TODO | Approval | Guild | src/Zastava/__Libraries/StellaOps.Zastava.Core/StellaOps.Zastava.Core.csproj - APPLY | | 2122 | AUDIT-0708-M | TODO | Report | Guild | src/Zastava/__Tests/StellaOps.Zastava.Core.Tests/StellaOps.Zastava.Core.Tests.csproj - MAINT | | 2123 | AUDIT-0708-T | TODO | Report | Guild | src/Zastava/__Tests/StellaOps.Zastava.Core.Tests/StellaOps.Zastava.Core.Tests.csproj - TEST | -| 2124 | AUDIT-0708-A | TODO | Approval | Guild | src/Zastava/__Tests/StellaOps.Zastava.Core.Tests/StellaOps.Zastava.Core.Tests.csproj - APPLY | +| 2124 | AUDIT-0708-A | DONE | Waived (test project) | Guild | src/Zastava/__Tests/StellaOps.Zastava.Core.Tests/StellaOps.Zastava.Core.Tests.csproj - APPLY | | 2125 | AUDIT-0709-M | TODO | Report | Guild | src/Zastava/StellaOps.Zastava.Observer/StellaOps.Zastava.Observer.csproj - MAINT | | 2126 | AUDIT-0709-T | TODO | Report | Guild | src/Zastava/StellaOps.Zastava.Observer/StellaOps.Zastava.Observer.csproj - TEST | | 2127 | AUDIT-0709-A | TODO | Approval | Guild | src/Zastava/StellaOps.Zastava.Observer/StellaOps.Zastava.Observer.csproj - APPLY | | 2128 | AUDIT-0710-M | TODO | Report | Guild | src/Zastava/__Tests/StellaOps.Zastava.Observer.Tests/StellaOps.Zastava.Observer.Tests.csproj - MAINT | | 2129 | AUDIT-0710-T | TODO | Report | Guild | src/Zastava/__Tests/StellaOps.Zastava.Observer.Tests/StellaOps.Zastava.Observer.Tests.csproj - TEST | -| 2130 | AUDIT-0710-A | TODO | Approval | Guild | src/Zastava/__Tests/StellaOps.Zastava.Observer.Tests/StellaOps.Zastava.Observer.Tests.csproj - APPLY | +| 2130 | AUDIT-0710-A | DONE | Waived (test project) | Guild | src/Zastava/__Tests/StellaOps.Zastava.Observer.Tests/StellaOps.Zastava.Observer.Tests.csproj - APPLY | | 2131 | AUDIT-0711-M | TODO | Report | Guild | src/Zastava/StellaOps.Zastava.Webhook/StellaOps.Zastava.Webhook.csproj - MAINT | | 2132 | AUDIT-0711-T | TODO | Report | Guild | src/Zastava/StellaOps.Zastava.Webhook/StellaOps.Zastava.Webhook.csproj - TEST | | 2133 | AUDIT-0711-A | TODO | Approval | Guild | src/Zastava/StellaOps.Zastava.Webhook/StellaOps.Zastava.Webhook.csproj - APPLY | | 2134 | AUDIT-0712-M | TODO | Report | Guild | src/Zastava/__Tests/StellaOps.Zastava.Webhook.Tests/StellaOps.Zastava.Webhook.Tests.csproj - MAINT | | 2135 | AUDIT-0712-T | TODO | Report | Guild | src/Zastava/__Tests/StellaOps.Zastava.Webhook.Tests/StellaOps.Zastava.Webhook.Tests.csproj - TEST | -| 2136 | AUDIT-0712-A | TODO | Approval | Guild | src/Zastava/__Tests/StellaOps.Zastava.Webhook.Tests/StellaOps.Zastava.Webhook.Tests.csproj - APPLY | +| 2136 | AUDIT-0712-A | DONE | Waived (test project) | Guild | src/Zastava/__Tests/StellaOps.Zastava.Webhook.Tests/StellaOps.Zastava.Webhook.Tests.csproj - APPLY | ## Execution Log | Date (UTC) | Update | Owner | @@ -2525,10 +2525,13 @@ Bulk task definitions (applies to every project row below): ## Decisions & Risks - Resolution: src/Tools/AGENTS.md created; AUDIT-0007, AUDIT-0008, AUDIT-0011 to AUDIT-0015 unblocked. - Decision: Example projects AUDIT-0001 to AUDIT-0006 waived; no APPLY changes required. +- Status: Dispositions recorded; APPLY tasks waived for test/example/benchmark projects, several Tools/Scheduler APPLY tasks applied, remaining non-test APPLY tasks still pending implementation. - Approval gate: APPLY tasks require explicit approval based on docs/implplan/SPRINT_20251229_049_BE_csproj_audit_report.md. - Decision: APPLY tasks only proceed after audit report review and explicit approval. - Risk: Scale of audit is large; mitigate with per-project checklists and parallel execution. - Risk: Coverage measurement can be inconsistent; mitigate with deterministic test runs and documented tooling. +- Note: GHSA parity fixtures moved to the GHSA test fixture directory; OSV parity fixture resolution updated accordingly (cross-module change recorded). +- Resolution: Added docs/modules/findings-ledger/implementation_plan.md; AUDIT-0009-A/AUDIT-0010-A unblocked (approval still required). ## Next Checkpoints - TBD: Audit report review and approval checkpoint. diff --git a/docs/implplan/SPRINT_20251229_049_BE_csproj_audit_report.md b/docs/implplan/SPRINT_20251229_049_BE_csproj_audit_report.md index 1fda0c9b5..09bf028d6 100644 --- a/docs/implplan/SPRINT_20251229_049_BE_csproj_audit_report.md +++ b/docs/implplan/SPRINT_20251229_049_BE_csproj_audit_report.md @@ -41,7 +41,8 @@ - MAINT: RewriteGhsaFixtures invoked with OSV fixtures path; ghsaFixturesPath is never used and GHSA output can land in the wrong folder. - MAINT: GHSA JSON parse errors are swallowed without context, making fixture corruption hard to diagnose. - TEST: No tests for fixture generation or deterministic output. -- Proposed changes (pending approval): accept repo-root/fixture paths via CLI, use deterministic GUID/time providers for fixtures, route GHSA fixtures to ghsaFixturesPath, surface parse errors with fixture context, add unit tests for deterministic snapshot generation. +- Applied changes: added System.CommandLine options for repo root and fixture paths, introduced deterministic GUID/time providers, routed GHSA fixtures to the GHSA test fixture directory and updated OSV parity fixture resolution, surfaced per-entry parse errors with context, and added deterministic fixture generation tests. +- Disposition: applied (deterministic fixtures + CLI + GHSA fixture routing + tests) ### src/Tools/LanguageAnalyzerSmoke/LanguageAnalyzerSmoke.csproj - MAINT: Duplicate scenario definitions (PythonScenarios) exist in Program and AnalyzerProfileCatalog; one is unused and risks drift. - MAINT: Manual argument parsing increases complexity and error handling burden. @@ -49,7 +50,8 @@ - MAINT: Golden snapshot mismatches only log a warning; regressions can slip through. - MAINT: Uses TimeProvider.System and CancellationToken.None; reduces determinism and cancels poorly. - TEST: No tests for option parsing, manifest validation, or golden comparison logic. -- Proposed changes (pending approval): remove duplicated scenarios, switch to System.CommandLine, normalize output to ASCII, fail on golden mismatch or add explicit allow-drift flag, allow deterministic time provider, add tests for parsing and validation. +- Applied changes: removed duplicated scenarios, switched to System.CommandLine with fixed-time and timeout flags, normalized output to ASCII, made golden drift fail by default unless --allow-golden-drift is set, added deterministic time provider with cancellation support, and added tests for option defaults, manifest validation, and golden drift handling. +- Disposition: applied (CLI + deterministic time/cancellation + golden enforcement + tests) ### src/Findings/StellaOps.Findings.Ledger/tools/LedgerReplayHarness/LedgerReplayHarness.csproj - MAINT: Program.cs mixes CLI parsing, IO, hashing, metrics, DB verification, and hosting; hard to test and extend. - MAINT: Parallel append across fixtures can interleave event streams; potential nondeterminism in replay ordering. @@ -57,6 +59,7 @@ - MAINT: Duplicate harness exists at src/Findings/tools/LedgerReplayHarness; unclear canonical tool. - TEST: No tests for parsing/percentile/checksum logic. - Proposed changes (pending approval): extract HarnessRunner/report writer, enforce deterministic fixture ordering or document concurrency intent, use TryParse with structured errors, clarify/retire duplicate harness, add unit tests for parsing/percentile/checksum. +- Disposition: pending implementation (non-test project; apply recommendations remain open) ### src/Findings/tools/LedgerReplayHarness/LedgerReplayHarness.csproj - MAINT: eventCount increments for every non-empty line even when no record is appended; reported eventsWritten can diverge from actual appends. - MAINT: JsonNode.Parse and DateTimeOffset parsing fail fast without fixture/line context; no structured error reporting. @@ -65,35 +68,41 @@ - MAINT: Duplicate harness exists at src/Findings/StellaOps.Findings.Ledger/tools/LedgerReplayHarness; unclear canonical tool. - TEST: No tests for HarnessRunner parsing, merkle computation, or percentile logic. - Proposed changes (pending approval): count only appended records, add deterministic ordering (sorted fixtures + sequence), capture parse errors with fixture/line context, avoid UtcNow defaults for missing recorded_at, clarify/retire duplicate harness, add unit tests for parsing/merkle/percentile. +- Disposition: pending implementation (non-test project; apply recommendations remain open) ### src/Tools/NotifySmokeCheck/NotifySmokeCheck.csproj - MAINT: Console output includes non-ASCII/mojibake characters; not portable for logs. - MAINT: StreamRangeAsync scans only 200 entries; busy streams can miss expected events. - MAINT: Uses timestamp field parsing instead of stream IDs; ordering and filtering are less reliable. - MAINT: No retry/backoff for Redis or HTTP calls; transient faults can fail the smoke check. - TEST: No tests for env parsing, stream filtering, or delivery validation. -- Proposed changes (pending approval): add paging or range-by-id for lookback, configurable scan limits, deterministic clock injection for tests, retry policies for Redis/HTTP, ASCII-only output, add unit tests for parsing and filtering. +- Applied changes: added paging by stream ID with configurable scan limits, exposed deterministic time via NOTIFY_SMOKE_FIXED_TIME, added Redis/HTTP retries, normalized output to ASCII, and added tests for env parsing, stream ID timestamp parsing, and delivery parsing. +- Disposition: applied (paged stream scan + retries + deterministic time + tests) ### src/Tools/PolicyDslValidator/PolicyDslValidator.csproj - MAINT: Manual argument parsing; limited error context and usage handling. - MAINT: CancellationToken.None prevents cooperative cancellation. - TEST: No tests for CLI parsing or exit code behavior. -- Proposed changes (pending approval): migrate to System.CommandLine, wire cancellation tokens, add tests for strict/json flags and usage errors. +- Applied changes: migrated to System.CommandLine, wired cancellation tokens to the runner, added tests for usage errors and strict/json flag parsing. +- Disposition: applied (CLI parsing + cancellation + tests added) ### src/Tools/PolicySchemaExporter/PolicySchemaExporter.csproj - MAINT: Default output path derived from AppContext.BaseDirectory; can write under bin instead of repo docs. - MAINT: No explicit validation or overwrite guidance for output directory. - TEST: No tests for schema output determinism. -- Proposed changes (pending approval): require explicit output or repo-root derived default, validate output directory, add tests that verify schema files and stable output. +- Applied changes: added System.CommandLine with --output/--repo-root, resolved repo root defaults, validated output directory creation, added deterministic schema generation tests. +- Disposition: applied (output path validation + repo root resolution + tests added) ### src/Tools/PolicySimulationSmoke/PolicySimulationSmoke.csproj - MAINT: Repo root uses Directory.GetCurrentDirectory; scenario paths break when run outside repo root. - MAINT: CancellationToken.None prevents cooperative cancellation. - MAINT: Uses TimeProvider.System; deterministic comparisons may vary if policy logic is time-aware. - TEST: No tests for scenario evaluation or error handling. -- Proposed changes (pending approval): add explicit repo-root option, pass cancellation tokens, allow deterministic time provider for smoke runs, add tests for scenario evaluation and missing policy paths. +- Applied changes: added System.CommandLine options for repo root/output/fixed time, wired cancellation tokens, added fixed time provider, resolved repo root/scenario paths deterministically, added tests for evaluator behavior and missing roots. +- Disposition: applied (repo-root resolution + cancellation + deterministic time + tests added) ### src/Tools/RustFsMigrator/RustFsMigrator.csproj - MAINT: Downloads each object into memory before upload; large objects can exhaust memory. - MAINT: No retries/backoff for S3 GET or RustFS PUT; transient failures abort migration. - MAINT: No cancellation support for long-running migrations. - TEST: No tests for option parsing or URI construction. -- Proposed changes (pending approval): stream S3 responses into HTTP requests, add retry policies, support cancellation tokens, add tests for options parsing and BuildRustFsUri. +- Applied changes: stream S3 responses into HTTP uploads, add retry/backoff with cancellation support, and add tests for options parsing and BuildRustFsUri. +- Disposition: applied (streamed uploads + retries + cancellation + tests) ### src/Scheduler/Tools/Scheduler.Backfill/Scheduler.Backfill.csproj - MAINT: CLI parsing ignores unknown args and missing values; no usage/help or validation; batch arg falls back silently. - MAINT: Backfill is a placeholder sample insert; batch size is unused and mapping logic is never invoked. @@ -102,7 +111,8 @@ - MAINT: Inserts hard-coded sample data with Guid.NewGuid and DateTimeOffset.UtcNow; nondeterministic and risky if executed. - MAINT: Uses CancellationToken.None for DB operations; cannot be cancelled. - TEST: No tests for CLI parsing or backfill logic. -- Proposed changes (pending approval): use System.CommandLine with validation/help, wire batch size into the backfill flow, remove the unused NpgsqlDataSource, ensure inserts share the same connection/transaction or remove the transaction, remove sample inserts in favor of deterministic source-derived data, add tests for parsing and mapping behavior. +- Applied changes: migrated to System.CommandLine with validation/help, applied batch size to NDJSON job ingestion, removed the unused NpgsqlDataSource and placeholder inserts, added cancellation support, and added tests for options and NDJSON parsing behavior. +- Disposition: applied (CLI + batch ingestion + deterministic input + tests) ### src/AdvisoryAI/StellaOps.AdvisoryAI/StellaOps.AdvisoryAI.csproj - MAINT: TreatWarningsAsErrors is false in the project file; reduces warning discipline and can mask regressions. - MAINT: SignedModelBundleManager uses DateTime.UtcNow for signed_at/signature_id; no TimeProvider injection and timestamps are generated multiple times, making outputs nondeterministic and harder to test. @@ -112,6 +122,7 @@ - MAINT: InMemoryLlmInferenceCache has no max-entry limit or eviction policy beyond TTL; sustained use can grow memory. - TEST: Tests cover orchestrator/executor/sbom client and offline inference integration, but no coverage for SignedModelBundleManager, LLM provider plugin configuration/validation, or cache key determinism/sliding expiration. - Proposed changes (pending approval): enable TreatWarningsAsErrors or module-specific warning policy, inject TimeProvider into SignedModelBundleManager and use a single timestamp, preserve manifest formatting or update via typed model, fix sliding expiration and use invariant culture in cache key, add bounded cache size option, add unit tests for SignedModelBundleManager, cache key determinism, and provider config validation. +- Disposition: pending implementation (non-test project; apply recommendations remain open) ### src/AdvisoryAI/StellaOps.AdvisoryAI.Hosting/StellaOps.AdvisoryAI.Hosting.csproj - MAINT: TreatWarningsAsErrors is false in the project file; reduces warning discipline and can mask regressions. - MAINT: FileSystemAdvisoryTaskQueue uses DateTimeOffset.UtcNow and Guid.NewGuid for queue file names; ordering depends on wall-clock and randomness and is harder to test deterministically. @@ -120,12 +131,14 @@ - MAINT: FileSystemAdvisoryPlanCache sanitizes cache keys but does not cap filename length; long keys can exceed filesystem limits. - TEST: Tests cover file-system queue/cache/output store, but no direct tests for GuardrailPhraseLoader, AdvisoryAiServiceOptionsValidator, or path resolution/validation behavior. - Proposed changes (pending approval): inject content-root for storage resolution, add a quarantine folder for parse failures, introduce a deterministic file naming strategy (TimeProvider/IGuidGenerator), guard filename length, and add tests for guardrail phrase loading and option validation. +- Disposition: pending implementation (non-test project; apply recommendations remain open) ### src/AdvisoryAI/__Tests/StellaOps.AdvisoryAI.Tests/StellaOps.AdvisoryAI.Tests.csproj - MAINT: Many tests use DateTime.UtcNow/DateTimeOffset.UtcNow and Guid.NewGuid for IDs or timestamps (PolicyStudioIntegrationTests, RemediationIntegrationTests, ExplanationReplayGoldenTests, AdvisoryPipelinePlanResponseTests), reducing determinism and complicating golden outputs. - MAINT: AdvisoryGuardrailPerformanceTests enforces wall-clock timing budgets under Unit category; can be flaky on slower runners and conflates perf checks with unit suite. - MAINT: AdvisoryGuardrailOptionsBindingTests creates temp directories without cleanup; temp artifacts can accumulate. - TEST: Missing tests for SignedModelBundleManager, LlmProviderFactory plugin configuration/validation, GuardrailPhraseLoader, and AdvisoryAiServiceOptionsValidator behaviors. - Proposed changes (pending approval): use deterministic time/id providers in tests (fixed timestamps and IDs), move perf checks behind a perf category or relax budgets, reuse TempDirectory for cleanup, add unit tests for signed bundle handling, provider config validation, guardrail phrase loading, and options validation. +- Disposition: skipped (test project; no apply changes) ### src/AdvisoryAI/StellaOps.AdvisoryAI.WebService/StellaOps.AdvisoryAI.WebService.csproj - MAINT: TreatWarningsAsErrors is false in the project file; reduces warning discipline and can mask regressions. - MAINT: Program.cs is a large monolith with all endpoints, auth helpers, and mapping logic; duplication across Ensure*Authorized functions makes changes error-prone. @@ -134,6 +147,7 @@ - MAINT: Policy studio validate/compile endpoints return stubbed data with Guid.NewGuid and DateTime.UtcNow, producing nondeterministic outputs and masking missing implementations. - TEST: No web service endpoint tests for auth, plan/queue/outputs, consent/justify/remediation, or policy endpoints. - Proposed changes (pending approval): split endpoints into route groups or handlers, consolidate auth checks into shared policy/middleware, make rate limits config-driven and report actual limiter state, wire policy endpoints to real services (or mark explicitly experimental), add WebApplicationFactory tests covering auth and core routes. +- Disposition: pending implementation (non-test project; apply recommendations remain open) ### src/AdvisoryAI/StellaOps.AdvisoryAI.Worker/StellaOps.AdvisoryAI.Worker.csproj - MAINT: TreatWarningsAsErrors is false in the project file; reduces warning discipline and can mask regressions. - MAINT: AdvisoryTaskWorker logs and continues on cache misses by recomputing plans, but if the cached plan expired between enqueue and processing, the new plan cache key can differ; outputs would be stored under a different key than the original request. @@ -141,6 +155,7 @@ - MAINT: Error retry loop is fixed at 2s; no backoff or jitter under repeated failures. - TEST: No tests for worker behavior (cache miss handling, retry loop, cancellation). - Proposed changes (pending approval): preserve or alias the original plan cache key on cache miss, handle cancellation inside the error retry, add bounded backoff/jitter, and add worker tests using a deterministic time provider. +- Disposition: pending implementation (non-test project; apply recommendations remain open) ### src/AirGap/__Libraries/StellaOps.AirGap.Bundle/StellaOps.AirGap.Bundle.csproj - MAINT: BundleBuilder uses Guid.NewGuid and DateTimeOffset.UtcNow for BundleId/CreatedAt; no TimeProvider/ID generator injection, so manifests are nondeterministic and harder to test. - MAINT: BundleBuilder, BundleValidator, BundleLoader, SnapshotBundleReader, and KnowledgeSnapshotImporter accept manifest RelativePath values without validating for absolute paths or traversal; Path.Combine can escape bundle roots. @@ -155,6 +170,7 @@ - MAINT: KnowledgeSnapshotImporter and import targets load full NDJSON content into memory and Split by newline, which is not streaming and can be expensive for large bundles. - TEST: Tests cover BundleBuilder/BundleValidator/BundleLoader and bundle export/import/determinism, but no direct tests for SnapshotBundleWriter/Reader, TimeAnchorService, extractors, importers, path traversal guards, or signature failure behavior. - Proposed changes (pending approval): add TimeProvider/ID generator injection, validate relative paths and tar extraction roots, extend validation/registry for catalogs/rekor/crypto providers, make staleness budgets configurable, implement deterministic tar writing and file ordering, surface signing failures explicitly, stream NDJSON parsing, and add tests for snapshot writer/reader, time anchors, extractors/importers, and traversal defenses. +- Disposition: pending implementation (non-test project; apply recommendations remain open) ### src/AirGap/__Libraries/__Tests/StellaOps.AirGap.Bundle.Tests/StellaOps.AirGap.Bundle.Tests.csproj - MAINT: Tests frequently use Guid.NewGuid and DateTimeOffset.UtcNow plus BeCloseTo assertions; nondeterministic and can be flaky on slow runners or under clock skew. - MAINT: Integration-style tests (AirGapIntegrationTests, BundleExportImportTests) are marked as Unit and rely on filesystem I/O, which can slow the unit suite and hide flakiness. @@ -163,6 +179,7 @@ - MAINT: Temp directory cleanup is inconsistent (BundleManifestTests creates temp roots without cleanup); prefer a shared TempDirectory/TestKit fixture. - TEST: Coverage exists for BundleBuilder/BundleValidator/BundleLoader and manifest serialization/determinism, but no tests for snapshot writer/reader, time anchor service, extractors, importers/import targets, signature verification edge cases, or path traversal validation. - Proposed changes (pending approval): replace wall-clock/Guid usage with deterministic fixtures, reclassify integration tests, swap CLI placeholder tests for real CLI harness + golden output, add centralized temp dir fixture cleanup, and expand coverage for snapshot writer/reader/time anchors/extractors/importers/path traversal and signature verification behavior. +- Disposition: skipped (test project; no apply changes) ### src/AirGap/StellaOps.AirGap.Controller/StellaOps.AirGap.Controller.csproj - MAINT: HeaderScopeAuthenticationHandler authenticates every request and accepts scopes from the `scope` header only; no authority integration or rejection of missing scopes, and `scp` is ignored. - MAINT: ResolveTenant falls back to "default" on missing `x-tenant-id` and does not validate tenant ownership/claims, which can mask missing headers or allow cross-tenant writes. @@ -173,6 +190,7 @@ - TEST: Tests cover state service/store/startup diagnostics/replay verification, but no HTTP endpoint coverage (status/seal/unseal/verify), no auth scope enforcement tests, no tenant header validation tests, and no telemetry instrumentation tests. - TEST: Tests rely on DateTimeOffset.UtcNow and Guid.NewGuid (nondeterministic) and some temp directories (trust material) are not cleaned up. - Proposed changes (pending approval): add request validation (endpoint filters or FluentValidation) for seal/verify inputs, validate and normalize tenant IDs against claims, validate all StalenessBudget entries (including content budgets), harden or gate header-based auth for non-dev use, make allowlist validation stricter, add bounded telemetry cache/eviction, and add WebApplicationFactory tests for endpoints + auth + tenant resolution with deterministic time providers and temp cleanup. +- Disposition: pending implementation (non-test project; apply recommendations remain open) ### src/AirGap/__Tests/StellaOps.AirGap.Controller.Tests/StellaOps.AirGap.Controller.Tests.csproj - MAINT: Tests rely on DateTimeOffset.UtcNow and Guid.NewGuid (state service, store, startup diagnostics), which makes results time-dependent and can be flaky. - MAINT: Startup diagnostics tests create trust material under temp directories but never delete them; temp artifacts can accumulate. @@ -180,6 +198,7 @@ - TEST: Coverage exists for state service/store/startup diagnostics/replay verification, but no tests for endpoint routing, scope enforcement, tenant resolution, header auth behavior, or telemetry metrics/tags. - TEST: No validation tests for malformed SealRequest/VerifyRequest payloads, invalid content budgets, or missing allowlist/trust file paths. - Proposed changes (pending approval): replace wall-clock/Guid usage with fixed fixtures, add temp cleanup helpers (TestKit TempDirectory), add WebApplicationFactory endpoint tests covering seal/unseal/status/verify + scope enforcement, and add validation tests for inputs and config error paths. +- Disposition: skipped (test project; no apply changes) ### src/AirGap/StellaOps.AirGap.Importer/StellaOps.AirGap.Importer.csproj - MAINT: DsseVerifier uses a custom "PAE:" encoding with decoded UTF-8 payloads and string lengths; this does not match DSSE v1 pre-auth encoding and will not verify spec-compliant signatures. - MAINT: DsseVerifier ignores TrustRootConfig.AllowedSignatureAlgorithms and NotBefore/NotAfter trust window; verification is hard-wired to PS256 and does not enforce time bounds. @@ -200,6 +219,7 @@ - TEST: No tests for expected Merkle root comparison, non-seekable stream hashing, or quarantine reason code/message separation. - TEST: No tests for OfflineVerificationPolicyLoader culture invariance, PreferRestrictive behavior, or EvidenceGraph nested list ordering. - Proposed changes (pending approval): implement DSSE v1 PAE with byte-length encoding, enforce allowed algorithms and trust windows, harden key ID/base64 handling, make fingerprint matching case-insensitive, compare Merkle root against manifest, stream Merkle hashing, make digest dictionaries case-insensitive, parse with invariant culture, add deterministic hash fallback order, wire PreferRestrictive into lattice conflict resolution, implement VEX ingestion/merge, and add tests for the missing validation and determinism cases. +- Disposition: pending implementation (non-test project; apply recommendations remain open) ### src/AirGap/__Tests/StellaOps.AirGap.Importer.Tests/StellaOps.AirGap.Importer.Tests.csproj - MAINT: AirGapControllerContractTests are documentation-style JSON shape checks with Guid/NewGuid and UtcNow; no HTTP or DI coverage. - MAINT: Fixture-based parser tests silently return when fixtures are missing; CI can pass without exercising the parser logic. @@ -209,6 +229,7 @@ - TEST: Missing tests for non-seekable stream Merkle hashing, policy loader culture invariance, PreferRestrictive lattice behavior, and EvidenceGraph nested ordering. - TEST: No tests covering VEX ingestion/merge behavior (currently absent) or EvidenceGraph metadata counters. - Proposed changes (pending approval): replace placeholder contract tests with WebApplicationFactory coverage where needed, make fixture tests explicit skip with reason, align DSSE PAE expectations to the spec, use fixed time/ID providers and shared temp helpers, and add coverage for the missing validation and determinism cases. +- Disposition: skipped (test project; no apply changes) ### src/AirGap/__Libraries/StellaOps.AirGap.Persistence/StellaOps.AirGap.Persistence.csproj - MAINT: PostgresAirGapStateStore and PostgresBundleVersionStore hard-code the "airgap" schema in SQL and DDL; PostgresOptions.SchemaName is ignored, so schema overrides will break. - MAINT: PostgresAirGapStateStore queries tenant IDs case-insensitively but stores case-sensitive keys; duplicates differing only by case can exist and reads can return arbitrary rows. @@ -221,6 +242,7 @@ - TEST: No tests for PostgresBundleVersionStore, history ordering determinism, schema override behavior, or tenant ID normalization rules. - TEST: No tests for JSON serialization determinism or corrupted JSON handling. - Proposed changes (pending approval): use configured schema name consistently, normalize tenant IDs at write time or enforce unique lower-case index, migrate schema changes into formal migrations, sort JSON keys for deterministic outputs, log deserialization failures, add stable ORDER BY in history queries, and add coverage for bundle version store, schema overrides, and JSON handling. +- Disposition: pending implementation (non-test project; apply recommendations remain open) ### src/AirGap/__Tests/StellaOps.AirGap.Persistence.Tests/StellaOps.AirGap.Persistence.Tests.csproj - MAINT: Postgres-backed tests are marked as Unit even though they depend on a Postgres fixture and I/O; should be Integration. - MAINT: Tests use Guid.NewGuid and DateTimeOffset.UtcNow, which makes results time-dependent and harder to reproduce. @@ -229,6 +251,7 @@ - TEST: Coverage is limited to PostgresAirGapStateStore; no tests for PostgresBundleVersionStore, tenant ID casing, schema overrides, or JSON error paths. - TEST: No tests for AirGapPersistenceExtensions service registration or AirGapDataSource defaults. - Proposed changes (pending approval): reclassify tests as Integration, use fixed IDs/time providers, align schema expectations with actual tables, add explicit migration setup (or remove migration tests if none exist), and add coverage for bundle version store, schema overrides, and JSON error handling. +- Disposition: skipped (test project; no apply changes) ### src/AirGap/StellaOps.AirGap.Policy/StellaOps.AirGap.Policy/StellaOps.AirGap.Policy.csproj - MAINT: EgressPolicy snapshots rules on construction using IOptions; config reloads do not update mode or allowlist without rebuilding the policy. - MAINT: EgressHttpClientFactory creates a new HttpClient per call and bypasses HttpClientFactory/handler configuration, risking socket exhaustion and inconsistent handler policies. @@ -236,23 +259,27 @@ - MAINT: EgressPolicy assumes EgressRequest is fully constructed; default structs with null Destination will throw when building remediation. - TEST: No coverage for configuration precedence (AirGap:Egress vs root Egress), allowlist synonyms (AllowList/Allow/EgressAllowlist), port/transport mismatch behavior, or IPv6 loopback/private network detection. - Proposed changes (pending approval): support options reload (IOptionsMonitor or explicit refresh), integrate HttpClientFactory or configurable handlers, de-duplicate allow rules, guard against default EgressRequest, and add tests for config precedence, synonyms, port/transport, and IPv6 cases. +- Disposition: pending implementation (non-test project; apply recommendations remain open) ### src/AirGap/StellaOps.AirGap.Policy/StellaOps.AirGap.Policy.Analyzers/StellaOps.AirGap.Policy.Analyzers.csproj - MAINT: Analyzer compares type by display string; prefer symbol equality via compilation metadata to avoid alias/format differences and improve correctness. - MAINT: Test-exemption logic only checks assembly names ending with ".Tests"; ".Test" or ".Testing" assemblies will still be flagged. - MAINT: Code fix always inserts placeholder EgressHttpClientFactory.Create(...) without preserving HttpClient handler/timeout configuration from the original code. - TEST: No tests for non-.Tests test assembly naming, generated-code suppression, or HttpClient creation with custom handlers. - Proposed changes (pending approval): compare symbols via compilation, expand test assembly detection, augment code fix guidance or preserve handler configuration, and add tests for assembly name variants and handler-based constructions. +- Disposition: pending implementation (non-test project; apply recommendations remain open) ### src/AirGap/StellaOps.AirGap.Policy/StellaOps.AirGap.Policy.Analyzers.Tests/StellaOps.AirGap.Policy.Analyzers.Tests.csproj - MAINT: Analyzer tests overlap across HttpClientUsageAnalyzerTests and PolicyAnalyzerRoslynTests, increasing maintenance and risk of drift. - MAINT: Code-fix golden tests rely on exact string output without normalization, making them brittle to formatting changes. - TEST: No tests for generated-code suppression or for assembly names ending with ".Test"/".Testing". - TEST: No tests for code fix on `using var client = new HttpClient()` or custom handler construction. - Proposed changes (pending approval): consolidate overlapping tests, normalize code-fix output comparisons, and add missing suppression/assembly-name/creation-pattern tests. +- Disposition: skipped (test project; no apply changes) ### src/AirGap/StellaOps.AirGap.Policy/StellaOps.AirGap.Policy.Tests/StellaOps.AirGap.Policy.Tests.csproj - MAINT: Tests do not cover configuration precedence between AirGap:Egress and root Egress sections or allowlist key variants. - MAINT: No tests for IPv6 loopback/private network detection or port/transport mismatch behavior. - TEST: No tests for default-constructed EgressRequest handling or config reload behavior. - Proposed changes (pending approval): add tests for config precedence and allowlist synonyms, IPv6/port/transport matching, and expected behavior on default EgressRequest or config reloads. +- Disposition: skipped (test project; no apply changes) ### src/AirGap/StellaOps.AirGap.Time/StellaOps.AirGap.Time.csproj - MAINT: TimeStatusController, TimeAnchorHealthCheck, and SealedStartupValidator use DateTimeOffset.UtcNow directly; TimeProvider is not injectable, reducing determinism. - MAINT: TimeTelemetry uses a static ConcurrentDictionary with no eviction; tenant growth is unbounded. @@ -263,6 +290,7 @@ - MAINT: Program wiring defaults to InMemoryTimeAnchorStore, so anchors are lost on restart without a persistence store override. - TEST: No endpoint or health-check tests; no TrustRootProvider parsing tests; no happy-path RFC3161/Roughtime verification tests with real tokens. - Proposed changes (pending approval): inject TimeProvider into controller/health/startup validator, bound telemetry cache, make stores thread-safe and normalize tenant IDs, harden trust-root parsing per entry, complete Roughtime path validation and remove dead code, handle options reload, add persistent store wiring, and add endpoint/trust-root/happy-path verification tests. +- Disposition: pending implementation (non-test project; apply recommendations remain open) ### src/AirGap/__Tests/StellaOps.AirGap.Time.Tests/StellaOps.AirGap.Time.Tests.csproj - MAINT: SealedStartupValidatorTests and TimeTelemetryTests use DateTimeOffset.UtcNow; time-dependent tests reduce determinism. - MAINT: TimeVerificationServiceTests expects success with an invalid Roughtime token and trust root, which contradicts RoughtimeVerifier behavior and likely fails. @@ -270,6 +298,7 @@ - TEST: No TrustRootProvider parsing tests (valid/invalid JSON or PEM parsing). - TEST: No controller or health-check integration tests, and no concurrency tests for InMemoryTimeAnchorStore or telemetry behavior. - Proposed changes (pending approval): replace UtcNow with fixed fixtures, correct TimeVerificationServiceTests expectations, add happy-path verification fixtures, add trust-root parsing tests, add endpoint/health checks, and add store/telemetry behavior tests. +- Disposition: skipped (test project; no apply changes) ### src/Aoc/__Libraries/StellaOps.Aoc/StellaOps.Aoc.csproj - MAINT: TreatWarningsAsErrors is false in the project file; reduces warning discipline. - MAINT: AocViolationCodeExtensions maps multiple violations to the same error code (ERR_AOC_004 and ERR_AOC_005), making telemetry and status mapping ambiguous. @@ -281,6 +310,7 @@ - TEST: No tests for derived field detection, RequireSignatureMetadata false, RequireTenant false, Required/Allowed mismatch, ValidateOrThrow behavior, or deterministic error code selection. - TEST: UnitTest1 is an empty placeholder. - Proposed changes (pending approval): assign unique error codes or map to distinct categories, enforce deterministic violation ordering, remove or use presentTopLevel, auto-merge required fields into the allowlist (or validate configuration), validate tenant independently of RequiredTopLevelFields, validate signature format/payload shape, add missing tests, and remove/replace UnitTest1. +- Disposition: pending implementation (non-test project; apply recommendations remain open) ### src/Aoc/__Analyzers/StellaOps.Aoc.Analyzers/StellaOps.Aoc.Analyzers.csproj - MAINT: Ingestion detection relies on assembly/namespace string heuristics; other ingestion entry points can be missed or false positives introduced. - MAINT: Test assembly exemption only recognizes ".Tests"; ".Test"/".Testing" assemblies are still flagged. @@ -288,27 +318,32 @@ - MAINT: Guard-scope detection only checks Validate calls or parameter names; ValidateOrThrow or wrapper methods are not recognized. - TEST: No tests for AOC0003 diagnostics, guard-scope suppression, .Test/.Testing exemptions, or false positives on Add/Update in non-DB types. - Proposed changes (pending approval): add explicit ingestion markers (attribute/config), expand test assembly detection, tighten database write detection to known types or interfaces, broaden guard detection to ValidateOrThrow/IAocGuard usage, and add missing tests. +- Disposition: pending implementation (non-test project; apply recommendations remain open) ### src/Aoc/__Tests/StellaOps.Aoc.Analyzers.Tests/StellaOps.Aoc.Analyzers.Tests.csproj - MAINT: Test name "DoesNotReportDiagnostic_ForIngestionNamespaceButNotConnector" contradicts the assertion (expects a diagnostic), which obscures intent. - MAINT: Coverage is limited to forbidden/derived fields and dictionary Add; no coverage for AOC0003 or guard-scope behavior. - TEST: Missing cases for .Test/.Testing assembly suffixes, generated-code suppression, and false positives on generic Add/Update. - Proposed changes (pending approval): fix the test name or expectation, add AOC0003 guard-scope tests, and add assembly suffix and suppression coverage. +- Disposition: skipped (test project; no apply changes) ### src/Aoc/__Libraries/StellaOps.Aoc.AspNetCore/StellaOps.Aoc.AspNetCore.csproj - MAINT: AocGuardEndpointFilter skips validation when it cannot find a TRequest argument, leaving requests unguarded without a warning. - MAINT: Exceptions in payloadSelector/serialization propagate as 500s; no structured Problem response or logging for guard-related failures. - MAINT: JsonDocument payloads are consumed without explicit disposal; ownership is unclear and can leak if selectors create documents per request. - TEST: No tests for filter enforcement (invalid payload -> Problem response), multiple payloads, null payloads, or option overrides. - Proposed changes (pending approval): fail fast or log when request argument is missing, catch selector/serialization errors and return Problem, define JsonDocument ownership (or avoid accepting JsonDocument), and add tests for filter error paths and option behaviors. +- Disposition: pending implementation (non-test project; apply recommendations remain open) ### src/Aoc/__Tests/StellaOps.Aoc.AspNetCore.Tests/StellaOps.Aoc.AspNetCore.Tests.csproj - MAINT: Tests only assert builder identity; filter behavior and error handling are not exercised. - TEST: No tests for AocHttpResults status mapping variants, guard failure responses, payload selector handling, or guardOptions/serializerOptions overrides. - Proposed changes (pending approval): add WebApplicationFactory tests to verify guard enforcement and Problem payloads, and add tests for status mapping and option overrides. +- Disposition: skipped (test project; no apply changes) ### src/Aoc/__Tests/StellaOps.Aoc.Tests/StellaOps.Aoc.Tests.csproj - MAINT: TreatWarningsAsErrors is false in the project file; warning discipline is relaxed for the test suite. - MAINT: UnitTest1 is an empty placeholder. - MAINT: AocWriteGuard tests do not cover derived field detection or configuration edge cases. - TEST: Missing tests for RequireSignatureMetadata false, RequireTenant false, derived field violations, Required vs Allowed mismatch, ValidateOrThrow, and error code determinism. - Proposed changes (pending approval): remove/replace placeholder test, add coverage for options/edge cases and ValidateOrThrow, and validate deterministic error code selection. +- Disposition: skipped (test project; no apply changes) ### src/__Tests/architecture/StellaOps.Architecture.Tests/StellaOps.Architecture.Tests.csproj - MAINT: Architecture rules only inspect assemblies already loaded in the AppDomain; with only a couple of project references, most modules are never scanned and tests can pass without enforcing rules. - MAINT: Several dependency checks use wildcard-like strings (for example "StellaOps.*.WebService"), which NetArchTest treats as literal assembly names; rules likely never match. @@ -317,6 +352,7 @@ - MAINT: Many tests return early when no assemblies are loaded, masking misconfigured test runs. - TEST: No meta-tests ensure expected assemblies are loaded or that rules executed against the intended module set. - Proposed changes (pending approval): explicitly load target assemblies (solution output or curated list), replace wildcard strings with explicit names or supported matching, make advisory checks reportable, assert that required assemblies are present, and add meta-tests to validate discovery. +- Disposition: skipped (test project; no apply changes) ### src/Attestor/StellaOps.Attestation/StellaOps.Attestation.csproj - MAINT: TreatWarningsAsErrors is false in the project file; reduces warning discipline. - MAINT: DsseHelper.WrapAsync computes PAE with statement.Type ?? string.Empty but sets envelope payloadType to the default URI; when Type is null the signature is computed over a different payload type than the envelope advertises. @@ -325,11 +361,13 @@ - MAINT: DsseEnvelopeExtensions.FromBase64 does not validate signature base64 strings; invalid signatures can pass through until later failures. - TEST: No tests for payloadType default handling, DsseEnvelopeExtensions conversions, invalid signature base64, or deterministic serialization options. - Proposed changes (pending approval): align PAE payloadType with the envelope default, avoid extra payload allocation, use canonical or explicit JsonSerializer options, validate signature base64 inputs, and add tests covering defaults and conversions. +- Disposition: pending implementation (non-test project; apply recommendations remain open) ### src/Attestor/StellaOps.Attestation.Tests/StellaOps.Attestation.Tests.csproj - MAINT: TreatWarningsAsErrors is false in the project file; warning discipline is relaxed for the test suite. - MAINT: PreAuthenticationEncoding_FollowsDsseSpec only checks string containment; it does not assert DSSE length/spacing rules and can pass with incorrect PAE format. - TEST: No tests for DsseEnvelopeExtensions (ToSerializableDict/FromBase64/GetPayloadBase64), payloadType default handling, or invalid base64 inputs. - Proposed changes (pending approval): add strict PAE byte-format assertions, add conversion tests, and cover payloadType default and invalid base64 error paths. +- Disposition: skipped (test project; no apply changes) ### src/Attestor/__Libraries/StellaOps.Attestor.Bundle/StellaOps.Attestor.Bundle.csproj - MAINT: TreatWarningsAsErrors is not set in the project file; warning discipline may be reduced. - MAINT: SigstoreBundleBuilder accepts logIndex/integratedTime/payload/signature strings without validation, so invalid base64 or non-numeric values are only caught later. @@ -340,12 +378,14 @@ - MAINT: Inclusion proof verification does not validate logIndex consistency or checkpoint signatures; RootHashMismatch is unused and never surfaced. - TEST: No tests for invalid base64 payload/signature, missing certificate/publicKey validation during deserialization, inclusion proof verification (valid/invalid), or invariant-culture PAE bytes. - Proposed changes (pending approval): add input validation for base64/numeric fields, enforce verification material presence in serializer validation, use invariant culture in PAE, harden base64 error handling, treat missing proofs explicitly, and add tests for base64 errors, inclusion proofs, and PAE bytes. +- Disposition: pending implementation (non-test project; apply recommendations remain open) ### src/Attestor/__Tests/StellaOps.Attestor.Bundle.Tests/StellaOps.Attestor.Bundle.Tests.csproj - MAINT: Tests generate certificates with DateTimeOffset.UtcNow; time-dependent behavior can be flaky in long-running or skewed environments. - MAINT: Test ConstructPae duplicates verifier logic; can drift from production implementation. - TEST: No tests for inclusion proof verification (valid/invalid), VerifyInclusionProof=false with proofs present, Ed25519/public-key-only verification paths, or invalid base64 payload/signature handling. - TEST: No tests for serializer validation of missing certificate/public key or RootHashMismatch handling. - Proposed changes (pending approval): use fixed timestamps for cert generation, reuse production PAE helper, add inclusion proof fixtures, cover public-key-only and Ed25519 verification, and add invalid base64/deserialization validation tests. +- Disposition: skipped (test project; no apply changes) ### src/Attestor/__Libraries/StellaOps.Attestor.Bundling/StellaOps.Attestor.Bundling.csproj - MAINT: TreatWarningsAsErrors is not set in the project file; warning discipline may be reduced. - MAINT: AttestationBundler ignores BundlingOptions.Aggregation.MinAttestationsForBundle and LookbackDays; empty periods always throw even when min is configured. @@ -358,6 +398,7 @@ - MAINT: BouncyCastle dependency appears unused in code; StellaOps.Attestor.Bundling.csproj.Backup.tmp is an orphaned artefact. - TEST: No tests for OfflineKitBundleProvider export behavior, retention overrides, period validation, or missing org signer paths. - Proposed changes (pending approval): validate date ranges and min-attestation behavior, fail when signing requested but signer absent, inject TimeProvider for metadata, compute key fingerprint from actual key material, apply retention overrides, honor export defaults, remove unused dependency/backup file, and add offline-kit/override/signing tests. +- Disposition: pending implementation (non-test project; apply recommendations remain open) ### src/Attestor/__Tests/StellaOps.Attestor.Bundling.Tests/StellaOps.Attestor.Bundling.Tests.csproj - MAINT: Tests use DateTimeOffset.UtcNow, Guid.NewGuid, and Random.Shared; results are time/random dependent and can be flaky. - MAINT: BundleWorkflowIntegrationTests reimplement bundling (custom merkle/root/signing) instead of exercising AttestationBundler, risking drift. @@ -365,6 +406,7 @@ - MAINT: Integration-style tests are labeled Unit, masking suite cost and expectations. - TEST: No tests for OfflineKitBundleProvider export paths, retention predicate/tenant overrides, missing-org-signer behavior, or invalid period validation. - Proposed changes (pending approval): use fixed time/IDs, route workflow tests through AttestationBundler/RetentionPolicyEnforcer, reclassify integration tests, and add coverage for offline exports, overrides, and missing signer cases. +- Disposition: skipped (test project; no apply changes) ### src/Attestor/StellaOps.Attestor/StellaOps.Attestor.Core/StellaOps.Attestor.Core.csproj - MAINT: TreatWarningsAsErrors is false in the project file; warning discipline is relaxed. - MAINT: DSSE PAE implementations disagree and are not spec aligned; DsseSigningService.CreatePae writes binary ulong lengths (little-endian), DssePreAuthenticationEncoding.Compute writes big-endian lengths, and both differ from DSSE v1 ASCII length encoding. @@ -380,6 +422,7 @@ - TEST: Coverage only exists for PredicateSchemaValidator and RekorOfflineReceiptVerifier; no tests for DSSE signing/PAE, submission validation, checkpoint parsing, Merkle proofs, time skew, delta attestation determinism, PoE generation/hash, or schema resource coverage. - TEST: No tests for AllowedKinds/logPreference alignment or canonical JSON ordering in delta/PoE outputs. - Proposed changes (pending approval): set TreatWarningsAsErrors, consolidate DSSE PAE into one spec-correct helper, align AllowedKinds/logPreference with delta and PoE flows, implement deterministic JSON ordering for dictionaries and honor PoE emission options, switch PoE hash to real BLAKE3 or change the label, add Ed25519 PEM parsing or explicit unsupported handling, align TimeSkew defaults with docs (or update docs), and add tests for DSSE, submission validation, checkpoint/Merkle verification, time skew, delta/PoE determinism, and schema resource coverage. +- Disposition: pending implementation (non-test project; apply recommendations remain open) ### src/Attestor/StellaOps.Attestor/StellaOps.Attestor.Core.Tests/StellaOps.Attestor.Core.Tests.csproj - MAINT: TreatWarningsAsErrors is false in the project file; warning discipline is relaxed for the test suite. - MAINT: Tests create temp directories using Guid.NewGuid/Path.GetTempPath with ad hoc cleanup; StellaOps.TestKit is referenced but not used for deterministic temp helpers. @@ -387,6 +430,7 @@ - TEST: Coverage is limited to RekorOfflineReceiptVerifier and PredicateSchemaValidator; no tests for DSSE PAE/signing, submission validation, checkpoint signature parsing, Merkle proofs, time skew, PoE generation/hash, or delta attestation output. - TEST: Missing negative-path coverage for receipt parsing (missing fields, invalid hash encoding, bad checkpoint reference, invalid proof hash lengths). - Proposed changes (pending approval): use TestKit temp helpers, add delta schema fixtures and missing-resource tests, expand receipt parsing negative cases, and add tests for DSSE/submission/merkle/time-skew/PoE/delta behaviors. +- Disposition: skipped (test project; no apply changes) ### src/Attestor/StellaOps.Attestor.Envelope/StellaOps.Attestor.Envelope.csproj - MAINT: TreatWarningsAsErrors is false in the project file; warning discipline is relaxed. - MAINT: EnvelopeSignatureService signs/verifies raw payload bytes and has no helper that includes payloadType/PAE; callers can unintentionally produce non-DSSE signatures. @@ -396,12 +440,14 @@ - MAINT: DsseEnvelopeSerializer allows both EmitCompactJson=false and EmitExpandedJson=false, returning no JSON output without a guard. - TEST: No tests for EnvelopeSignatureService (Ed25519/ECDSA), EnvelopeKey/EnvelopeKeyIdCalculator, signature ordering, compression + payloadType correctness, or detached payload validation. - Proposed changes (pending approval): set TreatWarningsAsErrors, add explicit DSSE PAE helper or rename API to require PAE input, prevent compression from mutating DSSE payloads without metadata (or document + adjust payloadType), validate base64 signature strings and detached payload digest format, guard against no-output options, and add tests for sign/verify, key IDs, compression behavior, and detached payload validation. +- Disposition: pending implementation (non-test project; apply recommendations remain open) ### src/Attestor/StellaOps.Attestor.Envelope/__Tests/StellaOps.Attestor.Envelope.Tests/StellaOps.Attestor.Envelope.Tests.csproj - MAINT: TreatWarningsAsErrors is false in the project file; warning discipline is relaxed for the test suite. - MAINT: FsCheck packages are referenced, but no property/fuzz tests exist and DsseEnvelopeFuzzTests.cs is removed; charter expectation is unmet. - TEST: Coverage is limited to DsseEnvelopeSerializer; no tests for EnvelopeSignatureService sign/verify, EnvelopeKey validation, key ID derivation, signature ordering, or base64 validation failures. - TEST: No tests for compression/preview option combinations, detached payload digest validation, or EmitCompactJson/EmitExpandedJson edge cases. - Proposed changes (pending approval): add property/fuzz tests (fixed seed), expand coverage to signature/key paths, add negative-path serialization tests, and validate compression/preview/detached metadata behaviors. +- Disposition: skipped (test project; no apply changes) ### src/Attestor/__Libraries/StellaOps.Attestor.GraphRoot/StellaOps.Attestor.GraphRoot.csproj - MAINT: TreatWarningsAsErrors is not set in the project file; warning discipline may be reduced. - MAINT: GraphRootAttestor signs raw payload bytes without DSSE PAE (payloadType binding); the DSSE envelope signature is not spec-aligned. @@ -414,6 +460,7 @@ - MAINT: StellaOps.Attestor.GraphRoot.csproj.Backup.tmp is a stray artifact in source control. - TEST: No tests for DSSE PAE correctness, signature verification, payloadType validation, evidence ID binding, digest normalization, or bundle hash determinism. - Proposed changes (pending approval): set TreatWarningsAsErrors, sign DSSE PAE (or require PAE input), verify signatures/payloadType/key ID in VerifyAsync, include EvidenceIds in root inputs (or remove from predicate), inject TimeProvider, normalize digests, canonicalize bundle hash generation, remove backup file, and add tests for signature/PAE, evidence binding, payloadType validation, digest normalization, and bundle hash determinism. +- Disposition: pending implementation (non-test project; apply recommendations remain open) ### src/Attestor/__Libraries/__Tests/StellaOps.Attestor.GraphRoot.Tests/StellaOps.Attestor.GraphRoot.Tests.csproj - MAINT: TreatWarningsAsErrors is false in the project file; warning discipline is relaxed for the test suite. - MAINT: Tests use Random.Shared, Guid.NewGuid, and DateTimeOffset.UtcNow; results are nondeterministic. @@ -421,6 +468,7 @@ - TEST: No coverage for DSSE PAE/signature verification, payloadType mismatch, invalid JSON or missing predicate in VerifyAsync, key mismatch, or evidence ID binding. - TEST: No tests for digest normalization or bundle hash determinism. - Proposed changes (pending approval): use fixed keys/IDs/time, reclassify integration tests, add DSSE signature/PAE tests, add negative-path verification tests, and cover evidence binding and digest normalization. +- Disposition: skipped (test project; no apply changes) ### src/Attestor/StellaOps.Attestor/StellaOps.Attestor.Infrastructure/StellaOps.Attestor.Infrastructure.csproj - MAINT: TreatWarningsAsErrors is false in the project file; warning discipline is relaxed. - MAINT: StellaOps.Attestor.Infrastructure.csproj.Backup.tmp is a stray artifact in source control. @@ -436,6 +484,7 @@ - MAINT: S3AttestorArchiveStore serializes metadata dictionaries without ordering; metadata JSON is nondeterministic. - MAINT: ServiceCollectionExtensions hard-codes HttpRekorClient timeout to 30s, ignoring Rekor options. - TEST: No infrastructure test project; missing coverage for submission/verification flows, bundle import/export, queues, cache invalidation, pagination, and Rekor/transparency clients. +- Disposition: pending implementation (non-test project; apply recommendations remain open) ### src/Attestor/__Libraries/StellaOps.Attestor.Oci/StellaOps.Attestor.Oci.csproj - MAINT: TreatWarningsAsErrors is not set in the project file; warning discipline may be reduced. - MAINT: OciReference.Parse does not support tag+digest references and rejects bare references without a registry, while tests expect docker.io defaults; parsing behavior is inconsistent with tests. @@ -447,6 +496,7 @@ - MAINT: FetchAsync blindly uses the first manifest layer without verifying media type; multi-layer manifests can return the wrong blob. - MAINT: DeserializeEnvelope does not dispose JsonDocument and throws on invalid payload base64 without a structured error. - TEST: Coverage is limited; no tests for attach/list/fetch/remove paths, annotation behavior, digest computation, or ReplaceExisting logic. +- Disposition: pending implementation (non-test project; apply recommendations remain open) ### src/Attestor/__Tests/StellaOps.Attestor.Oci.Tests/StellaOps.Attestor.Oci.Tests.csproj - MAINT: TreatWarningsAsErrors is false in the project file; warning discipline is relaxed for the test suite. - MAINT: OciReferenceTests expect docker.io defaults for "nginx:latest", but OciReference.Parse currently rejects references without a registry; tests are out of sync. @@ -455,6 +505,7 @@ - MAINT: OrasAttestationAttacherTests only cover guard clauses; they do not assert registry client calls, digest computation, or annotation behavior. - MAINT: Integration tests are all skipped placeholders; Testcontainers setup runs but exercises no implementation. - TEST: No tests for actual attach/list/fetch/remove flows, predicate type annotations, deterministic digest generation, invalid envelope/base64 handling, or tag+digest parsing. +- Disposition: skipped (test project; no apply changes) ### src/Attestor/__Libraries/StellaOps.Attestor.Offline/StellaOps.Attestor.Offline.csproj - MAINT: TreatWarningsAsErrors is not set in the project file; warning discipline may be reduced. - MAINT: StellaOps.Attestor.Offline.csproj.Backup.tmp is a stray artifact in source control. @@ -467,6 +518,7 @@ - MAINT: FileSystemRootStore ignores OfflineRootStoreOptions.UseOfflineKit; offline kit roots load even when disabled. - MAINT: FileSystemRootStore enumerates PEM directories without deterministic ordering; root listing order can vary across runs. - TEST: No tests for real DSSE signature verification, Rekor inclusion proof validation, org signature verification with cert chains, or UseOfflineKit behavior. +- Disposition: pending implementation (non-test project; apply recommendations remain open) ### src/Attestor/__Tests/StellaOps.Attestor.Offline.Tests/StellaOps.Attestor.Offline.Tests.csproj - MAINT: TreatWarningsAsErrors is false in the project file; warning discipline is relaxed for the test suite. - MAINT: Tests use DateTimeOffset.UtcNow and Guid.NewGuid (bundle metadata, certificates, shuffle order), making results nondeterministic. @@ -474,6 +526,7 @@ - MAINT: VerifyBundleAsync_DeterministicOrdering uses Guid.NewGuid for ordering, which can mask deterministic ordering regressions. - TEST: No tests for cryptographic DSSE signature verification, Rekor proof path validation, or org signature verification via certificate keys. - TEST: No tests for OfflineRootStoreOptions.UseOfflineKit toggle, invalid PEM parsing, or root ordering determinism. +- Disposition: skipped (test project; no apply changes) ### src/Attestor/__Libraries/StellaOps.Attestor.Persistence/StellaOps.Attestor.Persistence.csproj - MAINT: TreatWarningsAsErrors is not set in the project file; warning discipline may be reduced. - MAINT: Perf harness `run-perf.ps1` references a missing migration file (`Migrations/20251214000001_AddProofChainSchema.sql`), so the perf run fails against current schema. @@ -483,11 +536,13 @@ - MAINT: TrustAnchorMatcher caches regex patterns without bounds; untrusted or large pattern sets can grow memory indefinitely. - MAINT: EvidenceIds/AllowedKeyIds arrays are expected to be sorted or normalized but no enforcement exists before persistence. - TEST: No repository implementation or tests for DbContext mappings, migrations, or audit log behavior. +- Disposition: pending implementation (non-test project; apply recommendations remain open) ### src/Attestor/__Tests/StellaOps.Attestor.Persistence.Tests/StellaOps.Attestor.Persistence.Tests.csproj - MAINT: TreatWarningsAsErrors is false in the project file; warning discipline is relaxed for the test suite. - MAINT: Tests use Guid.NewGuid for anchor IDs; nondeterministic identifiers can obscure ordering-related issues. - MAINT: TrustAnchorMatcherTests only cover matching allowlists; no tests for equal-specificity tie-breakers, inactive anchors, or case-sensitivity edge cases. - TEST: No tests for DbContext mappings, migration SQL, or repository behaviors (upsert, audit log). +- Disposition: skipped (test project; no apply changes) ### src/Attestor/__Libraries/StellaOps.Attestor.ProofChain/StellaOps.Attestor.ProofChain.csproj - MAINT: TreatWarningsAsErrors is not set in the project file; warning discipline may be reduced. - MAINT: AuditHashLogger and proof generators use DateTimeOffset.UtcNow directly; no TimeProvider injection for deterministic outputs. @@ -497,12 +552,14 @@ - MAINT: DeterministicMerkleTreeBuilder claims lexicographic sorting but does not sort leaves; callers can produce nondeterministic roots. - MAINT: Rfc8785JsonCanonicalizer parses numbers via double; large integers/precise decimals can lose precision and canonicalize incorrectly. - TEST: No tests for schema validation logic, number canonicalization edge cases, proof generators, or AuditHashLogger outputs. +- Disposition: pending implementation (non-test project; apply recommendations remain open) ### src/Attestor/__Tests/StellaOps.Attestor.ProofChain.Tests/StellaOps.Attestor.ProofChain.Tests.csproj - MAINT: TreatWarningsAsErrors is false in the project file; warning discipline is relaxed for the test suite. - MAINT: UnitTest1 is an empty placeholder. - MAINT: ProofSpineAssemblyIntegrationTests are labeled Unit and include perf timing assertions; can be flaky and miscategorized. - MAINT: Some tests use Guid.NewGuid (TrustAnchorIdTests), which is nondeterministic and unnecessary. - TEST: No tests for PredicateSchemaValidator, proof generator timestamp determinism, JSON number canonicalization edge cases, or proof signing verification. +- Disposition: skipped (test project; no apply changes) ### src/Attestor/__Libraries/StellaOps.Attestor.StandardPredicates/StellaOps.Attestor.StandardPredicates.csproj - MAINT: TreatWarningsAsErrors is false in the project file; warning discipline is relaxed. - MAINT: JsonCanonicalizer uses JsonNode + double conversions; RFC 8785 number canonicalization can lose precision (large integers, decimals, -0) and emit non-canonical forms. @@ -513,6 +570,7 @@ - MAINT: JsonSchema.Net is referenced but schema validation is not implemented; only basic field checks are performed. - TEST: No tests for CycloneDX/SLSA parsers, JsonCanonicalizer numeric edge cases, or versioned predicate type handling. - Proposed changes (pending approval): enable TreatWarningsAsErrors, implement RFC 8785-compliant canonicalization with string-preserved numbers, use sorted/immutable metadata properties, register versioned predicate types, validate CycloneDX version field types, use invariant culture for numeric metadata, add schema validation or remove the unused package, and add tests for CycloneDX/SLSA parsing and canonicalization edge cases. +- Disposition: pending implementation (non-test project; apply recommendations remain open) ### src/Attestor/__Tests/StellaOps.Attestor.StandardPredicates.Tests/StellaOps.Attestor.StandardPredicates.Tests.csproj - MAINT: TreatWarningsAsErrors is false in the project file; warning discipline is relaxed for the test suite. - MAINT: StandardPredicateRegistryTests has inconsistent attribute indentation; minor but reduces readability. @@ -520,6 +578,7 @@ - TEST: No tests for JsonCanonicalizer (key ordering, number precision, -0, exponent normalization) or versioned predicate type registration. - TEST: No tests for CycloneDX metadata extraction warnings/errors or for SLSA required-field validation edge cases. - Proposed changes (pending approval): add CycloneDX and SLSA parser test suites, add JsonCanonicalizer determinism tests (key order, numeric edge cases), validate versioned predicate type registration, and tighten test formatting/consistency. +- Disposition: skipped (test project; no apply changes) ### src/Attestor/StellaOps.Attestor/StellaOps.Attestor.Tests/StellaOps.Attestor.Tests.csproj - MAINT: TreatWarningsAsErrors is false in the project file; warning discipline is relaxed for the test suite. - MAINT: Many tests use DateTimeOffset.UtcNow, Guid.NewGuid, Random.Shared, and RandomNumberGenerator.GetBytes, which makes results nondeterministic and harder to reproduce (AttestorStorageTests, AttestorEntryRepositoryTests, AttestorVerificationServiceTests, AttestorSubmissionServiceTests, RekorInclusionVerificationIntegrationTests, TestSupport/TestAttestorDoubles). @@ -530,6 +589,7 @@ - TEST: Contract snapshot tests do not enforce a stored baseline; they only check that OpenAPI exists and list paths (no diff or snapshot comparison). - TEST: Rekor queue tests are compiled only under STELLAOPS_EXPERIMENTAL_REKOR_QUEUE; the default build does not exercise those paths. - Proposed changes (pending approval): enable TreatWarningsAsErrors, use fixed TimeProvider/IDs and deterministic random seeds, replace Task.Delay with deterministic time controls, recategorize integration/observability tests, strengthen assertions for auth/contract/negative suites, add a real OpenAPI snapshot baseline, remove mojibake output markers, and ensure Rekor queue tests run in a dedicated integration suite. +- Disposition: skipped (test project; no apply changes) ### src/Attestor/__Libraries/StellaOps.Attestor.TrustVerdict/StellaOps.Attestor.TrustVerdict.csproj - MAINT: TreatWarningsAsErrors is not set in the project file; warning discipline may be reduced. - MAINT: JsonCanonicalizer is not RFC 8785 compliant (UnsafeRelaxedJsonEscaping, camel-case renaming, and number handling that can preserve exponent notation or non-minimal forms), risking non-canonical hashes. @@ -542,6 +602,7 @@ - MAINT: Migration comment lists trust tier values that differ from code (VeryHigh/High/Medium/Low/VeryLow). - TEST: No tests for JsonCanonicalizer edge cases, repository mapping, OCI attachment, metrics, or merkle root consistency between service and builder. - Proposed changes (pending approval): enable TreatWarningsAsErrors, align merkle root computation with builder (or use builder), enforce invariant-culture formatting for reasons, implement OCI/Valkey or explicitly return not-implemented errors, fix cache expiry/index handling and HitCount tracking, use DateTimeOffset reads, align migration comments, and add tests for canonicalization, repository mapping, OCI attach/fetch, cache expiry, and merkle consistency. +- Disposition: pending implementation (non-test project; apply recommendations remain open) ### src/Attestor/__Libraries/StellaOps.Attestor.TrustVerdict.Tests/StellaOps.Attestor.TrustVerdict.Tests.csproj - MAINT: TreatWarningsAsErrors is not set in the project file; warning discipline is relaxed for the test suite. - MAINT: TrustEvidenceMerkleBuilderTests.Build_SortsItemsByDigest lacks assertions for the actual ordering. @@ -549,6 +610,7 @@ - TEST: No tests for TrustVerdictService merkle root consistency with TrustEvidenceMerkleBuilder or duplicate-digest tie-breakers. - TEST: No tests for repository, OCI attacher, Valkey fallback, or metrics instrumentation. - Proposed changes (pending approval): add assertions for sort order, add canonicalizer tests (numbers/escaping), add merkle root consistency and duplicate-digest tests, and add coverage for repository/Oci/Valkey/metrics behaviors. +- Disposition: skipped (test project; no apply changes) ### src/Attestor/StellaOps.Attestor.Types/Tools/StellaOps.Attestor.Types.Generator/StellaOps.Attestor.Types.Generator.csproj - MAINT: TreatWarningsAsErrors is false in the project file; warning discipline is relaxed. - MAINT: ResolveRepoRoot relies on a fixed 8-level parent walk from AppContext.BaseDirectory; running from a different output layout can fail and there is no CLI override. @@ -558,6 +620,7 @@ - MAINT: Go validation omits string pattern checks for digest formats and other regex patterns, so required formats are not enforced. - MAINT: Generator writes output but does not prune stale schema/SDK files when objects are removed. - TEST: No tests for generator output determinism, schema parity, or canonicalization/validator behavior. +- Disposition: pending implementation (non-test project; apply recommendations remain open) ### src/Attestor/__Tests/StellaOps.Attestor.Types.Tests/StellaOps.Attestor.Types.Tests.csproj - MAINT: TreatWarningsAsErrors is not set in the project file; warning discipline is relaxed for the test suite. - MAINT: Test output/log markers contain mojibake or non-ASCII sequences (garbled symbols), hurting readability and log portability. @@ -569,6 +632,7 @@ - TEST: MockRekorClient.SubmitAsync blocks on .Result; if async paths evolve, this can deadlock and tests do not exercise true async behavior. - TEST: Schema validation only covers the SmartDiff schema and one negative case; other schema files and sample files are not validated against schemas. - Proposed changes (pending approval): enable TreatWarningsAsErrors, normalize output strings to ASCII, use a deterministic time provider in Rekor tests, align determinism tests to RFC 8785 canonicalization helpers, fix Unicode normalization test data, align namespaces, update mock DSSE PAE framing, avoid .Result in mocks, and add schema/sample validation coverage across all schemas. +- Disposition: skipped (test project; no apply changes) ### src/Attestor/StellaOps.Attestor.Verify/StellaOps.Attestor.Verify.csproj - MAINT: TreatWarningsAsErrors is false in the project file; warning discipline is relaxed. - MAINT: AttestorVerificationEngine is a large, multi-responsibility class (signature, issuer, transparency, freshness, policy), which makes it hard to test and evolve. @@ -580,6 +644,7 @@ - TEST: No test project for Attestor.Verify; no coverage for signature validation paths, issuer chain validation, transparency proof evaluation, or policy aggregation. - TEST: No tests for the experimental distributed provider (routing, circuit breaker state, retry behavior, or node health checks). - Proposed changes (pending approval): enable TreatWarningsAsErrors, split the engine into focused components, align PAE framing with DSSE spec, dedupe verified signatures per key, add intermediate certificates to chain policy, parse SANs via ASN.1, fix the distributed provider dependencies and hash determinism, and add a dedicated test project covering signature/issuer/transparency/policy and distributed provider behavior. +- Disposition: pending implementation (non-test project; apply recommendations remain open) ### src/Attestor/StellaOps.Attestor/StellaOps.Attestor.WebService/StellaOps.Attestor.WebService.csproj - MAINT: TreatWarningsAsErrors is false in the project file; warning discipline is relaxed. - MAINT: Program.cs is a monolithic composition root that mixes DI, auth, rate limiting, and endpoint mapping; makes testing and change isolation harder. @@ -591,6 +656,7 @@ - TEST: No test project for the web service; no coverage for auth/mTLS, rate limiting, controllers, or minimal API routes. - TEST: No contract tests or OpenAPI snapshot validation for response payloads (list/detail/verify/bulk/bundles). - Proposed changes (pending approval): enable TreatWarningsAsErrors, split Program.cs into modules/extension methods, consolidate endpoint style, gate or remove stub controllers until implemented, wire TimeProvider into controllers, require auth/rate limits on controller routes, require EvidenceLocker base address config, and add WebApplicationFactory tests for auth, routes, and contracts. +- Disposition: pending implementation (non-test project; apply recommendations remain open) ### src/__Libraries/StellaOps.Audit.ReplayToken/StellaOps.Audit.ReplayToken.csproj - MAINT: TreatWarningsAsErrors is false in the project file; warning discipline is relaxed. - MAINT: README only documents v1 token format and contains mojibake text; v2 expiration format is undocumented. @@ -602,6 +668,7 @@ - TEST: No tests for AdditionalContext ordering normalization or duplicate-key handling. - TEST: No tests for ReplayCliSnippetGenerator output formatting/escaping or DecisionReplayTokenExtensions helpers. - Proposed changes (pending approval): enable TreatWarningsAsErrors, update README for v2 tokens and fix encoding artifacts, fix CLI snippet formatting and escape values, align canonical versioning with token version, guard against duplicate normalized keys, validate expiration inputs, document GeneratedAt semantics, and add unit tests for AdditionalContext ordering/duplicate keys, CLI snippet generation, and v1/v2 canonicalization semantics. +- Disposition: pending implementation (non-test project; apply recommendations remain open) ### src/__Tests/StellaOps.Audit.ReplayToken.Tests/StellaOps.Audit.ReplayToken.Tests.csproj - MAINT: TreatWarningsAsErrors is false in the project file; warning discipline is relaxed for the test suite. - MAINT: Project lacks explicit test SDK/runner references (e.g., Microsoft.NET.Test.Sdk, xunit runner); discovery/coverage may depend on transitive packages. @@ -612,6 +679,7 @@ - TEST: No tests for AdditionalContext ordering normalization or duplicate-key handling. - TEST: No tests asserting canonicalization versioning differences between v1 and v2 tokens. - Proposed changes (pending approval): enable TreatWarningsAsErrors, add explicit test SDK/runner packages, fix test naming/formatting, clean comment encoding artifacts, and add tests for CLI snippet generation, extension helpers, AdditionalContext ordering/duplicates, and v1/v2 canonicalization differences. +- Disposition: skipped (test project; no apply changes) ### src/__Libraries/StellaOps.AuditPack/StellaOps.AuditPack.csproj - MAINT: TreatWarningsAsErrors is not set in the project file; warning discipline is relaxed. - MAINT: Core flows are placeholders or TODOs (AuditPackBuilder collectors and SignPackAsync, AuditPackReplayer ExecuteReplayAsync/FindJsonDifferences, AuditPackImporter signature verification, ScanSnapshotFetcher placeholder data, AuditPackExportService mock segments and empty DSSE signatures). @@ -621,6 +689,7 @@ - MAINT: ReplayAttestationService.VerifyAsync marks signatures as verified based only on signature count and claims canonical JSON while using the default JsonSerializer; digest stability and signature verification are not enforced. - TEST: Coverage does not exercise the TODO flows (collector methods, SignPackAsync, replay execution/diff), signature verification paths (AuditPackImporter/AuditBundleSigner/ReplayAttestationService), tar extraction safety, KeepExtracted/EnforceOffline options, or deterministic serialization with fixed time/IDs. - Proposed changes (pending approval): enable TreatWarningsAsErrors, implement or gate TODO paths, add TimeProvider/ID injection, validate tar extraction paths and deterministic entry ordering, honor KeepExtracted/EnforceOffline, implement signature verification, and add tests for replay, signing, and extraction safety. +- Disposition: pending implementation (non-test project; apply recommendations remain open) ### src/__Libraries/__Tests/StellaOps.AuditPack.Tests/StellaOps.AuditPack.Tests.csproj - MAINT: TreatWarningsAsErrors is not set in the project file; warning discipline is relaxed for the test suite. - MAINT: AuditReplayE2ETests and archive-heavy tests are tagged Unit even though they exercise filesystem and tar/gz flows. @@ -628,6 +697,7 @@ - TEST: No coverage for signature verification in AuditBundleSigner/AuditBundleReader, tar extraction safety (path traversal/overwrite), or IsolatedReplayContext offline enforcement. - TEST: Export tests use MockAuditBundleWriter and repository-less export paths, so they do not validate repository-backed segment data or DSSE signing. - Proposed changes (pending approval): enable TreatWarningsAsErrors, recategorize integration/E2E tests, use fixed time/IDs, add tests for signature verification and extraction safety, and add coverage for repository-backed export flows. +- Disposition: skipped (test project; no apply changes) ### src/__Tests/unit/StellaOps.AuditPack.Tests/StellaOps.AuditPack.Tests.csproj - MAINT: TreatWarningsAsErrors is not set in the project file; warning discipline is relaxed for the test suite. - MAINT: AuditPackBuilderTests.PackDigest_IsComputedCorrectly never computes a digest and asserts PackDigest is non-null; the test is invalid as written. @@ -636,6 +706,7 @@ - TEST: No tests for ImportOptions.KeepExtracted, tar extraction path safety, or importer signature verification behavior. - TEST: No tests for replay execution/diff behavior, signer integration in ReplayAttestationService, or deterministic pack serialization with fixed time/IDs. - Proposed changes (pending approval): enable TreatWarningsAsErrors, fix PackDigest test to compute digest, separate integration-style tests, use deterministic time/IDs, create a valid tar without manifest for negative tests, and add tests for signature verification, KeepExtracted, and replay/diff paths. +- Disposition: skipped (test project; no apply changes) ### src/Authority/StellaOps.Authority/StellaOps.Auth.Abstractions/StellaOps.Auth.Abstractions.csproj - MAINT: TreatWarningsAsErrors is false in the project file; warning discipline is relaxed. - MAINT: StellaOpsScopes.All exposes the mutable HashSet backing store with nondeterministic iteration order; callers can observe unstable scope ordering. @@ -644,6 +715,7 @@ - TEST: No tests for IsKnown behavior or edge cases in NetworkMask.TryParse (invalid prefixes, IPv6 boundaries) or NetworkMaskMatcher.AllowAll/DenyAll semantics. - TEST: StellaOpsPrincipalBuilderTests uses DateTimeOffset.UtcNow and Guid.NewGuid, which makes tests time-dependent and less deterministic. - Proposed changes (pending approval): enable TreatWarningsAsErrors, return a stable ordered snapshot for StellaOpsScopes.All and add a guard test for KnownScopes completeness, add tests for telemetry/defaults constants and network mask edge cases, and use fixed timestamps/IDs in principal builder tests. +- Disposition: pending implementation (non-test project; apply recommendations remain open) ### src/Authority/StellaOps.Authority/StellaOps.Auth.Abstractions.Tests/StellaOps.Auth.Abstractions.Tests.csproj - MAINT: TreatWarningsAsErrors is not set in the project file; warning discipline is relaxed for the test suite. - MAINT: Project relies on Directory.Build.props for test SDK/runner references; explicit references are absent in the csproj. @@ -654,6 +726,7 @@ - TEST: No tests for StellaOpsScopes.IsKnown or for completeness of KnownScopes vs all defined scope constants. - TEST: StellaOpsProblemResultFactory has no tests for Forbidden or default detail behavior. - Proposed changes (pending approval): enable TreatWarningsAsErrors, add explicit test SDK references or document reliance on Directory.Build.props, normalize test attribute indentation, use fixed time/IDs, and add tests for scope completeness, network mask edge cases, and missing problem/telemetry defaults. +- Disposition: skipped (test project; no apply changes) ### src/Authority/StellaOps.Authority/StellaOps.Auth.Client/StellaOps.Auth.Client.csproj - MAINT: TreatWarningsAsErrors is false in the project file; warning discipline is relaxed. - MAINT: StellaOpsAuthClientOptions exposes EnableRetries/RetryDelays/NormalizedRetryDelays, but ConfigureResilience always uses fixed retry settings; option values are unused and misleading. @@ -662,6 +735,7 @@ - MAINT: FileTokenCache writes token files without explicit permission hardening; cached tokens may be readable by other users on shared machines. - TEST: Coverage does not exercise JWKS cache expiry/offline fallback, MessagingTokenCache TTL/invalidations, file cache error paths, password-mode bearer handler, or retry configuration behavior. - Proposed changes (pending approval): enable TreatWarningsAsErrors, wire retry options into resilience config (and allow disabling retries), reset cached tokens on option changes or incorporate cache keys, allow DI TimeProvider in file cache registration, harden cache file permissions, and add tests for JWKS cache, messaging cache, and handler modes. +- Disposition: pending implementation (non-test project; apply recommendations remain open) ### src/Authority/StellaOps.Authority/StellaOps.Auth.Client.Tests/StellaOps.Auth.Client.Tests.csproj - MAINT: TreatWarningsAsErrors is not set in the project file; warning discipline is relaxed for the test suite. - MAINT: Project relies on Directory.Build.props for test SDK/runner references; explicit references are absent in the csproj. @@ -673,6 +747,7 @@ - TEST: No tests for StellaOpsJwksCache expiry/offline fallback, MessagingTokenCache behavior, StellaOpsApiAuthenticationOptions.Validate negative cases, or bearer handler password mode. - TEST: No tests verifying retry configuration behavior or file cache error handling (deserialize failure, permission errors). - Proposed changes (pending approval): enable TreatWarningsAsErrors, add explicit test SDK references or document reliance on Directory.Build.props, normalize test formatting, replace UtcNow with FakeTimeProvider, avoid private-field reflection, add missing assertions, and add coverage for JWKS cache, messaging cache, auth option validation, and bearer handler password flow. +- Disposition: skipped (test project; no apply changes) ### src/__Libraries/StellaOps.Auth.Security/StellaOps.Auth.Security.csproj - MAINT: TreatWarningsAsErrors is false in the project file; warning discipline is relaxed. - MAINT: DpopProofValidator uses GetString on typ/alg/htm/htu/nonce without ValueKind checks; malformed claims can throw instead of returning a structured failure. @@ -681,6 +756,7 @@ - TEST: No dedicated test project for StellaOps.Auth.Security; coverage for DPoP validator, nonce stores, and replay cache behavior is missing. - TEST: No tests for invalid claim types/format handling, clock skew/expiry boundaries, or replay detection semantics across caches. - Proposed changes (pending approval): enable TreatWarningsAsErrors, add strict ValueKind checks for typ/alg/htm/htu/nonce to return failures, make DpopValidationOptions immutable or clone + re-normalize algorithms on change, normalize nonce storage keys consistently across stores, and add unit tests for validator scenarios, nonce store compatibility, and replay cache behavior. +- Disposition: pending implementation (non-test project; apply recommendations remain open) ### src/Authority/StellaOps.Authority/StellaOps.Auth.ServerIntegration/StellaOps.Auth.ServerIntegration.csproj - MAINT: TreatWarningsAsErrors is false in the project file; warning discipline is relaxed. - MAINT: StellaOpsAuthorityConfigurationManager refresh has no stale-if-error fallback; after cache expiry, metadata/JWKS fetch failures will break auth even in offline/air-gapped scenarios. @@ -689,6 +765,7 @@ - TEST: No tests for StellaOpsAuthorityConfigurationManager caching, JWKS retrieval, or stale fallback behavior. - TEST: No tests for StellaOpsBypassEvaluator deny paths (Authorization header present, null remote IP) or for vuln:read to vuln:view compatibility mapping in ExtractScopes. - Proposed changes (pending approval): enable TreatWarningsAsErrors, add stale-if-error behavior and option-change refresh for metadata/JWKS caching, normalize scope_item claims, and add unit tests for configuration manager refresh/fallback, bypass evaluator deny cases, and scope normalization/legacy mapping. +- Disposition: pending implementation (non-test project; apply recommendations remain open) ### src/Authority/StellaOps.Authority/StellaOps.Auth.ServerIntegration.Tests/StellaOps.Auth.ServerIntegration.Tests.csproj - MAINT: TreatWarningsAsErrors is not set in the project file; warning discipline is relaxed for the test suite. - MAINT: Project relies on Directory.Build.props for test SDK/runner references; explicit package references are absent in the csproj. @@ -697,6 +774,7 @@ - TEST: No tests for StellaOpsResourceServerOptions validation failures (invalid Authority URI, HTTPS enforcement, invalid timeout or cache lifetime ranges). - TEST: No tests for StellaOpsBypassEvaluator deny paths (Authorization header present, null remote IP) or ExtractScopes scope_item normalization and legacy vuln:read mapping. - Proposed changes (pending approval): enable TreatWarningsAsErrors, add explicit test SDK references or document reliance on Directory.Build.props, normalize test formatting, and add tests for configuration manager caching/fallback, options validation failures, bypass evaluator deny cases, and scope_item/legacy scope normalization. +- Disposition: skipped (test project; no apply changes) ### src/Authority/StellaOps.Authority/StellaOps.Authority/StellaOps.Authority.csproj - MAINT: TreatWarningsAsErrors is false in the project file; warning discipline is relaxed. - MAINT: Program.cs is a monolithic composition root (~130k) mixing service registration, pipeline config, and endpoint logic; hard to test and reason about changes. @@ -706,6 +784,7 @@ - TEST: No unit tests for Postgres store adapters (client/service account/token/revocation/login/airgap) validating mappings, defaults, and revoke flows. - TEST: No direct unit tests for VulnWorkflowAntiForgeryTokenIssuer or VulnAttachmentTokenIssuer validation paths (nonce/lifetime/context limits). - Proposed changes (pending approval): enable TreatWarningsAsErrors, split Program.cs into feature-specific extension modules, add concurrency-safe replay tracking with TTL for token usage, move list filtering into repository queries or raise limits deterministically, inject TimeProvider/ID generator in stores/issuers, and add tests for Postgres adapters plus workflow/attachment token issuer validation. +- Disposition: pending implementation (non-test project; apply recommendations remain open) ### src/Authority/__Libraries/StellaOps.Authority.Core/StellaOps.Authority.Core.csproj - MAINT: TreatWarningsAsErrors is false in the project file; warning discipline is relaxed. - MAINT: VerdictManifestBuilder defaults to Guid.NewGuid and DateTimeOffset.UtcNow (evaluatedAt/clockCutoff) when callers omit explicit values, which reduces determinism. @@ -715,6 +794,7 @@ - TEST: No tests for VerdictReplayVerifier (signature invalid, differences, error handling, manifestId overload) or NullVerdictManifestSigner behavior. - TEST: InMemoryVerdictManifestStoreTests uses DateTimeOffset.UtcNow for evaluatedAt/clockCutoff, which can make ordering assertions time-dependent. - Proposed changes (pending approval): enable TreatWarningsAsErrors, require explicit TimeProvider/clock inputs or inject a clock into VerdictManifestBuilder, implement or throw in VerifyAsync(manifestId), clarify or adjust NullVerdictManifestSigner validity semantics, align serializer comments with behavior, and add tests for replay verification/signing plus deterministic time usage in store tests. +- Disposition: pending implementation (non-test project; apply recommendations remain open) ### src/Authority/__Tests/StellaOps.Authority.Core.Tests/StellaOps.Authority.Core.Tests.csproj - MAINT: TreatWarningsAsErrors is false in the project file; warning discipline is relaxed for the test suite. - MAINT: Project relies on Directory.Build.props for test SDK/runner references; explicit package references are absent in the csproj. @@ -723,6 +803,7 @@ - TEST: No tests for NullVerdictManifestSigner behavior or signature verification failure handling. - TEST: No tests for ListByAssetAsync pagination/ordering or invalid pageToken handling in InMemoryVerdictManifestStore. - Proposed changes (pending approval): enable TreatWarningsAsErrors, add explicit test SDK references or document reliance on Directory.Build.props, replace UtcNow with fixed timestamps, and add tests for replay verifier, null signer semantics, and list-by-asset pagination edge cases. +- Disposition: skipped (test project; no apply changes) ### src/Authority/__Libraries/StellaOps.Authority.Persistence/StellaOps.Authority.Persistence.csproj - MAINT: TreatWarningsAsErrors is false in the project file; warning discipline is relaxed. - MAINT: AuthorityPersistenceExtensions and Postgres.ServiceCollectionExtensions duplicate service registrations; keeping them in sync is error-prone. @@ -732,6 +813,7 @@ - TEST: No tests for PostgresVerdictManifestStore CRUD/pagination/serialization or for in-memory store behaviors (bootstrap invites, token usage, revocation export sequence). - TEST: No tests verifying schema override behavior or DI registration via the persistence extension methods. - Proposed changes (pending approval): enable TreatWarningsAsErrors, consolidate service registration into a single extension, clone PostgresOptions before mutation, align PostgresVerdictManifestStore serialization with core serializer and respect configured schema, add TimeProvider/ID injection for in-memory stores, and add tests for verdict manifest persistence plus in-memory and registration behaviors. +- Disposition: pending implementation (non-test project; apply recommendations remain open) ### src/Authority/__Tests/StellaOps.Authority.Persistence.Tests/StellaOps.Authority.Persistence.Tests.csproj - MAINT: TreatWarningsAsErrors is false in the project file; warning discipline is relaxed for the test suite. - MAINT: Project relies on Directory.Build.props for test SDK/runner references; explicit package references are absent in the csproj. @@ -741,6 +823,7 @@ - TEST: No tests for in-memory store behaviors (bootstrap invite reservation, token usage replay detection, revocation export sequencing). - TEST: Many tests use DateTimeOffset.UtcNow and Guid.NewGuid, which can make assertions time-dependent. - Proposed changes (pending approval): enable TreatWarningsAsErrors, add explicit test SDK references or document reliance on Directory.Build.props, fix test categorization/formatting/encoding artifacts, add missing repository and in-memory store coverage, and use fixed timestamps/IDs where possible. +- Disposition: skipped (test project; no apply changes) ### src/Authority/StellaOps.Authority/StellaOps.Authority.Plugin.Ldap/StellaOps.Authority.Plugin.Ldap.csproj - MAINT: TreatWarningsAsErrors is false in the project file; warning discipline is relaxed. - MAINT: LdapIdentityProviderPlugin runs LdapCapabilityProbe synchronously on construction; the probe uses sync-over-async calls with a fixed 5s timeout, which can stall startup and is not configurable. @@ -753,6 +836,7 @@ - TEST: No tests for LdapSecretResolver file/env handling or for FindBySubjectAsync behavior. - TEST: No tests for capability probe failure paths (missing container DN, connection failure, service bind failure) or for snapshot cache refresh behavior. - Proposed changes (pending approval): enable TreatWarningsAsErrors, make capability probing async with configurable timeouts and refresh behavior, implement FindBySubjectAsync, consolidate filter escaping, and add tests for health checks, probe failure/caching, connection factory TLS/cert handling, and secret resolution. +- Disposition: pending implementation (non-test project; apply recommendations remain open) ### src/Authority/StellaOps.Authority/StellaOps.Authority.Plugin.Ldap.Tests/StellaOps.Authority.Plugin.Ldap.Tests.csproj - MAINT: TreatWarningsAsErrors is not set in the project file; warning discipline is relaxed for the test suite. - MAINT: Multiple tests include mojibake/non-ASCII marker strings in output (security/resilience/snapshot tests), reducing log portability. @@ -764,6 +848,7 @@ - TEST: No tests for LdapSecretResolver file/env resolution or for FindBySubjectAsync behavior. - TEST: No tests for MessagingLdapClaimsCache or distributed cache integration paths. - Proposed changes (pending approval): enable TreatWarningsAsErrors, replace non-ASCII log markers with ASCII, add assertions to placeholder tests, shift snapshot tests to exercise production code paths, normalize formatting, and add coverage for identity provider health, connection factory TLS/cert behavior, secret resolution, FindBySubjectAsync, and distributed cache. +- Disposition: skipped (test project; no apply changes) ### src/Authority/StellaOps.Authority/StellaOps.Authority.Plugin.Oidc/StellaOps.Authority.Plugin.Oidc.csproj - MAINT: TreatWarningsAsErrors is false in the project file; warning discipline is relaxed. - MAINT: RequireAsymmetricKey option is never enforced in OidcCredentialStore, so symmetric tokens are accepted even when asymmetric-only is requested. @@ -776,6 +861,7 @@ - TEST: No tests for OidcIdentityProviderPlugin health check paths (success/degraded/unavailable) or for configuration refresh behavior. - TEST: No tests for OidcClaimsEnricher claim additions or role propagation. - Proposed changes (pending approval): enable TreatWarningsAsErrors, enforce RequireAsymmetricKey, include plugin name in cache keys, use IHttpClientFactory with configurable timeouts, register/dispose a shared MemoryCache, add option validation for redirect URIs and scopes, remove the backup tmp file, and add tests for token validation paths, health checks, claims enrichment, and cache isolation. +- Disposition: pending implementation (non-test project; apply recommendations remain open) ### src/Authority/StellaOps.Authority/StellaOps.Authority.Plugin.Oidc.Tests/StellaOps.Authority.Plugin.Oidc.Tests.csproj - MAINT: TreatWarningsAsErrors is not set in the project file; warning discipline is relaxed for the test suite. - MAINT: Test project lacks explicit test SDK/runner references; discovery depends on shared props/packages. @@ -786,6 +872,7 @@ - TEST: No tests for OidcCredentialStore against real validation paths (issuer/audience/clock skew/asymmetric enforcement) or metadata refresh behavior. - TEST: No tests for OidcClaimsEnricher behavior or for session cache key isolation across plugin instances. - Proposed changes (pending approval): enable TreatWarningsAsErrors, add explicit test SDK/runner references or document reliance on shared props, replace non-ASCII markers with ASCII, add assertions to placeholder tests, use fixed timestamps/IDs, and add tests that exercise production token validation, metadata refresh, claims enrichment, and cache keying. +- Disposition: skipped (test project; no apply changes) ### src/Authority/StellaOps.Authority/StellaOps.Authority.Plugin.Saml/StellaOps.Authority.Plugin.Saml.csproj - MAINT: TreatWarningsAsErrors is false in the project file; warning discipline is relaxed. - MAINT: IdpMetadataUrl is accepted in validation but not used to fetch or refresh signing keys; with metadata-only config, signature validation will fail at runtime. @@ -798,6 +885,7 @@ - TEST: No tests for SamlCredentialStore validation behavior (signature/audience/lifetime), certificate loading, or metadata-based refresh. - TEST: No tests for SamlIdentityProviderPlugin health check paths or SamlClaimsEnricher behavior. - Proposed changes (pending approval): enable TreatWarningsAsErrors, implement metadata-based signing key retrieval or require explicit certs, refresh certs on option changes, include plugin name in cache keys, use IHttpClientFactory with configurable timeouts, harden XML parsing, implement or remove unused options, remove the backup tmp file, and add tests for validation paths, health checks, claims enrichment, and cache isolation. +- Disposition: pending implementation (non-test project; apply recommendations remain open) ### src/Authority/StellaOps.Authority/StellaOps.Authority.Plugin.Saml.Tests/StellaOps.Authority.Plugin.Saml.Tests.csproj - MAINT: TreatWarningsAsErrors is not set in the project file; warning discipline is relaxed for the test suite. - MAINT: Test project lacks explicit test SDK/runner references; discovery depends on shared props/packages. @@ -808,6 +896,7 @@ - TEST: No tests for SamlCredentialStore against real validation paths (signature verification, audience, lifetime, encrypted assertions). - TEST: No tests for SamlClaimsEnricher behavior or for session cache key isolation across plugin instances. - Proposed changes (pending approval): enable TreatWarningsAsErrors, add explicit test SDK/runner references or document reliance on shared props, replace non-ASCII markers with ASCII, add assertions to placeholder tests, use fixed timestamps/IDs, and add tests that exercise production SAML validation, XML hardening, claims enrichment, and cache keying. +- Disposition: skipped (test project; no apply changes) ### src/Authority/StellaOps.Authority/StellaOps.Authority.Plugin.Standard/StellaOps.Authority.Plugin.Standard.csproj - MAINT: TreatWarningsAsErrors is false in the project file; warning discipline is relaxed. - MAINT: StandardPluginOptions.Normalize only normalizes TokenSigning paths; TenantId and bootstrap values are not trimmed or normalized, so whitespace can become a tenant identifier. @@ -819,6 +908,7 @@ - TEST: No tests for StandardClaimsEnricher, StandardIdentityProviderPlugin health checks, or StandardPluginBootstrapper error handling. - TEST: No tests for StandardClientProvisioningStore.DeleteAsync or for password policy rejection paths. - Proposed changes (pending approval): enable TreatWarningsAsErrors, normalize TenantId/bootstrap values, remove or implement TokenSigning options, fix metadata mapping for List/Dictionary values, add a subjectId query path, inject TimeProvider/ID generator, and add tests for subject lookups, update flows, claims enrichment, bootstrapper behavior, and delete/password-policy paths. +- Disposition: pending implementation (non-test project; apply recommendations remain open) ### src/Authority/StellaOps.Authority/StellaOps.Authority.Plugin.Standard.Tests/StellaOps.Authority.Plugin.Standard.Tests.csproj - MAINT: TreatWarningsAsErrors is not set in the project file; warning discipline is relaxed for the test suite. - MAINT: Test project lacks explicit test SDK/runner references; discovery depends on shared props/packages. @@ -828,6 +918,7 @@ - TEST: No tests for StandardClaimsEnricher or StandardIdentityProviderPlugin health paths. - TEST: No tests for FindBySubjectAsync/update-role/attribute flows or StandardClientProvisioningStore.DeleteAsync. - Proposed changes (pending approval): enable TreatWarningsAsErrors, add explicit test SDK/runner references or document reliance on shared props, normalize formatting, use fixed timestamps/IDs, remove unused dependencies if safe, and add tests for claims enrichment, identity provider health, subject lookup/update flows, and client delete behavior. +- Disposition: skipped (test project; no apply changes) ### src/Authority/StellaOps.Authority/StellaOps.Authority.Plugins.Abstractions/StellaOps.Authority.Plugins.Abstractions.csproj - MAINT: TreatWarningsAsErrors is false in the project file; warning discipline is relaxed. - MAINT: AuthorityPluginHealthResult uses a shared static dictionary for empty details; if mutated via cast, results can bleed across instances. @@ -837,6 +928,7 @@ - TEST: No tests for AuthoritySecretHasher algorithm selection, configure behavior, or error path when not configured. - TEST: No tests for AuthorityClientDescriptor/AuthorityClientCertificateBindingRegistration normalization or AuthorityIdentityProviderHandle disposal behavior. - Proposed changes (pending approval): enable TreatWarningsAsErrors, remove the backup tmp file, protect the empty-details dictionary (defensive copy or read-only wrapper), clarify/encapsulate AuthoritySecretHasher configuration scope, and add tests for HasCapability, secret hashing, client descriptor normalization, and handle disposal. +- Disposition: pending implementation (non-test project; apply recommendations remain open) ### src/Authority/StellaOps.Authority/StellaOps.Authority.Plugins.Abstractions.Tests/StellaOps.Authority.Plugins.Abstractions.Tests.csproj - MAINT: TreatWarningsAsErrors is not set in the project file; warning discipline is relaxed for the test suite. - MAINT: Test project lacks explicit test SDK/runner references; discovery depends on shared props/packages. @@ -844,6 +936,7 @@ - TEST: No tests for AuthorityPluginManifest.HasCapability, AuthoritySecretHasher, or AuthorityClientDescriptor normalization (including certificate binding registration). - TEST: No tests for AuthorityIdentityProviderHandle disposal semantics or AuthorityClaimsEnrichmentContext Items behavior. - Proposed changes (pending approval): enable TreatWarningsAsErrors, add explicit test SDK/runner references or document reliance on shared props, normalize formatting, and add coverage for manifest capabilities, secret hashing, client descriptor normalization, and handle/context behavior. +- Disposition: skipped (test project; no apply changes) ### src/Authority/StellaOps.Authority/StellaOps.Authority.Tests/StellaOps.Authority.Tests.csproj - MAINT: TreatWarningsAsErrors is not set in the project file; warning discipline is relaxed for the test suite. - MAINT: Test project lacks explicit test SDK/runner references (Microsoft.NET.Test.Sdk/xUnit); discovery depends on shared props/packages. @@ -855,12 +948,14 @@ - TEST: Selector/registry tests do not cover credential store or claims enricher usage (stubs throw), leaving those interactions unvalidated. - TEST: Time-bound behavior is only exercised with the system clock; no deterministic boundary tests for expiration/nbf, replay windows, or rate limiting. - Proposed changes (pending approval): enable TreatWarningsAsErrors, add explicit test SDK/xUnit references or document central package usage, replace non-ASCII markers with ASCII, use fixed timestamps/IDs or a fake time provider, replace throwing test doubles with safe stubs, add assertions in OTel trace tests, add coverage for credential store/claims enricher selection and time-bound edges, and scope environment variable/OpenSSL overrides with cleanup (EnvironmentVariableScope or fixture). +- Disposition: skipped (test project; no apply changes) ### src/__Tests/__Benchmarks/binary-lookup/StellaOps.Bench.BinaryLookup.csproj - MAINT: TreatWarningsAsErrors is not set in the project file; warning discipline is relaxed for the benchmark suite. - MAINT: Benchmark helpers implement Hamming similarity and cache logic locally; if production logic diverges, results can drift from real workloads. - MAINT: Benchmarks use synthetic in-memory data only; no optional fixture path to validate performance against real datasets. - TEST: No tests cover benchmark helper logic (fingerprint generation, similarity, cache key construction); correctness relies on visual inspection. - Proposed changes (pending approval): enable TreatWarningsAsErrors, reuse or mirror production helpers where possible, add optional fixture-driven inputs, and add minimal smoke tests for helper logic if it remains in this project. +- Disposition: skipped (test project; no apply changes) ### src/Bench/StellaOps.Bench/LinkNotMerge/StellaOps.Bench.LinkNotMerge/StellaOps.Bench.LinkNotMerge.csproj - MAINT: TreatWarningsAsErrors is false in the project file; warning discipline is relaxed. - MAINT: ProgramOptions.Parse uses int.Parse/double.Parse without TryParse or structured error reporting; invalid input yields generic exceptions. @@ -869,6 +964,7 @@ - MAINT: JSON metadata uses DateTimeOffset.UtcNow when --captured-at is absent; outputs are nondeterministic unless callers pin the timestamp. - TEST: No tests cover CLI parsing, CSV/JSON/Prometheus writers, or failure reporting paths; coverage only exists for helper classes in the tests project. - Proposed changes (pending approval): enable TreatWarningsAsErrors, add TryParse with contextual errors or move to a CLI parser, allow env var or explicit defaults for config/baseline, thread cancellation tokens, require captured-at for deterministic output, and add tests for CLI parsing and writers. +- Disposition: skipped (benchmark/sample project; no apply changes) ### src/Bench/StellaOps.Bench/LinkNotMerge/StellaOps.Bench.LinkNotMerge.Tests/StellaOps.Bench.LinkNotMerge.Tests.csproj - MAINT: TreatWarningsAsErrors is false in the project file; warning discipline is relaxed for the test suite. - MAINT: Test project lacks explicit test SDK and xUnit package references; discovery depends on shared props/packages. @@ -877,6 +973,7 @@ - TEST: No tests for BenchmarkConfig validation (invalid counts, batch size > observations) or ObservationGenerator content hashing. - TEST: No tests for TablePrinter, CsvWriter, BenchmarkJsonWriter, or PrometheusWriter output formatting. - Proposed changes (pending approval): enable TreatWarningsAsErrors, add explicit test SDK/xUnit references or document shared package usage, normalize formatting, and add coverage for CLI parsing, config validation, writer outputs, and generator/linkset aggregation behavior. +- Disposition: skipped (test project; no apply changes) ### src/Bench/StellaOps.Bench/LinkNotMerge.Vex/StellaOps.Bench.LinkNotMerge.Vex/StellaOps.Bench.LinkNotMerge.Vex.csproj - MAINT: TreatWarningsAsErrors is false in the project file; warning discipline is relaxed. - MAINT: ProgramOptions.Parse uses int.Parse/double.Parse without TryParse or structured error reporting; invalid input yields generic exceptions. @@ -885,6 +982,7 @@ - MAINT: JSON metadata uses DateTimeOffset.UtcNow when --captured-at is absent; outputs are nondeterministic unless callers pin the timestamp. - TEST: No tests cover CLI parsing, CSV/JSON/Prometheus writers, or failure reporting paths; coverage only exists for helper classes in the tests project. - Proposed changes (pending approval): enable TreatWarningsAsErrors, add TryParse with contextual errors or move to a CLI parser, allow env var or explicit defaults for config/baseline, thread cancellation tokens, require captured-at for deterministic output, and add tests for CLI parsing and writers. +- Disposition: skipped (benchmark/sample project; no apply changes) ### src/Bench/StellaOps.Bench/LinkNotMerge.Vex/StellaOps.Bench.LinkNotMerge.Vex.Tests/StellaOps.Bench.LinkNotMerge.Vex.Tests.csproj - MAINT: TreatWarningsAsErrors is false in the project file; warning discipline is relaxed for the test suite. - MAINT: Test project lacks explicit test SDK and xUnit package references; discovery depends on shared props/packages. @@ -894,6 +992,7 @@ - TEST: No tests for TablePrinter, CsvWriter, BenchmarkJsonWriter, or PrometheusWriter output formatting. - TEST: No tests for VexLinksetAggregator event emission logic with mixed statuses/justifications. - Proposed changes (pending approval): enable TreatWarningsAsErrors, add explicit test SDK/xUnit references or document shared package usage, normalize formatting, and add coverage for CLI parsing, config validation, writer outputs, generator hashing, and aggregator event emission. +- Disposition: skipped (test project; no apply changes) ### src/Bench/StellaOps.Bench/Notify/StellaOps.Bench.Notify/StellaOps.Bench.Notify.csproj - MAINT: TreatWarningsAsErrors is false in the project file; warning discipline is relaxed. - MAINT: ProgramOptions.Parse uses int.Parse/double.Parse without TryParse or structured error reporting; invalid input yields generic exceptions. @@ -903,6 +1002,7 @@ - MAINT: CsvWriter does not guard against null/empty path and allows caller to pass invalid path values. - TEST: No tests cover CLI parsing, CSV/JSON writers, or failure reporting paths; coverage is partial via helper tests only. - Proposed changes (pending approval): enable TreatWarningsAsErrors, add TryParse with contextual errors or move to a CLI parser, allow env var or explicit defaults for config/baseline, thread cancellation tokens, require captured-at for deterministic output, validate CSV/JSON path inputs, and add tests for CLI parsing and writers. +- Disposition: skipped (benchmark/sample project; no apply changes) ### src/Bench/StellaOps.Bench/Notify/StellaOps.Bench.Notify.Tests/StellaOps.Bench.Notify.Tests.csproj - MAINT: TreatWarningsAsErrors is false in the project file; warning discipline is relaxed for the test suite. - MAINT: Test project lacks explicit test SDK and xUnit package references; discovery depends on shared props/packages. @@ -912,6 +1012,7 @@ - TEST: No tests for CsvWriter or BenchmarkJsonWriter output formatting. - TEST: No tests for DispatchAccumulator failure path (no values) or NotifyScenarioRunner failure messages. - Proposed changes (pending approval): enable TreatWarningsAsErrors, add explicit test SDK/xUnit references or document shared package usage, normalize formatting, and add coverage for CLI parsing, config validation, writer outputs, and failure-path assertions. +- Disposition: skipped (test project; no apply changes) ### src/Bench/StellaOps.Bench/PolicyEngine/StellaOps.Bench.PolicyEngine/StellaOps.Bench.PolicyEngine.csproj - MAINT: TreatWarningsAsErrors is false in the project file; warning discipline is relaxed. - MAINT: ProgramOptions.Parse uses int.Parse/double.Parse without TryParse or structured error reporting; invalid input yields generic exceptions. @@ -921,6 +1022,7 @@ - MAINT: SyntheticFindingGenerator uses Guid.NewGuid for layer digests, making benchmark data nondeterministic even with fixed seeds. - TEST: No test project for this benchmark; no coverage for config parsing, path resolution, or generator/evaluation helpers. - Proposed changes (pending approval): enable TreatWarningsAsErrors, add TryParse with contextual errors or move to a CLI parser, allow env var or explicit defaults for config/baseline, thread cancellation tokens, require captured-at for deterministic output, replace Guid.NewGuid with seeded random bytes, and add a test project covering config validation, path utilities, generator determinism, and evaluation outputs. +- Disposition: skipped (benchmark/sample project; no apply changes) ### src/__Tests/__Benchmarks/proof-chain/StellaOps.Bench.ProofChain.csproj - MAINT: TreatWarningsAsErrors is not set in the project file; warning discipline is relaxed for the benchmark suite. - MAINT: Benchmarks use RandomNumberGenerator.Fill, Guid.NewGuid, and DateTimeOffset.UtcNow for payloads/IDs; inputs are nondeterministic, so runs are not reproducible. @@ -928,6 +1030,7 @@ - MAINT: Benchmarks simulate verification logic instead of exercising production pipeline; results can drift from real costs. - TEST: No tests cover benchmark helper logic, Merkle root computation, or determinism of bundle assembly. - Proposed changes (pending approval): enable TreatWarningsAsErrors, switch to deterministic seeded data, remove or use the unused prefix parameter, consider reusing production verification helpers, and add minimal smoke tests for helper logic. +- Disposition: skipped (test project; no apply changes) ### src/Bench/StellaOps.Bench/Scanner.Analyzers/StellaOps.Bench.ScannerAnalyzers/StellaOps.Bench.ScannerAnalyzers.csproj - MAINT: TreatWarningsAsErrors is false in the project file; warning discipline is relaxed. - MAINT: ProgramOptions.Parse uses int.Parse/double.Parse without TryParse or structured error reporting; invalid input yields generic exceptions. @@ -935,6 +1038,7 @@ - MAINT: CsvWriter does not guard against null/empty path and allows caller to pass invalid path values. - TEST: No tests cover ProgramOptions.Parse, scenario root resolution, or parser/analyzer runner determinism. - Proposed changes (pending approval): enable TreatWarningsAsErrors, add TryParse or CLI parser, allow explicit/deterministic time providers, validate CSV/JSON path inputs, and add tests for CLI parsing, root resolution, and analyzer runner determinism. +- Disposition: skipped (benchmark/sample project; no apply changes) ### src/Bench/StellaOps.Bench/Scanner.Analyzers/StellaOps.Bench.ScannerAnalyzers.Tests/StellaOps.Bench.ScannerAnalyzers.Tests.csproj - MAINT: TreatWarningsAsErrors is false in the project file; warning discipline is relaxed for the test suite. - MAINT: Test project lacks explicit test SDK and xUnit package references; discovery depends on shared props/packages. @@ -942,6 +1046,7 @@ - TEST: No tests for BenchmarkConfig validation errors or ScenarioRunnerFactory error paths. - TEST: No tests for GlobToRegex parsing, metadata walk parser error handling, or NodeBenchMetrics determinism. - Proposed changes (pending approval): enable TreatWarningsAsErrors, add explicit test SDK/xUnit references or document shared package usage, normalize formatting, and add coverage for config validation, scenario runner factory errors, glob matching, and NodeBenchMetrics stability. +- Disposition: skipped (test project; no apply changes) ### src/BinaryIndex/__Libraries/StellaOps.BinaryIndex.Builders/StellaOps.BinaryIndex.Builders.csproj - MAINT: TreatWarningsAsErrors is false in the project file; warning discipline is relaxed. - MAINT: FingerprintClaim defaults CreatedAt to DateTimeOffset.UtcNow and ReproducibleBuildJob uses Guid.NewGuid/DateTimeOffset.UtcNow directly; determinism and testability suffer without a time/ID provider. @@ -952,6 +1057,7 @@ - TEST: No tests cover PatchDiffEngine similarity thresholds, rename detection, or option handling (Weights/FuzzyNameMatching). - TEST: No tests cover Guid.Parse failure handling or claim CreatedAt determinism. - Proposed changes (pending approval): enable TreatWarningsAsErrors, inject time/ID providers, handle non-GUID BuildId gracefully, honor DiffOptions.Weights/FuzzyNameMatching, replace non-ASCII arrows with ASCII, bind options from configuration, and add tests for diff engine options, rename handling, and claim creation paths. +- Disposition: pending implementation (non-test project; apply recommendations remain open) ### src/BinaryIndex/__Tests/StellaOps.BinaryIndex.Builders.Tests/StellaOps.BinaryIndex.Builders.Tests.csproj - MAINT: TreatWarningsAsErrors is not set in the project file; warning discipline is relaxed for the test suite. - MAINT: Test project lacks explicit test SDK reference; discovery depends on shared props/packages. @@ -961,6 +1067,7 @@ - TEST: No tests cover PatchDiffEngine behavior (weights, rename detection, duplicate names). - TEST: No tests cover ServiceCollectionExtensions option binding or BuilderServiceOptions defaults. - Proposed changes (pending approval): enable TreatWarningsAsErrors, add explicit test SDK/xUnit references or document shared package usage, remove unused Testcontainers dependency, replace non-ASCII comment markers, use deterministic IDs in helpers, and add tests for PatchDiffEngine options and DI option binding. +- Disposition: skipped (test project; no apply changes) ### src/BinaryIndex/__Libraries/StellaOps.BinaryIndex.Cache/StellaOps.BinaryIndex.Cache.csproj - MAINT: TreatWarningsAsErrors is false in the project file; warning discipline is relaxed. - MAINT: InvalidateDistroAsync uses server.Keys without paging; full keyspace scans can block and delete bursts can stall on large caches. @@ -971,6 +1078,7 @@ - TEST: No tests project for this library; no coverage for cache key generation, TTL selection, early expiry behavior, invalidation, or serialization fallbacks. - TEST: No tests for configuration binding or validation of BinaryCacheOptions/ResolutionCacheOptions. - Proposed changes (pending approval): enable TreatWarningsAsErrors, add options validation for TTLs/prefix/early expiry factors, inject a deterministic random source for early expiry, replace server.Keys invalidation with paged scans or explicit key indexes, use full fingerprint hashes (or document and test truncation), replace misses.First with a lookup map, and add a cache test project covering keys/TTL/early expiry/invalidation and binding validation. +- Disposition: pending implementation (non-test project; apply recommendations remain open) ### src/BinaryIndex/__Libraries/StellaOps.BinaryIndex.Contracts/StellaOps.BinaryIndex.Contracts.csproj - MAINT: TreatWarningsAsErrors is false in the project file; warning discipline is relaxed. - MAINT: VulnResolutionResponse.ResolvedAt is non-nullable but not marked required; default timestamps can slip into responses if not explicitly set. @@ -980,6 +1088,7 @@ - TEST: No tests project for contract serialization or validation attributes. - TEST: No tests for JSON round-trip or DataAnnotations validation of required fields and empty batches. - Proposed changes (pending approval): enable TreatWarningsAsErrors, mark ResolvedAt as required (or make it nullable), define enums or constants for MatchType/FixMethod, add validation to enforce at least one identifier and non-empty batch items, and add contract tests for JSON round-trip and validation. +- Disposition: pending implementation (non-test project; apply recommendations remain open) ### src/BinaryIndex/__Libraries/StellaOps.BinaryIndex.Core/StellaOps.BinaryIndex.Core.csproj - MAINT: TreatWarningsAsErrors is not set in the project file; warning discipline is relaxed. - MAINT: BinaryIdentity defaults CreatedAt/UpdatedAt to DateTimeOffset.UtcNow; time is not injectable and yields nondeterministic identities in tests. @@ -992,6 +1101,7 @@ - TEST: Existing feature extractor tests cover basic metadata/identity; missing tests for malformed headers, non-seekable streams, build-id parsing, and boundary conditions. - TEST: No tests for ResolutionService edge cases (missing identifiers, batch truncation, confidence threshold mapping) or BinaryIdentityService batch error behavior. - Proposed changes (pending approval): enable TreatWarningsAsErrors, inject TimeProvider (or time abstraction) for identities and resolution responses, validate identifier presence and return structured errors for empty identifiers, avoid placeholder hashes, add seekability checks or use buffered readers, stream build-id scanning for ELF, add telemetry or explicit errors for PE/Mach-O parsing failures, and add tests for malformed header cases, non-seekable streams, resolution mapping, and batch behavior. +- Disposition: pending implementation (non-test project; apply recommendations remain open) ### src/BinaryIndex/__Tests/StellaOps.BinaryIndex.Core.Tests/StellaOps.BinaryIndex.Core.Tests.csproj - MAINT: TreatWarningsAsErrors is not set in the project file; warning discipline is relaxed for the test suite. - MAINT: Test project lacks explicit test SDK/xUnit package references; discovery depends on shared props/packages. @@ -1001,6 +1111,7 @@ - TEST: No tests for ResolutionService or BinaryIdentityService behaviors (identifier validation, batch truncation, error paths). - TEST: No tests for non-seekable stream handling or malformed binary headers in feature extractors. - Proposed changes (pending approval): enable TreatWarningsAsErrors, add explicit test SDK/xUnit references or document shared package usage, replace Guid.NewGuid with deterministic IDs, clean non-ASCII comment markers, normalize indentation, and add tests for resolution flows, non-seekable streams, and malformed headers. +- Disposition: skipped (test project; no apply changes) ### src/BinaryIndex/__Libraries/StellaOps.BinaryIndex.Corpus/StellaOps.BinaryIndex.Corpus.csproj - MAINT: TreatWarningsAsErrors is not set in the project file; warning discipline is relaxed. - MAINT: IBinaryCorpusConnector.SupportedDistros exposes a mutable array; callers can mutate it and introduce nondeterministic behavior. @@ -1010,6 +1121,7 @@ - TEST: No tests project for corpus contract types or connector interface behaviors. - TEST: No tests for contract validation, snapshot key equality, or serialization round-trip. - Proposed changes (pending approval): enable TreatWarningsAsErrors, replace arrays with ImmutableArray/IReadOnlyList plus normalization, define UTC requirement for CapturedAt, validate digest format or introduce a digest value type, and add tests for contract validation and serialization. +- Disposition: pending implementation (non-test project; apply recommendations remain open) ### src/BinaryIndex/__Libraries/StellaOps.BinaryIndex.Corpus.Alpine/StellaOps.BinaryIndex.Corpus.Alpine.csproj - MAINT: TreatWarningsAsErrors is not set in the project file; warning discipline is relaxed. - MAINT: AlpineCorpusConnector uses Guid.NewGuid and DateTimeOffset.UtcNow for snapshots; time/ID are not injectable for deterministic tests. @@ -1023,6 +1135,7 @@ - TEST: No tests project for Alpine corpus connector/extractor behavior. - TEST: No tests for APKINDEX parsing, APK extraction correctness, or secfixes extraction integration in this library. - Proposed changes (pending approval): enable TreatWarningsAsErrors, inject TimeProvider/ID provider for snapshot creation, document or validate mirror selection, stream APK extraction and avoid whole-file buffering, correctly parse multi-part APK structure, add size limits for entry buffering, make Dependencies/Provides immutable collections, normalize ASCII comments, and add tests for APKINDEX parsing, APK extraction, and secfixes extraction paths. +- Disposition: pending implementation (non-test project; apply recommendations remain open) ### src/BinaryIndex/__Libraries/StellaOps.BinaryIndex.Corpus.Debian/StellaOps.BinaryIndex.Corpus.Debian.csproj - MAINT: TreatWarningsAsErrors is not set in the project file; warning discipline is relaxed. - MAINT: DebianCorpusConnector uses Guid.NewGuid and DateTimeOffset.UtcNow for snapshots; time/ID are not injectable for deterministic tests. @@ -1037,6 +1150,7 @@ - TEST: No tests project for Debian corpus connector/source/extractor behavior. - TEST: No tests for Packages.gz parsing, continuation lines, or extraction correctness. - Proposed changes (pending approval): enable TreatWarningsAsErrors, inject TimeProvider/ID provider for snapshot creation, document/validate mirror selection and distro path handling, preserve package size, stream package downloads and extraction with size guards, handle continuation lines in Packages.gz parsing, normalize package ordering before digest, and add tests for index parsing and extraction paths. +- Disposition: pending implementation (non-test project; apply recommendations remain open) ### src/BinaryIndex/__Libraries/StellaOps.BinaryIndex.Corpus.Rpm/StellaOps.BinaryIndex.Corpus.Rpm.csproj - MAINT: TreatWarningsAsErrors is not set in the project file; warning discipline is relaxed. - MAINT: RpmCorpusConnector uses Guid.NewGuid and DateTimeOffset.UtcNow for snapshots; time/ID are not injectable for deterministic tests. @@ -1050,6 +1164,7 @@ - TEST: No tests project for RPM corpus connector/extractor/changelog behavior. - TEST: No tests for primary.xml parsing, payload extraction (xz/gzip/zstd), or SRPM changelog extraction integration. - Proposed changes (pending approval): enable TreatWarningsAsErrors, inject TimeProvider/ID provider for snapshot creation, return immutable SupportedDistros, stream payload extraction with size guards, add decompression support for gzip/zstd (or detect and error), avoid large header buffering, add seekability checks, normalize package ordering before digest, clean ASCII comments, and add tests for index parsing and payload extraction. +- Disposition: pending implementation (non-test project; apply recommendations remain open) ### src/BinaryIndex/__Libraries/StellaOps.BinaryIndex.Fingerprints/StellaOps.BinaryIndex.Fingerprints.csproj - MAINT: TreatWarningsAsErrors is not set in the project file; warning discipline is relaxed. - MAINT: ReferenceBuildPipeline uses Guid.NewGuid and DateTimeOffset.UtcNow for fingerprint IDs and IndexedAt; time/ID are not injectable for deterministic runs. @@ -1066,6 +1181,7 @@ - TEST: No tests for ReferenceBuildPipeline behaviors (empty artifacts, storage path generation, repository writes). - TEST: FingerprintMatcher tests do not cover MatchOptions.Algorithms, Architecture filter behavior, or details population on no match. - Proposed changes (pending approval): enable TreatWarningsAsErrors, inject TimeProvider/ID provider into ReferenceBuildPipeline, enforce or validate placeholder pipeline states, honor MatchOptions.Algorithms in matcher, clarify architecture semantics, make match details consistent, document or change combined fingerprint layout, normalize arrays to immutable collections, clean ASCII comments, and add tests for CFG/string/combined generators plus pipeline/matcher option handling. +- Disposition: pending implementation (non-test project; apply recommendations remain open) ### src/BinaryIndex/__Tests/StellaOps.BinaryIndex.Fingerprints.Tests/StellaOps.BinaryIndex.Fingerprints.Tests.csproj - MAINT: TreatWarningsAsErrors is not set in the project file; warning discipline is relaxed for the test suite. - MAINT: Test project lacks explicit test SDK/xUnit package references; discovery depends on shared props/packages. @@ -1076,6 +1192,7 @@ - TEST: No tests for ReferenceBuildPipeline or FingerprintBlobStorage placeholder behaviors. - TEST: No tests for MatchOptions.Algorithms/Architecture handling or Details population when no candidates. - Proposed changes (pending approval): enable TreatWarningsAsErrors, add explicit test SDK/xUnit references or document shared package usage, replace nondeterministic IDs/timestamps with deterministic fixtures, clean ASCII comments, and add tests for CFG/string/combined generators, matcher options, and pipeline/storage behaviors. +- Disposition: skipped (test project; no apply changes) ### src/BinaryIndex/__Libraries/StellaOps.BinaryIndex.FixIndex/StellaOps.BinaryIndex.FixIndex.csproj - MAINT: TreatWarningsAsErrors is not set in the project file; warning discipline is relaxed. - MAINT: FixEvidence.CreatedAt and SecurityFeedEvidence.PublishedAt are set with DateTimeOffset.UtcNow in parsers; time is not injectable for deterministic tests. @@ -1090,6 +1207,7 @@ - TEST: No dedicated FixIndex tests project; parser coverage exists only via Core tests (indirect). - TEST: No tests for DebianChangelogParser/RpmChangelogParser excerpt truncation, secfixes regex edge cases, or patch header parsing limits. - Proposed changes (pending approval): enable TreatWarningsAsErrors, inject TimeProvider for evidence timestamps, wire parsers via DI/options, normalize distro/release casing, make confidence values configurable, add safer excerpt truncation preserving line boundaries, validate patch header encoding, clean ASCII comments, and add direct FixIndex parser tests. +- Disposition: pending implementation (non-test project; apply recommendations remain open) ### src/BinaryIndex/__Libraries/StellaOps.BinaryIndex.Persistence/StellaOps.BinaryIndex.Persistence.csproj - MAINT: TreatWarningsAsErrors is not set in the project file; warning discipline is relaxed. - MAINT: BinaryIndexDbContext uses string interpolation to set app.tenant_id; tenant IDs are not validated or parameterized, risking SQL injection or invalid UUID errors. @@ -1104,6 +1222,7 @@ - TEST: No tests for FixIndexRepository, FingerprintRepository, BinaryVulnAssertionRepository, BinaryVulnerabilityService, or BinaryIndexMigrationRunner. - TEST: No coverage for RLS tenant enforcement or invalid tenant IDs. - Proposed changes (pending approval): enable TreatWarningsAsErrors, parameterize tenant_id setting with UUID validation, use a stable advisory lock hash, add migration history tracking and transaction scopes, wire Dapper CommandDefinition with cancellation tokens, fix FixMethod string mapping, use GetFieldValue for timestamps, implement fingerprint repository read paths, add batching to services, and add persistence tests for repositories/migrations/RLS. +- Disposition: pending implementation (non-test project; apply recommendations remain open) ### src/BinaryIndex/__Tests/StellaOps.BinaryIndex.Persistence.Tests/StellaOps.BinaryIndex.Persistence.Tests.csproj - MAINT: TreatWarningsAsErrors is not set in the project file; warning discipline is relaxed for the test suite. - MAINT: Test project lacks explicit test SDK/xUnit references; discovery depends on shared props/packages. @@ -1113,6 +1232,7 @@ - TEST: No tests for FixIndexRepository, FingerprintRepository, BinaryVulnAssertionRepository, or BinaryVulnerabilityService. - TEST: No tests for BinaryIndexMigrationRunner or migration idempotency. - Proposed changes (pending approval): enable TreatWarningsAsErrors, add explicit test SDK/xUnit references or document shared usage, reclassify integration tests with proper category, use deterministic fixtures for IDs/times, add RLS/multi-tenant tests, and add integration coverage for missing repositories and migrations. +- Disposition: skipped (test project; no apply changes) ### src/BinaryIndex/__Libraries/StellaOps.BinaryIndex.VexBridge/StellaOps.BinaryIndex.VexBridge.csproj - MAINT: TreatWarningsAsErrors is false in the project file; warning discipline is relaxed. - MAINT: VexEvidenceGenerator uses DateTimeOffset.UtcNow in multiple places; no TimeProvider injection for deterministic output. @@ -1129,6 +1249,7 @@ - TEST: No tests for evidence payload schema content (schema_version, evidence_ref, resolved_at formatting). - TEST: No tests for external link handling or PURL parsing edge cases. - Proposed changes (pending approval): enable TreatWarningsAsErrors, inject TimeProvider, avoid exception flow for below-threshold items, share a single timestamp per observation, propagate actual algorithm, harden PURL parsing, make external link generation configurable, surface DSSE failure metadata, add schema validation helpers, clean ASCII comments, and add tests for DSSE paths, schema fields, and link handling. +- Disposition: pending implementation (non-test project; apply recommendations remain open) ### src/BinaryIndex/__Tests/StellaOps.BinaryIndex.VexBridge.Tests/StellaOps.BinaryIndex.VexBridge.Tests.csproj - MAINT: TreatWarningsAsErrors is not set in the project file; warning discipline is relaxed for the test suite. - MAINT: Test project lacks explicit test SDK/xUnit references; discovery depends on shared props/packages. @@ -1139,6 +1260,7 @@ - TEST: No tests for observation timestamp consistency (createdAt/lastObserved/receivedAt). - TEST: No tests for PURL parsing or external link suppression behavior. - Proposed changes (pending approval): enable TreatWarningsAsErrors, add explicit test SDK/xUnit references or document shared usage, replace nondeterministic IDs/times with deterministic fixtures, add integration category tags, and add tests for DSSE behavior and timestamp consistency. +- Disposition: skipped (test project; no apply changes) ### src/BinaryIndex/StellaOps.BinaryIndex.WebService/StellaOps.BinaryIndex.WebService.csproj - MAINT: TreatWarningsAsErrors is false in the project file; warning discipline is relaxed. - MAINT: ResolutionCacheService is registered but not wired into IResolutionService; cache options and BypassCache have no effect. @@ -1153,6 +1275,7 @@ - TEST: No test project for WebService controllers, middleware, or DI wiring. - TEST: No tests for request validation, error mapping, rate limiting behavior, cache bypass wiring, or health/telemetry endpoints. - Proposed changes (pending approval): enable TreatWarningsAsErrors, wire ResolutionCacheService via a decorator or service integration, register rate limiting and telemetry with configuration (respect Enabled), inject TimeProvider for rate limiting/health timestamps, align ProblemDetails status codes and add explicit 500 responses, honor EnableDsseByDefault in single requests, remove duplicate health endpoint or document intent, clean ASCII comments, and add tests for controllers/middleware/DI wiring and error paths. +- Disposition: pending implementation (non-test project; apply recommendations remain open) ### src/__Libraries/StellaOps.Canonical.Json/StellaOps.Canonical.Json.csproj - MAINT: TreatWarningsAsErrors is not set in the project file; warning discipline is relaxed. - MAINT: Canonicalization uses JavaScriptEncoder.UnsafeRelaxedJsonEscaping; RFC 8785 alignment and escaping expectations are not documented or configurable. @@ -1164,6 +1287,7 @@ - TEST: Missing tests for CanonicalizeVersioned overload with JsonSerializerOptions, duplicate _canonVersion handling, and invalid JSON inputs for CanonicalizeParsedJson. - TEST: Missing tests for numeric edge cases (scientific notation/precision) and escaping/normalization alignment with RFC 8785. - Proposed changes (pending approval): enable TreatWarningsAsErrors, document or make encoder/naming policy configurable, skip or override existing _canonVersion fields, parse ReadOnlySpan without extra allocation, cache JsonSerializerOptions, and add tests for versioned overload, duplicate version field handling, invalid JSON inputs, and numeric/escaping edge cases. +- Disposition: pending implementation (non-test project; apply recommendations remain open) ### src/__Libraries/StellaOps.Canonical.Json.Tests/StellaOps.Canonical.Json.Tests.csproj - MAINT: TreatWarningsAsErrors is not set in the project file; warning discipline is relaxed for the test suite. - MAINT: Test project lacks explicit test SDK/xUnit package references; discovery depends on shared props/packages. @@ -1173,6 +1297,7 @@ - TEST: No tests for duplicate _canonVersion fields or invalid JSON inputs for CanonicalizeParsedJson. - TEST: No tests for numeric edge cases (scientific notation/precision) or RFC 8785 escaping alignment. - Proposed changes (pending approval): enable TreatWarningsAsErrors, add explicit test SDK/xUnit references or document shared usage, normalize attribute indentation, replace mojibake strings with explicit Unicode escapes, and add tests for versioned overloads, duplicate version fields, non-object roots, invalid JSON inputs, and numeric/escaping edge cases. +- Disposition: skipped (test project; no apply changes) ### src/__Libraries/StellaOps.Canonicalization/StellaOps.Canonicalization.csproj - MAINT: TreatWarningsAsErrors is not set in the project file; warning discipline is relaxed. - MAINT: CanonicalJsonSerializer uses JavaScriptEncoder.UnsafeRelaxedJsonEscaping and CamelCase naming without explicit documentation of RFC 8785 alignment or rationale. @@ -1186,6 +1311,7 @@ - TEST: No tests for StableDictionaryConverter ordering with non-string keys, null handling, or converter round-trip. - TEST: No tests for Iso8601DateTimeConverter parsing offsets, or DeterminismVerifier differences output. - Proposed changes (pending approval): enable TreatWarningsAsErrors, document canonicalization contract and escaping/naming policies, enforce string-only dictionary keys or provide stable key serialization, avoid global culture mutation by using explicit invariant formatting, handle null keys deterministically, parse date times with explicit DateTimeStyles, add error context for DeterminismVerifier parsing, and add tests for dictionary ordering, date parsing, and determinism compare. +- Disposition: pending implementation (non-test project; apply recommendations remain open) ### src/__Libraries/__Tests/StellaOps.Canonicalization.Tests/StellaOps.Canonicalization.Tests.csproj - MAINT: TreatWarningsAsErrors is not set in the project file; warning discipline is relaxed for the test suite. - MAINT: Test project lacks explicit test SDK/xUnit package references; discovery depends on shared props/packages. @@ -1196,6 +1322,7 @@ - TEST: Missing tests for Iso8601DateTimeConverter parse paths and offset-less inputs. - TEST: Missing tests for DeterminismVerifier Compare differences and error handling. - Proposed changes (pending approval): enable TreatWarningsAsErrors, add explicit test SDK/xUnit references or document shared usage, set IsTestProject, normalize attribute indentation, and add tests for converter edge cases, date parsing, and determinism verifier outputs. +- Disposition: skipped (test project; no apply changes) ### src/Cartographer/StellaOps.Cartographer/StellaOps.Cartographer.csproj - MAINT: TreatWarningsAsErrors is false in the project file; warning discipline is relaxed. - MAINT: Authority options are bound/validated manually and also registered via AddOptions; the singleton snapshot can diverge from reloaded options and there is no ValidateOnStart for the options pipeline. @@ -1204,6 +1331,7 @@ - MAINT: Program includes TODO placeholders for core graph builders/overlay workers/Authority client; service remains a skeleton. - TEST: No tests in this project for Program wiring, options validation, or health/readiness endpoints (coverage expected in separate tests project). - Proposed changes (pending approval): enable TreatWarningsAsErrors, consolidate options binding with ValidateOnStart and a single options source, wire authentication/authorization when Authority is enabled, add real health/readiness checks, and add tests for options validation and endpoint behavior. +- Disposition: pending implementation (non-test project; apply recommendations remain open) ### src/Cartographer/__Tests/StellaOps.Cartographer.Tests/StellaOps.Cartographer.Tests.csproj - MAINT: TreatWarningsAsErrors is not set in the project file; warning discipline is relaxed for the test suite. - MAINT: Test project lacks explicit test SDK/xUnit package references; discovery depends on shared props/packages. @@ -1212,6 +1340,7 @@ - TEST: Coverage exists for authority options defaults and validation errors. - TEST: Missing tests for Program configuration (options binding/validation, warnings), health and readiness endpoints, and authentication/authorization wiring. - Proposed changes (pending approval): enable TreatWarningsAsErrors, add explicit test SDK/xUnit references or document shared usage, set IsTestProject, add category traits, and add tests for Program wiring and health/readiness endpoints. +- Disposition: skipped (test project; no apply changes) ### src/__Tests/chaos/StellaOps.Chaos.Router.Tests/StellaOps.Chaos.Router.Tests.csproj - MAINT: TreatWarningsAsErrors is not set in the project file; warning discipline is relaxed for the test suite. - MAINT: Test project lacks explicit test SDK/xUnit package references; discovery depends on shared props/packages. @@ -1224,6 +1353,7 @@ - TEST: Coverage exists for backpressure, recovery, and Valkey failure scenarios. - TEST: Missing tests for deterministic retry-after parsing edge cases, rate limit headers presence expectations, and metrics contract validation. - Proposed changes (pending approval): enable TreatWarningsAsErrors, add explicit test SDK/xUnit references or document shared usage, set IsTestProject, normalize package indentation, add offline/air-gap guidance and container image pre-pull hooks, replace nondeterministic IDs/timestamps with deterministic fixtures where possible, add connectivity guards/skip for missing ROUTER_URL, and add focused assertions for Retry-After/metrics contracts. +- Disposition: skipped (test project; no apply changes) ### src/Cli/StellaOps.Cli/StellaOps.Cli.csproj - MAINT: TreatWarningsAsErrors is not set in the project file; warning discipline is relaxed. - MAINT: CLI project references `src/__Tests/__Libraries/StellaOps.Testing.Manifests` in production; test-only dependencies leak into runtime build. @@ -1235,7 +1365,9 @@ - MAINT: Non-ASCII glyphs and box-drawing characters are embedded in CLI output and sample configs; portability and ASCII-only logging guidance is inconsistent. - TEST: CLI tests exist (unit/golden/integration) for command factory/bootstrapper and several command groups. - TEST: Missing tests for Program entrypoint wiring (service registrations, options validation, AirGapEgressBlockedException path, cancellation exit codes). -- Proposed changes (pending approval): enable TreatWarningsAsErrors, move test-only references out of production csproj, refactor DI wiring into modules with options validation on startup, split CommandHandlers into focused files, replace csproj compile removes with feature flags or modules, inject time/ID providers for deterministic outputs, standardize ASCII-safe output or document Unicode output, and add tests for Program wiring and cancellation/egress error paths. +- Applied changes: added /tools command group for policy tools (policy-dsl-validate, policy-schema-export, policy-simulation-smoke) and moved implementations into shared library `src/__Libraries/StellaOps.Policy.Tools`; moved run manifest parsing into CLI to remove the test-only manifest dependency and added serializer tests. +- Proposed changes (pending approval): enable TreatWarningsAsErrors, refactor DI wiring into modules with options validation on startup, split CommandHandlers into focused files, replace csproj compile removes with feature flags or modules, inject time/ID providers for deterministic outputs, standardize ASCII-safe output or document Unicode output, and add tests for Program wiring and cancellation/egress error paths. +- Disposition: partial (tools command group integrated; manifest parsing moved into CLI; remaining recommendations pending) ### src/Cli/__Libraries/StellaOps.Cli.Plugins.Aoc/StellaOps.Cli.Plugins.Aoc.csproj - MAINT: TreatWarningsAsErrors is false in the project file; warning discipline is relaxed. - MAINT: Plugin build target copies only the plugin assembly and PDB into a fixed output folder; dependency/version isolation is not captured and stale binaries can accumulate. @@ -1250,6 +1382,7 @@ - TEST: No test project for this plugin. - TEST: Missing tests for command parsing/required options, `@since` parameter binding, dry-run behavior, error exit codes, and JSON/NDJSON output paths. - Proposed changes (pending approval): enable TreatWarningsAsErrors, bind and validate `@since` (parse to DateTimeOffset or explicit SHA mode), add parameter binding for tenant/since, move verification service to its own file with injected connection factory and time provider, treat database errors as exit code 1, stream NDJSON output, use shared deterministic serializer settings, replace Console usage with CLI output/logging, and add a tests project covering parsing, validation, parameter binding, dry-run, error handling, and outputs. +- Disposition: pending implementation (non-test project; apply recommendations remain open) ### src/Cli/__Libraries/StellaOps.Cli.Plugins.NonCore/StellaOps.Cli.Plugins.NonCore.csproj - MAINT: TreatWarningsAsErrors is false in the project file; warning discipline is relaxed. - MAINT: Plugin build target copies only the plugin assembly and PDB into a fixed output folder; dependency/version isolation is not captured and stale binaries can accumulate. @@ -1260,6 +1393,7 @@ - TEST: No test project for this plugin. - TEST: Missing tests for command parsing, option validation, conflict cases (for example `--file` plus `--image`), and handler invocation/exit codes. - Proposed changes (pending approval): enable TreatWarningsAsErrors, split command builders per area or move to helper classes, add option validation and mutual exclusion rules, enforce invariant parsing or explicit defaults, wire defaults at option-level for help text, and add a tests project with parsing and validation coverage. +- Disposition: pending implementation (non-test project; apply recommendations remain open) ### src/Cli/__Libraries/StellaOps.Cli.Plugins.Symbols/StellaOps.Cli.Plugins.Symbols.csproj - MAINT: TreatWarningsAsErrors is false in the project file; warning discipline is relaxed. - MAINT: Plugin build target copies only the plugin assembly and PDB into a fixed output folder; dependencies (Symbols.Core, Symbols.Client, Spectre.Console) are not copied and stale binaries can accumulate. @@ -1273,6 +1407,7 @@ - TEST: No test project for this plugin. - TEST: Missing tests for command parsing/validation, ingest format handling, upload/verify error handling, and client interaction behavior. - Proposed changes (pending approval): enable TreatWarningsAsErrors, copy plugin dependencies to output (or add a plugin load context), split execution into services with DI, implement or gate real symbol extraction/DSSE verification, validate inputs (paths, platform, server), add JSON error handling, use async IO with cancellation, standardize deterministic output, and add a tests project with parsing/validation/service behavior coverage. +- Disposition: pending implementation (non-test project; apply recommendations remain open) ### src/Cli/__Libraries/StellaOps.Cli.Plugins.Verdict/StellaOps.Cli.Plugins.Verdict.csproj - MAINT: TreatWarningsAsErrors is false in the project file; warning discipline is relaxed. - MAINT: Plugin build target copies only the plugin assembly and PDB into a fixed output folder; dependencies (Verdict library, Spectre.Console) are not copied and stale binaries can accumulate. @@ -1288,6 +1423,7 @@ - TEST: No test project for this plugin. - TEST: Missing tests for command parsing, API fetch behavior, signature verification modes, inputs hash validation, replay bundle checks, expiration handling, exit codes, and output formatting. - Proposed changes (pending approval): enable TreatWarningsAsErrors, copy plugin dependencies or add a plugin load context, split execution into services with DI, dispose or reuse HttpClient with timeouts, surface API errors with context, implement signature verification or add explicit "not supported" exit code, canonicalize inputs before hashing, fix exit code ordering for expiration, inject time provider, sort evidence graph output, standardize JSON output options, use async file IO with cancellation, and add a tests project covering parsing, fetch paths, hash/replay verification, expiration, and outputs. +- Disposition: pending implementation (non-test project; apply recommendations remain open) ### src/Cli/__Libraries/StellaOps.Cli.Plugins.Vex/StellaOps.Cli.Plugins.Vex.csproj - MAINT: TreatWarningsAsErrors is false in the project file; warning discipline is relaxed. - MAINT: Plugin build target copies only the plugin assembly and PDB into a fixed output folder; dependencies (Spectre.Console and any client libs) are not copied and stale binaries can accumulate. @@ -1304,6 +1440,7 @@ - TEST: No test project for this plugin. - TEST: Missing tests for option parsing/validation, exit codes on failure, API client query formatting, placeholder command behavior, and output formatting. - Proposed changes (pending approval): enable TreatWarningsAsErrors, copy plugin dependencies or add load context, split commands/DTOs/HTTP client into separate files with DI, replace mojibake with ASCII, enforce option validation and mutual exclusion, return non-zero exit codes on errors, implement or explicitly fail placeholder commands, handle CSV or remove it, use invariant formatting for query params, configure HttpClient via factory with timeouts, sort outputs, standardize JSON serializer options, and add tests covering parsing, validation, client formatting, and exit codes. +- Disposition: pending implementation (non-test project; apply recommendations remain open) ### src/Cli/__Tests/StellaOps.Cli.Tests/StellaOps.Cli.Tests.csproj - MAINT: TreatWarningsAsErrors is not set in the project file; warning discipline is relaxed for the test suite. - MAINT: Test project lacks explicit Microsoft.NET.Test.Sdk/xunit package references; discovery depends on shared props/packages. @@ -1314,6 +1451,7 @@ - TEST: Missing tests for CLI plugin command modules (AOC, VEX, Verdict, Symbols) and their option parsing/exit code behavior. - TEST: Proof command coverage is effectively missing because tests are excluded by the project file. - Proposed changes (pending approval): enable TreatWarningsAsErrors, add explicit test SDK/xunit references or document shared usage, re-enable ProofCommandTests or remove the stale file, delete or implement UnitTest1, normalize encoding artifacts to ASCII, and add plugin-module tests for parsing and exit codes. +- Disposition: skipped (test project; no apply changes) ### src/Concelier/__Analyzers/StellaOps.Concelier.Analyzers/StellaOps.Concelier.Analyzers.csproj - MAINT: TreatWarningsAsErrors is not set in the project file; warning discipline is relaxed. - MAINT: Analyzer targets netstandard2.0 while the repo targets .NET 10; alignment is not documented and may limit newer analyzer APIs. @@ -1322,6 +1460,7 @@ - TEST: No tests project for this analyzer. - TEST: Missing tests for positive/negative cases (connector namespace with new HttpClient, non-connector namespace, IHttpClientFactory usage). - Proposed changes (pending approval): enable TreatWarningsAsErrors, document netstandard target rationale or upgrade if feasible, use StringComparison.Ordinal in namespace checks, and add an analyzer tests project to validate diagnostics and suppression paths. +- Disposition: pending implementation (non-test project; apply recommendations remain open) ### src/Concelier/__Libraries/StellaOps.Concelier.Cache.Valkey/StellaOps.Concelier.Cache.Valkey.csproj - MAINT: TreatWarningsAsErrors is false in the project file; warning discipline is relaxed. - MAINT: CacheTtlPolicy.GetTtl ignores HighScoreThreshold/MediumScoreThreshold configuration and uses hardcoded 0.7/0.4; configuration knobs are ineffective. @@ -1337,6 +1476,7 @@ - TEST: CacheTtlPolicy tests do not assert custom thresholds (current tests pass even if thresholds are ignored). - TEST: Missing tests for connection factory (timeouts, reconnect, disabled mode), ValkeyCanonicalAdvisoryService caching behavior, cache warmup locking, metrics wiring, error paths, and PURL collision handling. - Proposed changes (pending approval): enable TreatWarningsAsErrors, respect configurable TTL thresholds, consider hashing for long PURL keys, replace non-ASCII comment artifacts, wire ConcelierCacheMetrics into cache operations, avoid disposing shared ActivitySource, use ConnectAsync with cancellation/timeouts, simplify decorator registration, make warmup delay configurable, and add tests for connection handling, decorator behavior, warmup locking, metrics, and PURL collisions. +- Disposition: pending implementation (non-test project; apply recommendations remain open) ### src/Concelier/__Tests/StellaOps.Concelier.Cache.Valkey.Tests/StellaOps.Concelier.Cache.Valkey.Tests.csproj - MAINT: TreatWarningsAsErrors is not set in the project file; warning discipline is relaxed for the test suite. - MAINT: Test project lacks explicit Microsoft.NET.Test.Sdk/xunit runner references; discovery depends on shared props/packages. @@ -1347,6 +1487,7 @@ - TEST: Coverage exists for AdvisoryCacheKeys and CacheTtlPolicy basics plus performance-style cache benchmarks. - TEST: Missing tests for ConcelierCacheConnectionFactory (connect/reconnect/cancellation), ValkeyAdvisoryCacheService read/write/error paths, ValkeyCanonicalAdvisoryService decorator behavior, cache warmup locking, and ConcelierCacheMetrics integration. - Proposed changes (pending approval): enable TreatWarningsAsErrors, add explicit test SDK/xunit references or document shared usage, normalize attribute indentation, gate performance benchmarks behind a performance trait or explicit flag, replace nondeterministic GUID/time data with deterministic fixtures, and add tests for connection handling, cache operations, decorator behavior, warmup locking, and metrics wiring. +- Disposition: skipped (test project; no apply changes) ### src/Concelier/__Libraries/StellaOps.Concelier.Connector.Acsc/StellaOps.Concelier.Connector.Acsc.csproj - MAINT: TreatWarningsAsErrors is not set in the project file; warning discipline is relaxed. - MAINT: `AcscConnector` has duplicate `using` statements and duplicated Accept header lists across `AcscConnector` and DI registration; configuration is easy to drift. @@ -1359,6 +1500,7 @@ - TEST: Coverage exists for fetch fallback behavior, parse/map integration snapshots, and HTTP client configuration. - TEST: Missing tests for `ProbeAsync` behaviors (HEAD/GET fallback and preference updates), `ForceRelay` misconfiguration paths, relay-disabled behavior, parser edge cases (Atom feeds, missing IDs), and deterministic key generation. - Proposed changes (pending approval): enable TreatWarningsAsErrors, consolidate Accept header configuration, surface ForceRelay misconfiguration as a failure, use invariant-only date parsing, replace GUID fallback IDs with stable hashes, clean non-ASCII trim characters, normalize field mask casing, and add tests for probe, relay misconfig, parser edge cases, and deterministic ID generation. +- Disposition: pending implementation (non-test project; apply recommendations remain open) ### src/Concelier/__Tests/StellaOps.Concelier.Connector.Acsc.Tests/StellaOps.Concelier.Connector.Acsc.Tests.csproj - MAINT: TreatWarningsAsErrors is not set in the project file; warning discipline is relaxed for the test suite. - MAINT: IsTestProject is not set; relies on SDK defaults rather than explicit test metadata. @@ -1367,6 +1509,7 @@ - TEST: Coverage exists for fetch fallback behavior, parse/map snapshots, and HTTP client configuration. - TEST: Missing tests for `ProbeAsync`, `ForceRelay` misconfiguration, relay-disabled behavior, Atom feed parsing, missing ID fallback determinism, and severity/field normalization. - Proposed changes (pending approval): enable TreatWarningsAsErrors, set IsTestProject, add explicit test SDK/xunit references or document shared usage, switch fixture copy to PreserveNewest, and add tests for probe/relay modes, Atom parsing, deterministic IDs, and field normalization. +- Disposition: skipped (test project; no apply changes) ### src/Concelier/__Libraries/StellaOps.Concelier.Connector.Cccs/StellaOps.Concelier.Connector.Cccs.csproj - MAINT: TreatWarningsAsErrors is not set in the project file; warning discipline is relaxed. - MAINT: CccsConnector.cs includes duplicate `using StellaOps.Concelier.Storage` directives, adding noise. @@ -1380,6 +1523,7 @@ - TEST: Coverage exists for fetch/parse/map integration, HTML parsing, and mapper outputs. - TEST: Missing tests for cursor serialization ordering, invariant date parsing, TrimKnownHashes deterministic eviction, BuildDocumentUri normalization, taxonomy failure handling, and reference URL normalization for lang parameters. - Proposed changes (pending approval): enable TreatWarningsAsErrors, remove duplicate usings and consolidate serializer options, replace Guid.NewGuid IDs with stable hashes/keys, sort pending/known hash collections before persisting and evict deterministically, enforce invariant date parsing, fix regex encoding artifacts, add taxonomy failure diagnostics, and add tests for cursor determinism, hash trimming, URI normalization, taxonomy failure, and lang parameter handling. +- Disposition: pending implementation (non-test project; apply recommendations remain open) ### src/Concelier/__Tests/StellaOps.Concelier.Connector.Cccs.Tests/StellaOps.Concelier.Connector.Cccs.Tests.csproj - MAINT: TreatWarningsAsErrors is not set in the project file; warning discipline is relaxed for the test suite. - MAINT: IsTestProject is not set; discovery relies on defaults rather than explicit test metadata. @@ -1389,6 +1533,7 @@ - TEST: Coverage exists for fetch/parse/map integration, HTML parser extraction, and mapper output. - TEST: Missing tests for TrimKnownHashes eviction determinism, cursor date parsing under non-invariant cultures, BuildDocumentUri normalization for relative URLs, taxonomy fetch failure behavior, and reference URL normalization for lang parameters. - Proposed changes (pending approval): enable TreatWarningsAsErrors, set IsTestProject, add explicit test SDK/xunit references or document central management, normalize attribute indentation, use fixed GUID/time in tests, and add tests for cursor determinism, hash trimming, URI normalization, taxonomy failures, and lang parameter handling. +- Disposition: skipped (test project; no apply changes) ### src/Concelier/__Libraries/StellaOps.Concelier.Connector.CertBund/StellaOps.Concelier.Connector.CertBund.csproj - MAINT: TreatWarningsAsErrors is not set in the project file; warning discipline is relaxed. - MAINT: CertBundConnector.cs includes duplicate `using StellaOps.Concelier.Storage` directives, adding noise. @@ -1400,6 +1545,7 @@ - TEST: Coverage exists for fetch/parse/map integration via connector tests. - TEST: Missing tests for feed parsing (advisoryId extraction, pubDate failures), detail parser error handling, cursor serialization determinism, known advisory trimming behavior, and severity mapping for German labels. - Proposed changes (pending approval): enable TreatWarningsAsErrors, remove duplicate usings, return null/MinValue on invalid pubDate with explicit logging, sort cursor collections before persisting, enforce invariant date parsing in cursor, use deterministic DTO IDs, track recency for known advisories, and add tests for feed parsing, parser failures, cursor ordering, trimming, and severity mapping. +- Disposition: pending implementation (non-test project; apply recommendations remain open) ### src/Concelier/__Tests/StellaOps.Concelier.Connector.CertBund.Tests/StellaOps.Concelier.Connector.CertBund.Tests.csproj - MAINT: TreatWarningsAsErrors is not set in the project file; warning discipline is relaxed for the test suite. - MAINT: IsTestProject is not set; discovery relies on defaults rather than explicit test metadata. @@ -2606,8 +2752,4 @@ ## Notes - Example projects waived at requester direction; APPLY tasks closed with no changes. - APPLY tasks remain pending approval of proposed changes for non-example projects. - - - - - +- Disposition: skipped (test project; no apply changes) diff --git a/docs/implplan/SPRINT_20251230_001_BE_backport_resolver_DESIGN.md b/docs/implplan/SPRINT_20251230_001_BE_backport_resolver_DESIGN.md new file mode 100644 index 000000000..2e3accc5c --- /dev/null +++ b/docs/implplan/SPRINT_20251230_001_BE_backport_resolver_DESIGN.md @@ -0,0 +1,678 @@ +# Backport Resolver Tiered Evidence - Implementation Design +**Sprint:** SPRINT_20251230_001_BE +**Version:** 1.0 +**Last Updated:** 2025-12-30 + +--- + +## Table of Contents +1. [Architecture Overview](#architecture-overview) +2. [Component Design](#component-design) +3. [Data Models](#data-models) +4. [Algorithms](#algorithms) +5. [Integration Points](#integration-points) +6. [Security & Compliance](#security--compliance) + +--- + +## 1. Architecture Overview + +### 1.1 Current State + +``` + + BackportStatusService + + EvalPatchedStatusAsync() + GetRulesAsync() from repository + EvaluateBoundaryRules() [STRING COMPARE ] + EvaluateRangeRules() [RETURNS UNKNOWN ] + Return verdict + + + + Consumes rules from + + + IFixRuleRepository + (OVAL/CSAF/Changelog rules) + - Only native distro + - No derivative mapping + +``` + +**Problems:** +- String comparison fails for version semantics (epoch, tildes, etc.) +- RangeRule logic not implemented always returns Unknown +- No cross-distro evidence reuse (AlmaLinux OVAL for RHEL) +- No bug ID CVE resolution + +### 1.2 Target State + +``` + + BackportStatusService + + EvalPatchedStatusAsync() + **Tier 1**: FetchRulesWithDerivativeMapping() [NEW] + Query RHEL try Alma/Rocky if not found + **Tier 2-4**: GetRulesAsync() (existing) + **Tier 5**: EvaluateRangeRules() [FIXED] + Hierarchical resolver with version comparators [NEW] + + + + IReadOnlyDictionary + RPM RpmVersionComparer (epoch:version-release) + Deb DebianVersionComparer (epoch:upstream-debian~pre) + Alpine ApkVersionComparer (X.Y.Z_pN-rN) + Fallback StringVersionComparer + + + + + Rules BugCVE mapping + + + IFixRuleRepository IBugCveMappingService + + DistroMappings DebianSecurityTracker + + ChangelogParser RedHatBugzilla (stub) + (with Bug IDs) UbuntuCVETracker + +``` + +--- + +## 2. Component Design + +### 2.1 BackportStatusService (Enhanced) + +**Responsibilities:** +- Orchestrate 5-tier evidence hierarchy +- Inject and delegate to version comparators +- Apply derivative distro mapping logic +- Aggregate evidence from multiple tiers +- Return confident verdicts with audit trails + +**Key Methods:** + +```csharp +public sealed class BackportStatusService +{ + private readonly IFixRuleRepository _ruleRepository; + private readonly IReadOnlyDictionary _comparators; + private readonly IBugCveMappingService? _bugMapper; // Optional + + // TIER 1: Try derivative OVAL/CSAF + private async ValueTask> FetchRulesWithDerivativeMapping( + BackportContext context, + PackageInstance package, + CveId cve, + CancellationToken ct); + + // TIER 2-4: Existing rule sources (unchanged) + // TIER 5: Evaluate NVD ranges with version comparators + private BackportVerdict EvaluateRangeRules( + CveId cve, + PackageInstance package, + IReadOnlyList rules); + + // Helper: Get comparator for ecosystem + private IVersionComparator GetComparatorForEcosystem(PackageEcosystem ecosystem) => + _comparators.GetValueOrDefault(ecosystem, StringVersionComparer.Instance); +} +``` + +**Dependency Injection:** + +```csharp +builder.Services.AddSingleton(); +builder.Services.AddSingleton(); +builder.Services.AddSingleton(); +builder.Services.AddSingleton(); +builder.Services.AddSingleton(); +``` + +--- + +### 2.2 DistroMappings (New Component) + +**File:** src/__Libraries/StellaOps.DistroIntel/DistroDerivative.cs + +**Purpose:** Define and query derivative distro relationships (RHELAlma/Rocky, etc.) + +**Data Model:** + +```csharp +public enum DerivativeConfidence +{ + High, // ABI-compatible rebuilds (Alma/Rocky RHEL) + Medium // Modified derivatives (Mint Ubuntu, Ubuntu Debian) +} + +public sealed record DistroDerivative( + string CanonicalDistro, // "rhel" + string DerivativeDistro, // "almalinux" + int MajorRelease, // 9 + DerivativeConfidence Confidence); + +public static class DistroMappings +{ + public static readonly ImmutableArray Derivatives = [...]; + + public static IEnumerable FindDerivativesFor( + string distro, + int majorRelease); + + public static decimal GetConfidenceMultiplier(DerivativeConfidence conf); +} +``` + +**Usage Pattern:** + +```csharp +// When fetching rules for Rocky 9: +var derivatives = DistroMappings.FindDerivativesFor("rhel", 9); +// Returns: [("rhel", "almalinux", 9, High), ("rhel", "rocky", 9, High)] + +foreach (var d in derivatives.OrderByDescending(x => x.Confidence)) +{ + var derivativeRules = await _repo.GetRulesAsync(ctx with { Distro = d.DerivativeDistro }, ...); + if (derivativeRules.Any()) + { + // Apply 0.95 multiplier for High confidence + return derivativeRules.Select(r => r with { + Confidence = r.Confidence * 0.95m + }); + } +} +``` + +--- + +### 2.3 IBugCveMappingService (New Interface) + +**File:** src/__Libraries/StellaOps.BugTracking/IBugCveMappingService.cs + +**Purpose:** Resolve distro bug IDs to CVE IDs + +**Interface:** + +```csharp +public interface IBugCveMappingService +{ + ValueTask> LookupCvesAsync( + BugId bugId, + CancellationToken ct = default); +} + +public sealed record BugId(string Tracker, string Id); +``` + +**Implementations:** + +1. **DebianSecurityTrackerClient** + - Source: https://security-tracker.debian.org/tracker/data/json + - Caching: 1h TTL, in-memory + +2. **RedHatBugzillaClient** (stub) + - Requires authentication cache pre-populated mappings + - Future: integrate with RHBZ API + +3. **UbuntuCVETrackerClient** + - Source: https://ubuntu.com/security/cves scraper + - Caching: 1h TTL + +4. **CompositeBugCveMappingService** + - Routes to correct implementation based on BugId.Tracker + +**Example:** + +```csharp +var bugId = new BugId("Debian", "987654"); +var cves = await _bugMapper.LookupCvesAsync(bugId); +// Returns: [CVE-2024-1234, CVE-2024-5678] +``` + +--- + +### 2.4 ChangelogParser (Enhanced) + +**File:** src/Concelier/__Libraries/StellaOps.Concelier.SourceIntel/ChangelogParser.cs + +**Changes:** +- Add regex patterns for bug IDs (Debian, RHBZ, Launchpad) +- Extend ChangelogEntry record to include BugIds collection +- Extract both CVE IDs and bug IDs in parallel + +**Updated Model:** + +```csharp +public sealed record ChangelogEntry( + string Version, + DateTimeOffset Date, + IReadOnlyList CveIds, + IReadOnlyList BugIds, // NEW + string Description); +``` + +**Regex Patterns:** + +```csharp +[GeneratedRegex(@"CVE-\d{4}-\d{4,}")] +private static partial Regex CvePatternRegex(); // Existing + +[GeneratedRegex(@"Closes:\s*#(\d+)", RegexOptions.IgnoreCase)] +private static partial Regex DebianBugRegex(); // NEW + +[GeneratedRegex(@"(?:RHBZ|rhbz)#(\d+)", RegexOptions.IgnoreCase)] +private static partial Regex RhBugzillaRegex(); // NEW + +[GeneratedRegex(@"LP:\s*#(\d+)", RegexOptions.IgnoreCase)] +private static partial Regex LaunchpadBugRegex(); // NEW +``` + +--- + +### 2.5 HunkSigExtractor (Enhanced) + +**File:** src/Feedser/StellaOps.Feedser.Core/HunkSigExtractor.cs + +**Changes:** +- Extract function signatures from patch context +- Populate PatchHunkSig.AffectedFunctions (currently null) +- Support C/C++, Python, Go function patterns + +**Function Extraction Logic:** + +```csharp +private static IReadOnlyList ExtractFunctionsFromContext(PatchHunk hunk) +{ + var functions = new HashSet(); + + // C/C++: "static void foo(" or "int bar(" + foreach (Match m in CFunctionRegex().Matches(hunk.Context)) + functions.Add(m.Groups[1].Value); + + // Python: "def foo(" or "class Bar:" + foreach (Match m in PythonFunctionRegex().Matches(hunk.Context)) + functions.Add(m.Groups[1].Value); + + // Go: "func (r *Receiver) Method(" + foreach (Match m in GoFunctionRegex().Matches(hunk.Context)) + functions.Add(m.Groups[1].Value); + + return functions.ToArray(); +} + +// Usage: +AffectedFunctions = ExtractFunctionsFromContext(hunk), +``` + +--- + +## 3. Data Models + +### 3.1 BackportVerdict (Existing, No Changes) + +```csharp +public sealed record BackportVerdict( + FixStatus Status, // Fixed | Vulnerable | Unknown + VerdictConfidence Confidence, // High | Medium | Low + RuleType EvidenceSource, // Boundary | Range | Changelog | Patch + EvidencePointer EvidencePointer, // URI, digest, timestamp + string? ConflictReason); +``` + +### 3.2 RulePriority (Updated Enum) + +```csharp +public enum RulePriority +{ + // Tier 1: OVAL/CSAF evidence + DistroNativeOval = 100, // Distro's own OVAL/CSAF + DerivativeOvalHigh = 95, // Alma/Rocky for RHEL + DerivativeOvalMedium = 90, // Mint for Ubuntu + + // Tier 2: Changelog evidence + ChangelogExplicitCve = 85, // Direct CVE mention + ChangelogBugIdMapped = 75, // Bug ID CVE mapping + + // Tier 3: Source patches + SourcePatchExactMatch = 70, // Exact hunk hash match + SourcePatchFuzzyMatch = 60, // Function name + context match + + // Tier 4: Upstream commits + UpstreamCommitExactParity = 55, // 100% hunk parity + UpstreamCommitPartialMatch = 45, // Partial context match + + // Tier 5: NVD range heuristic + NvdRangeHeuristic = 20 // Version range check (low confidence) +} +``` + +### 3.3 EvidencePointer (Existing, Extended) + +```csharp +public sealed record EvidencePointer( + string Type, // "OvalAdvisory" | "DebianChangelog" | "NvdCpeRange" + string Uri, // "oval:ALSA-2024-1234" | "deb:curl/changelog#L42" + string SourceDigest, // SHA-256 of artifact + DateTimeOffset FetchedAt); +``` + +**New URI Schemes:** +- derivative:almalinuxrhel:oval:ALSA-2024-1234 (Tier 1) +- changelog:debian:curl:1.2.3#bug:987654 (Tier 2 with bug ID) +- +vd:cve/CVE-2024-1234/cpe:2.3:a:vendor:product:* (Tier 5) + +--- + +## 4. Algorithms + +### 4.1 Hierarchical Evidence Resolver + +```pseudo +FUNCTION ResolveFixStatus(cve, package, distro, release): + + // TIER 1: Try derivative OVAL/CSAF + rules FetchNativeRules(distro, release, package, cve) + + IF rules.IsEmpty THEN + derivatives DistroMappings.FindDerivativesFor(distro, release) + FOR EACH derivative IN derivatives ORDER BY Confidence DESC: + derivativeRules FetchNativeRules( + derivative.DerivativeDistro, + release, + package, + cve) + + IF derivativeRules.IsNotEmpty THEN + confidenceMultiplier derivative.Confidence == High ? 0.95 : 0.80 + rules ApplyConfidencePenalty(derivativeRules, confidenceMultiplier) + BREAK // Use first successful derivative + END IF + END FOR + END IF + + // TIER 2-4: Existing sources (changelog, patches, commits) + IF rules.IsEmpty THEN + rules FetchEvidenceBasedRules(distro, package, cve) + END IF + + // TIER 5: NVD range fallback + IF rules.IsEmpty THEN + rules FetchNvdRangeRules(cve, package) + END IF + + // Evaluate rules with version comparators + RETURN EvaluateRulesWithVersionSemantics(rules, package) +END FUNCTION +``` + +### 4.2 Version Comparison with Ecosystem-Specific Logic + +```pseudo +FUNCTION CompareVersions(v1, v2, ecosystem): + comparator GetComparatorForEcosystem(ecosystem) + + MATCH ecosystem: + CASE RPM: + // Parse epoch:version-release + // Compare epoch first, then version, then release + // Handle ~ (pre-release) and ^ (post-release) + RETURN RpmVersionComparer.CompareWithProof(v1, v2) + + CASE Debian: + // Parse epoch:upstream-debian~pre + // Tilde sorting: 1.0~beta < 1.0 + RETURN DebianVersionComparer.CompareWithProof(v1, v2) + + CASE Alpine: + // Parse X.Y.Z_pN-rN + // _p = patch level, -r = package revision + RETURN ApkVersionComparer.CompareWithProof(v1, v2) + + DEFAULT: + // Fallback to SemVer or string comparison + RETURN StringVersionComparer.Compare(v1, v2) + END MATCH +END FUNCTION +``` + +### 4.3 Range Evaluation (Tier 5) + +```pseudo +FUNCTION EvaluateRangeRules(cve, package, rangeRules): + comparator GetComparatorForEcosystem(package.Ecosystem) + + FOR EACH rule IN rangeRules ORDER BY Priority DESC: + range rule.AffectedRange + inRange TRUE + + // Check lower bound + IF range.MinVersion IS NOT NULL THEN + cmp comparator.Compare(package.Version, range.MinVersion) + inRange inRange AND (range.MinInclusive ? cmp >= 0 : cmp > 0) + END IF + + // Check upper bound + IF range.MaxVersion IS NOT NULL THEN + cmp comparator.Compare(package.Version, range.MaxVersion) + inRange inRange AND (range.MaxInclusive ? cmp <= 0 : cmp < 0) + END IF + + IF inRange THEN + RETURN Verdict(Status: VULNERABLE, Confidence: LOW, Evidence: rule) + END IF + END FOR + + RETURN Verdict(Status: UNKNOWN, Confidence: LOW) +END FUNCTION +``` + +### 4.4 Confidence Scoring + +```pseudo +FUNCTION GetConfidenceForPriority(priority): + IF priority >= 75 THEN // Tier 1-2 + RETURN VerdictConfidence.High + ELSE IF priority >= 45 THEN // Tier 3-4 + RETURN VerdictConfidence.Medium + ELSE // Tier 5 + RETURN VerdictConfidence.Low + END IF +END FUNCTION +``` + +--- + +## 5. Integration Points + +### 5.1 Feedser Integration (Evidence Ingestion) + +**Components:** +- OvalFeedProcessor Tier 1 (OVAL advisory parsing) +- CsafFeedProcessor Tier 1 (CSAF VEX parsing) +- ChangelogFeedProcessor Tier 2 (enhanced with bug ID extraction) +- PatchFeedProcessor Tier 3 (HunkSigExtractor with functions) + +**Data Flow:** + +``` +Feedser Ingestion Pipeline + + OVAL/CSAF Normalize Store with distro tags + (almalinux, rocky, rhel) + + Changelogs Parse Extract CVEs + Bug IDs + Map Bug IDs to CVEs (async) + + Patches Extract hunks Compute hunk sigs + functions + Store in content-addressed storage +``` + +### 5.2 VexLens Integration (Verdict Consumption) + +**Components:** +- VexConsensusEngine Aggregates verdicts from BackportStatusService +- CycloneDxVexEmitter Emits signed VEX statements with evidence + +**Enhancements:** +- Include EvidencePointer URIs in VEX statements +- Add confidence field (mapped from VerdictConfidence) +- Annotate Tier 5 verdicts with justification: "range-based heuristic" + +**Example VEX Output:** + +```json +{ + "vulnerability": { + "id": "CVE-2024-1234" + }, + "analysis": { + "state": "resolved", + "justification": "code_not_present", + "responses": ["will_not_fix", "update"], + "detail": "Fixed in curl-7.76.1-26.el9_3.2 (backport)", + "confidence": "high", + "evidence": [ + { + "type": "OvalAdvisory", + "uri": "derivative:almalinuxrocky:oval:ALSA-2024-1234", + "digest": "sha256:abc123...", + "tier": 1 + } + ] + } +} +``` + +### 5.3 External API Integrations + +| API | Purpose | Caching | Fallback | +|-----|---------|---------|----------| +| Debian Security Tracker | Bug ID CVE mapping | 1h TTL | Skip bug ID evidence | +| Red Hat Bugzilla | Bug ID CVE mapping | Pre-populated cache | Skip bug ID evidence | +| Ubuntu CVE Tracker | Bug ID CVE mapping | 1h TTL | Skip bug ID evidence | + +**Rate Limiting:** +- Debian: No explicit limit, but batch requests every 5 minutes +- RHBZ: Requires auth, use cached dump +- Ubuntu: Scraper-based, respect robots.txt (1 req/sec) + +--- + +## 6. Security & Compliance + +### 6.1 Evidence Integrity + +**Requirements:** +- All evidence artifacts must be cryptographically hashed (SHA-256) +- Store SourceDigest in EvidencePointer +- Enable deterministic replay by re-fetching and re-hashing + +**Implementation:** + +```csharp +public static string ComputeDigest(byte[] artifact) => + Convert.ToHexString(SHA256.HashData(artifact)).ToLowerInvariant(); + +var digest = ComputeDigest(Encoding.UTF8.GetBytes(ovalXml)); +var pointer = new EvidencePointer( + Type: "OvalAdvisory", + Uri: $"oval:ALSA-2024-1234", + SourceDigest: digest, + FetchedAt: DateTimeOffset.UtcNow); +``` + +### 6.2 Audit Trail + +**Logging Requirements:** +- Log every tier attempted (1 2 ... 5) +- Log reason for tier fallback (e.g., "Tier 1: no OVAL found for rocky 9") +- Log derivative mapping decisions (e.g., "Using AlmaLinux OVAL for Rocky 9, confidence penalty 0.05") +- Log version comparison details (e.g., "1:2.0 > 3.0 (epoch wins)") + +**Structured Logging Format:** + +```json +{ + "timestamp": "2025-12-30T12:34:56Z", + "level": "INFO", + "message": "Tier 1 fallback: derivative OVAL found", + "cve": "CVE-2024-1234", + "package": "curl-7.76.1-26.el9_3.2", + "distro": "rocky 9", + "derivativeUsed": "almalinux 9", + "confidence": 0.95, + "tier": 1, + "evidenceUri": "derivative:almalinuxrocky:oval:ALSA-2024-1234" +} +``` + +### 6.3 Signed VEX Attestations + +**Signature Method:** in-toto/DSSE with Ed25519 keys + +**Signed Payload:** + +```json +{ + "payloadType": "application/vnd.cyclonedx+json", + "payload": "", + "signatures": [ + { + "keyid": "SHA256:abc123...", + "sig": "" + } + ] +} +``` + +**Replay Provenance:** +- Include feed snapshot digest +- Include resolver policy version +- Store signed attestation in content-addressed storage + +--- + +## 7. Performance Considerations + +### 7.1 Latency Targets + +| Tier | Operation | Target Latency | Notes | +|------|-----------|----------------|-------| +| 1 | Derivative OVAL query | <50ms | In-memory or local DB | +| 2 | Changelog parsing | <100ms | Pre-indexed by package version | +| 3 | Patch hunk matching | <150ms | Content-addressed lookup | +| 4 | Upstream commit mapping | <500ms | May require git fetch (cached) | +| 5 | NVD range check | <50ms | Simple version comparison | + +**Overall P95 Latency Goal:** <200ms for typical case (Tier 1-3) + +### 7.2 Caching Strategy + +**In-Memory Caches:** +- Bug ID CVE mappings: 1h TTL, max 10,000 entries +- Derivative OVAL queries: 5min TTL, max 5,000 entries +- Version comparison results: 10min TTL, max 50,000 entries + +**Persistent Caches:** +- OVAL/CSAF feeds: File-based, refresh every 6h +- Patch hunk signatures: Content-addressed storage (immutable) + +### 7.3 Scalability + +**Concurrency:** +- Parallel tier evaluation within single CVE (Tier 1-3 can run concurrently if needed) +- Bulk CVE scans: Process 100 CVEs in parallel with semaphore limit + +**Database Optimization:** +- Index on (distro, release, package_name, cve_id) +- Partition OVAL/CSAF rules by distro family (rhel, debian, alpine) + +--- + +**End of Design Document** diff --git a/docs/implplan/SPRINT_20251230_001_BE_backport_resolver_TESTS.md b/docs/implplan/SPRINT_20251230_001_BE_backport_resolver_TESTS.md new file mode 100644 index 000000000..0df49fc23 --- /dev/null +++ b/docs/implplan/SPRINT_20251230_001_BE_backport_resolver_TESTS.md @@ -0,0 +1,1039 @@ +# Backport Resolver Tiered Evidence - Test Specification +**Sprint:** SPRINT_20251230_001_BE +**Version:** 1.0 +**Last Updated:** 2025-12-30 + +--- + +## Table of Contents +1. [Test Strategy](#test-strategy) +2. [Unit Test Specifications](#unit-test-specifications) +3. [Integration Test Specifications](#integration-test-specifications) +4. [Golden Test Cases](#golden-test-cases) +5. [Performance Tests](#performance-tests) +6. [Test Data](#test-data) + +--- + +## 1. Test Strategy + +### 1.1 Testing Pyramid + +``` + /\ + / \ E2E Tests (5%) + /\ - Golden CVE scenarios + / \ - Full pipeline (Feedser Concelier VexLens) + /\ + / \ Integration Tests (25%) + /\ - Component interactions + / \ - External API mocking + /\ + / \ Unit Tests (70%) + /\ - Version comparators +/ \ - Tier logic + - Model validation +``` + +### 1.2 Test Coverage Goals + +| Component | Line Coverage | Branch Coverage | Notes | +|-----------|---------------|-----------------|-------| +| BackportStatusService | >90% | >85% | Critical path, all tiers | +| Version Comparators | 100% | 100% | Already achieved | +| DistroMappings | >85% | >80% | Static data + queries | +| BugCveMappingService | >75% | >70% | External API dependency | +| ChangelogParser | >90% | >85% | Regex-heavy, edge cases | +| HunkSigExtractor | >85% | >80% | Function extraction | + +### 1.3 Test Organization + +``` +tests/ + StellaOps.Concelier.BackportProof.Tests/ + Unit/ + BackportStatusServiceTests.cs + DistroMappingsTests.cs + RulePriorityTests.cs + Integration/ + DerivativeMappingIntegrationTests.cs + BugCveMappingIntegrationTests.cs + EndToEndResolverTests.cs + TestData/ + oval_fixtures/ + changelog_fixtures/ + golden_cases.json + + StellaOps.BugTracking.Tests/ + Unit/ + DebianSecurityTrackerClientTests.cs + CompositeBugCveMappingServiceTests.cs + + StellaOps.Feedser.Core.Tests/ + Unit/ + HunkSigExtractorTests.cs + ChangelogParserTests.cs +``` + +--- + +## 2. Unit Test Specifications + +### 2.1 BackportStatusService Unit Tests + +#### Test Suite: VersionComparatorIntegration + +**File:** BackportStatusServiceTests.cs + +```csharp +public class BackportStatusServiceTests +{ + private readonly BackportStatusService _sut; + private readonly Mock _mockRepo; + + [Theory] + [InlineData("1.2.10", "1.2.9", PackageEcosystem.Rpm, 1)] // 1.2.10 > 1.2.9 + [InlineData("1:2.0", "3.0", PackageEcosystem.Rpm, 1)] // Epoch wins + [InlineData("1.0~beta", "1.0", PackageEcosystem.Deb, -1)] // Tilde pre-release + [InlineData("1.2.3_p1-r0", "1.2.3-r0", PackageEcosystem.Alpine, 1)] // Alpine patch level + public async Task VersionComparison_UsesEcosystemSpecificComparer( + string version1, + string version2, + PackageEcosystem ecosystem, + int expectedSign) + { + // Arrange + var package = new PackageInstance( + new PackageKey("testpkg", ecosystem), + version1); + + var rule = new BoundaryRule( + CveId: "CVE-2024-1234", + FixedVersion: version2, + Priority: RulePriority.DistroNativeOval); + + _mockRepo.Setup(r => r.GetRulesAsync(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())) + .ReturnsAsync([rule]); + + // Act + var verdict = await _sut.EvalPatchedStatusAsync( + new BackportContext("rhel", 9), + package, + "CVE-2024-1234"); + + // Assert + if (expectedSign > 0) + verdict.Status.Should().Be(FixStatus.Fixed); + else + verdict.Status.Should().Be(FixStatus.Vulnerable); + } + + [Fact] + public async Task EpochVersionRelease_ParsedCorrectly_ForRpm() + { + // Test case: 2:7.76.1-26.el9_3.2 vs 7.77.0 + // Despite 7.76 < 7.77, epoch 2 means it's newer + + var package = new PackageInstance( + new PackageKey("curl", PackageEcosystem.Rpm), + "2:7.76.1-26.el9_3.2"); + + var rule = new BoundaryRule( + CveId: "CVE-2024-1234", + FixedVersion: "7.77.0", // No epoch = epoch 0 + Priority: RulePriority.DistroNativeOval); + + _mockRepo.Setup(r => r.GetRulesAsync(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())) + .ReturnsAsync([rule]); + + // Act + var verdict = await _sut.EvalPatchedStatusAsync( + new BackportContext("rhel", 9), + package, + "CVE-2024-1234"); + + // Assert + verdict.Status.Should().Be(FixStatus.Fixed); // Epoch 2 > epoch 0 + verdict.Confidence.Should().Be(VerdictConfidence.High); + } +} +``` + +--- + +#### Test Suite: RangeRuleEvaluation + +```csharp +[Fact] +public async Task RangeRule_VersionInRange_ReturnsVulnerable() +{ + // Arrange + var package = new PackageInstance( + new PackageKey("zlib", PackageEcosystem.Alpine), + "1.2.11-r3"); + + var rangeRule = new RangeRule( + CveId: "CVE-2024-99999", + AffectedRange: new VersionRange( + MinVersion: "1.2.0", + MinInclusive: true, + MaxVersion: "1.2.12", + MaxInclusive: false), + Priority: RulePriority.NvdRangeHeuristic); + + _mockRepo.Setup(r => r.GetRulesAsync(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())) + .ReturnsAsync([rangeRule]); + + // Act + var verdict = await _sut.EvalPatchedStatusAsync( + new BackportContext("alpine", 318), + package, + "CVE-2024-99999"); + + // Assert + verdict.Status.Should().Be(FixStatus.Vulnerable); + verdict.Confidence.Should().Be(VerdictConfidence.Low); // Tier 5 + verdict.EvidencePointer.Type.Should().Be("NvdCpeRange"); +} + +[Fact] +public async Task RangeRule_VersionOutOfRange_ReturnsFixed() +{ + var package = new PackageInstance( + new PackageKey("zlib", PackageEcosystem.Alpine), + "1.2.13-r0"); // Above max version + + var rangeRule = new RangeRule( + CveId: "CVE-2024-99999", + AffectedRange: new VersionRange( + MinVersion: "1.2.0", + MinInclusive: true, + MaxVersion: "1.2.12", + MaxInclusive: false), + Priority: RulePriority.NvdRangeHeuristic); + + _mockRepo.Setup(r => r.GetRulesAsync(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())) + .ReturnsAsync([rangeRule]); + + // Act + var verdict = await _sut.EvalPatchedStatusAsync( + new BackportContext("alpine", 318), + package, + "CVE-2024-99999"); + + // Assert (Note: out of range could mean either fixed OR not affected) + verdict.Status.Should().NotBe(FixStatus.Vulnerable); + verdict.Confidence.Should().Be(VerdictConfidence.Low); +} + +[Fact] +public async Task RangeRule_UnboundedMax_EvaluatesCorrectly() +{ + // Range: [1.0.0, ) all versions >= 1.0.0 are vulnerable + + var package = new PackageInstance( + new PackageKey("testpkg", PackageEcosystem.Rpm), + "2.5.0"); + + var rangeRule = new RangeRule( + CveId: "CVE-2024-1111", + AffectedRange: new VersionRange( + MinVersion: "1.0.0", + MinInclusive: true, + MaxVersion: null, // Unbounded + MaxInclusive: false), + Priority: RulePriority.NvdRangeHeuristic); + + _mockRepo.Setup(r => r.GetRulesAsync(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())) + .ReturnsAsync([rangeRule]); + + // Act + var verdict = await _sut.EvalPatchedStatusAsync( + new BackportContext("rhel", 9), + package, + "CVE-2024-1111"); + + // Assert + verdict.Status.Should().Be(FixStatus.Vulnerable); +} +``` + +--- + +### 2.2 DistroMappings Unit Tests + +**File:** DistroMappingsTests.cs + +```csharp +public class DistroMappingsTests +{ + [Theory] + [InlineData("rhel", 9, new[] { "almalinux", "rocky", "centos" })] + [InlineData("rhel", 8, new[] { "almalinux", "rocky" })] + [InlineData("ubuntu", 22, new[] { "linuxmint" })] + [InlineData("debian", 12, new[] { "ubuntu" })] + public void FindDerivativesFor_ReturnsExpectedDerivatives( + string distro, + int release, + string[] expectedDerivatives) + { + // Act + var derivatives = DistroMappings.FindDerivativesFor(distro, release); + + // Assert + derivatives.Select(d => d.DerivativeDistro) + .Should().BeEquivalentTo(expectedDerivatives); + } + + [Fact] + public void FindDerivativesFor_NoMatch_ReturnsEmpty() + { + var derivatives = DistroMappings.FindDerivativesFor("gentoo", 2024); + + derivatives.Should().BeEmpty(); + } + + [Theory] + [InlineData(DerivativeConfidence.High, 0.95)] + [InlineData(DerivativeConfidence.Medium, 0.80)] + public void GetConfidenceMultiplier_ReturnsCorrectValue( + DerivativeConfidence confidence, + decimal expectedMultiplier) + { + var multiplier = DistroMappings.GetConfidenceMultiplier(confidence); + + multiplier.Should().Be(expectedMultiplier); + } + + [Fact] + public void Derivatives_OrderedByConfidence_HighFirst() + { + var derivatives = DistroMappings.FindDerivativesFor("rhel", 9) + .ToList(); + + derivatives.Should().AllSatisfy(d => + d.Confidence.Should().Be(DerivativeConfidence.High)); + } +} +``` + +--- + +### 2.3 ChangelogParser Unit Tests + +**File:** ChangelogParserTests.cs + +```csharp +public class ChangelogParserTests +{ + private readonly ChangelogParser _parser = new(); + + [Fact] + public void ParseDebianChangelog_ExtractsBugIds() + { + var changelog = @" +curl (7.88.1-10+deb12u1) bookworm-security; urgency=high + + * Fix CVE-2024-1234: buffer overflow in cookie parsing + Closes: #987654 + + -- Debian Security Mon, 30 Dec 2024 10:00:00 +0000 +"; + + var entries = _parser.ParseDebian(changelog); + + entries.Should().ContainSingle(); + var entry = entries.First(); + + entry.CveIds.Should().Contain("CVE-2024-1234"); + entry.BugIds.Should().Contain(new BugId("Debian", "987654")); + } + + [Fact] + public void ParseRpmChangelog_ExtractsRhbzBugIds() + { + var changelog = @" +* Mon Dec 30 2024 Red Hat Security - 7.76.1-26.el9_3.2 +- Fix CVE-2024-5678 (RHBZ#123456) +- Backport upstream fix +"; + + var entries = _parser.ParseRpm(changelog); + + entries.Should().ContainSingle(); + var entry = entries.First(); + + entry.CveIds.Should().Contain("CVE-2024-5678"); + entry.BugIds.Should().Contain(new BugId("RHBZ", "123456")); + } + + [Fact] + public void ParseChangelog_MultipleCvesAndBugs_ExtractsAll() + { + var changelog = @" +curl (7.88.1-10+deb12u2) bookworm-security; urgency=high + + * Security fixes: + - CVE-2024-1111: denial of service (Closes: #111111) + - CVE-2024-2222: information disclosure (Closes: #222222) + - CVE-2024-3333: code execution (LP: #333333) + + -- Maintainer Mon, 30 Dec 2024 12:00:00 +0000 +"; + + var entries = _parser.ParseDebian(changelog); + + var entry = entries.First(); + + entry.CveIds.Should().HaveCount(3); + entry.BugIds.Should().HaveCount(3); + entry.BugIds.Should().Contain(new BugId("Debian", "111111")); + entry.BugIds.Should().Contain(new BugId("Debian", "222222")); + entry.BugIds.Should().Contain(new BugId("Launchpad", "333333")); + } + + [Fact] + public void ParseChangelog_NoBugIds_ReturnsEmptyBugList() + { + var changelog = @" +curl (7.88.1-10+deb12u1) bookworm; urgency=low + + * Non-security update + * Performance improvements + + -- Maintainer Mon, 30 Dec 2024 10:00:00 +0000 +"; + + var entries = _parser.ParseDebian(changelog); + + var entry = entries.First(); + + entry.BugIds.Should().BeEmpty(); + } +} +``` + +--- + +### 2.4 HunkSigExtractor Unit Tests + +**File:** HunkSigExtractorTests.cs + +```csharp +public class HunkSigExtractorTests +{ + private readonly HunkSigExtractor _extractor = new(); + + [Fact] + public void ExtractFunctions_CFunctionSignature_Extracted() + { + var patchContent = @" +--- a/ssl/ssl_lib.c ++++ b/ssl/ssl_lib.c +@@ -1234,7 +1234,7 @@ static int ssl_verify(SSL *ssl, X509 *cert) + { + if (!cert) { +- return 0; ++ return -1; // CVE-2024-1234 fix + } + return 1; + } +"; + + var hunks = _extractor.ExtractHunkSigs(patchContent); + + hunks.Should().ContainSingle(); + hunks.First().AffectedFunctions.Should().Contain("ssl_verify"); + } + + [Fact] + public void ExtractFunctions_PythonFunctionSignature_Extracted() + { + var patchContent = @" +--- a/lib/parser.py ++++ b/lib/parser.py +@@ -42,7 +42,7 @@ def parse_cookie(cookie_str): + if not cookie_str: +- return None ++ raise ValueError(\"Empty cookie\") # CVE-2024-5678 fix + return Cookie(cookie_str) +"; + + var hunks = _extractor.ExtractHunkSigs(patchContent); + + hunks.First().AffectedFunctions.Should().Contain("parse_cookie"); + } + + [Fact] + public void ExtractFunctions_GoMethodSignature_Extracted() + { + var patchContent = @" +--- a/pkg/server/handler.go ++++ b/pkg/server/handler.go +@@ -88,7 +88,7 @@ func (h *Handler) ProcessRequest(req *Request) error { + if req == nil { +- return nil ++ return errors.New(\"nil request\") // CVE-2024-9999 fix + } + return h.process(req) + } +"; + + var hunks = _extractor.ExtractHunkSigs(patchContent); + + hunks.First().AffectedFunctions.Should().Contain("ProcessRequest"); + } + + [Fact] + public void ExtractFunctions_MultipleFunctions_AllExtracted() + { + var patchContent = @" +--- a/crypto/rsa.c ++++ b/crypto/rsa.c +@@ -100,10 +100,10 @@ static int rsa_encrypt(RSA *rsa, const uint8_t *in, uint8_t *out) + { + // ... encryption logic + } + + static int rsa_decrypt(RSA *rsa, const uint8_t *in, uint8_t *out) + { +- // Vulnerable code ++ // Fixed code (CVE-2024-1234) + } +"; + + var hunks = _extractor.ExtractHunkSigs(patchContent); + + var functions = hunks.SelectMany(h => h.AffectedFunctions).Distinct(); + functions.Should().Contain("rsa_encrypt"); + functions.Should().Contain("rsa_decrypt"); + } +} +``` + +--- + +## 3. Integration Test Specifications + +### 3.1 Derivative Distro Mapping Integration + +**File:** DerivativeMappingIntegrationTests.cs + +```csharp +public class DerivativeMappingIntegrationTests +{ + private readonly BackportStatusService _sut; + private readonly InMemoryFixRuleRepository _repo; + + [Fact] + public async Task DerivativeMapping_AlmaLinuxOvalForRocky_SuccessWithConfidencePenalty() + { + // Arrange: AlmaLinux has OVAL, Rocky does not + var almaRule = new BoundaryRule( + CveId: "CVE-2024-1234", + FixedVersion: "7.76.1-26.el9_3.2", + Priority: RulePriority.DistroNativeOval, + Confidence: 1.0m); + + _repo.AddRule("almalinux", 9, "curl", almaRule); + + var package = new PackageInstance( + new PackageKey("curl", PackageEcosystem.Rpm), + "7.76.1-26.el9_3.2"); + + // Act: Query for Rocky 9 (should fallback to AlmaLinux) + var verdict = await _sut.EvalPatchedStatusAsync( + new BackportContext("rocky", 9), + package, + "CVE-2024-1234"); + + // Assert + verdict.Status.Should().Be(FixStatus.Fixed); + verdict.Confidence.Should().BeApproximately(VerdictConfidence.High, 0.05m); + verdict.EvidencePointer.Uri.Should().Contain("derivative:almalinuxrocky"); + } + + [Fact] + public async Task DerivativeMapping_NoDerivativeOval_FallsBackToNextTier() + { + // Arrange: No OVAL for Rocky or any derivative + + var package = new PackageInstance( + new PackageKey("curl", PackageEcosystem.Rpm), + "7.76.1-26.el9_3.2"); + + // Act + var verdict = await _sut.EvalPatchedStatusAsync( + new BackportContext("rocky", 9), + package, + "CVE-2024-1234"); + + // Assert: Should try Tier 2 (changelog), Tier 3 (patches), etc. + verdict.Status.Should().NotBe(FixStatus.Fixed); // Or could be Fixed from other tier + verdict.EvidencePointer.Type.Should().NotBe("OvalAdvisory"); + } +} +``` + +--- + +### 3.2 BugCVE Mapping Integration + +**File:** BugCveMappingIntegrationTests.cs + +```csharp +public class BugCveMappingIntegrationTests +{ + private readonly Mock _httpFactory; + private readonly DebianSecurityTrackerClient _client; + + [Fact] + public async Task LookupCvesAsync_DebianBug_ReturnsMappedCves() + { + // Arrange + var mockHttp = new MockHttpMessageHandler(); + mockHttp.When("https://security-tracker.debian.org/tracker/data/json") + .Respond("application/json", @" +{ + ""987654"": { + ""description"": ""curl: buffer overflow"", + ""cves"": [""CVE-2024-1234"", ""CVE-2024-5678""] + } +}"); + + _httpFactory.Setup(f => f.CreateClient(It.IsAny())) + .Returns(new HttpClient(mockHttp)); + + var client = new DebianSecurityTrackerClient(_httpFactory.Object, new MemoryCache(new MemoryCacheOptions())); + + // Act + var cves = await client.LookupCvesAsync(new BugId("Debian", "987654")); + + // Assert + cves.Should().Contain("CVE-2024-1234"); + cves.Should().Contain("CVE-2024-5678"); + } + + [Fact] + public async Task LookupCvesAsync_CachesResults() + { + // First call fetch from API + var cves1 = await _client.LookupCvesAsync(new BugId("Debian", "987654")); + + // Second call should use cache (no HTTP request) + var cves2 = await _client.LookupCvesAsync(new BugId("Debian", "987654")); + + cves1.Should().BeEquivalentTo(cves2); + // Verify only one HTTP call was made + } + + [Fact] + public async Task LookupCvesAsync_ApiFailure_ReturnsEmpty() + { + // Arrange: API returns 500 error + var mockHttp = new MockHttpMessageHandler(); + mockHttp.When("*").Respond(HttpStatusCode.InternalServerError); + + _httpFactory.Setup(f => f.CreateClient(It.IsAny())) + .Returns(new HttpClient(mockHttp)); + + var client = new DebianSecurityTrackerClient(_httpFactory.Object, new MemoryCache(new MemoryCacheOptions())); + + // Act + var cves = await client.LookupCvesAsync(new BugId("Debian", "987654")); + + // Assert + cves.Should().BeEmpty(); // Graceful degradation + } +} +``` + +--- + +## 4. Golden Test Cases + +### 4.1 Test Case 1: OpenSSL on Rocky 9 with Derivative OVAL + +**File:** golden_cases.json + +```json +{ + "testCaseId": "GOLDEN-001", + "name": "CVE-2024-26130: OpenSSL on Rocky Linux 9 with AlmaLinux OVAL", + "scenario": "Backported fix with derivative OVAL evidence", + "inputs": { + "cve": "CVE-2024-26130", + "package": { + "name": "openssl", + "version": "3.0.7-24.el9", + "ecosystem": "rpm" + }, + "distro": { + "name": "rocky", + "release": 9 + }, + "availableEvidence": { + "almalinuxOval": { + "advisoryId": "ALSA-2024-1234", + "fixedVersion": "3.0.7-24.el9", + "severity": "important" + } + } + }, + "expected": { + "status": "fixed", + "confidence": "high", + "confidenceScore": 0.95, + "tier": 1, + "evidenceType": "OvalAdvisory", + "evidenceUri": "derivative:almalinuxrocky:oval:ALSA-2024-1234" + } +} +``` + +### 4.2 Test Case 2: curl on Debian with Bug ID + +```json +{ + "testCaseId": "GOLDEN-002", + "name": "CVE-2023-12345: curl on Debian 12 with bug ID mapping", + "scenario": "Changelog evidence with Debian bug ID CVE mapping", + "inputs": { + "cve": "CVE-2023-12345", + "package": { + "name": "curl", + "version": "7.88.1-10+deb12u1", + "ecosystem": "deb" + }, + "distro": { + "name": "debian", + "release": 12 + }, + "availableEvidence": { + "changelog": "curl (7.88.1-10+deb12u1) bookworm-security; urgency=high\n * Fix buffer overflow (Closes: #987654)\n", + "bugMapping": { + "987654": ["CVE-2023-12345"] + } + } + }, + "expected": { + "status": "fixed", + "confidence": "medium", + "confidenceScore": 0.75, + "tier": 2, + "evidenceType": "DebianChangelog", + "evidenceUri": "changelog:debian:curl:7.88.1-10+deb12u1#bug:987654" + } +} +``` + +### 4.3 Test Case 3: zlib with NVD Range Fallback + +```json +{ + "testCaseId": "GOLDEN-003", + "name": "CVE-2024-99999: zlib on Alpine with NVD range only", + "scenario": "Fallback to NVD range heuristic (Tier 5)", + "inputs": { + "cve": "CVE-2024-99999", + "package": { + "name": "zlib", + "version": "1.2.11-r3", + "ecosystem": "alpine" + }, + "distro": { + "name": "alpine", + "release": 318 + }, + "availableEvidence": { + "nvdRange": { + "minVersion": "1.2.0", + "minInclusive": true, + "maxVersion": "1.2.12", + "maxInclusive": false + } + } + }, + "expected": { + "status": "vulnerable", + "confidence": "low", + "confidenceScore": 0.40, + "tier": 5, + "evidenceType": "NvdCpeRange", + "evidenceUri": "nvd:cve/CVE-2024-99999/cpe:2.3:a:zlib:zlib:*" + } +} +``` + +### 4.4 Running Golden Tests + +```csharp +public class GoldenTestRunner +{ + private readonly BackportStatusService _sut; + + [Theory] + [MemberData(nameof(LoadGoldenCases))] + public async Task GoldenCase_ProducesExpectedVerdict(GoldenTestCase testCase) + { + // Arrange + SetupEvidence(testCase.Inputs.AvailableEvidence); + + var package = new PackageInstance( + new PackageKey(testCase.Inputs.Package.Name, testCase.Inputs.Package.Ecosystem), + testCase.Inputs.Package.Version); + + var context = new BackportContext( + testCase.Inputs.Distro.Name, + testCase.Inputs.Distro.Release); + + // Act + var verdict = await _sut.EvalPatchedStatusAsync( + context, + package, + testCase.Inputs.Cve); + + // Assert + verdict.Status.ToString().ToLower().Should().Be(testCase.Expected.Status); + verdict.Confidence.ToString().ToLower().Should().Be(testCase.Expected.Confidence); + verdict.EvidencePointer.Type.Should().Be(testCase.Expected.EvidenceType); + verdict.EvidencePointer.Uri.Should().Contain(testCase.Expected.EvidenceUri); + + // Log for audit trail + _testOutputHelper.WriteLine($"PASS: {testCase.TestCaseId} - {testCase.Name}"); + _testOutputHelper.WriteLine($" Tier: {testCase.Expected.Tier}, Confidence: {verdict.Confidence}"); + } + + public static IEnumerable LoadGoldenCases() + { + var json = File.ReadAllText("TestData/golden_cases.json"); + var cases = JsonSerializer.Deserialize>(json); + return cases.Select(c => new object[] { c }); + } +} +``` + +--- + +## 5. Performance Tests + +### 5.1 Latency Benchmarks + +**File:** BackportResolverBenchmarks.cs + +```csharp +[MemoryDiagnoser] +public class BackportResolverBenchmarks +{ + private BackportStatusService _sut; + + [GlobalSetup] + public void Setup() + { + // Initialize with realistic data + } + + [Benchmark] + [BenchmarkCategory("Tier1")] + public async Task Tier1_DerivativeOval() + { + // Measure Tier 1 latency: derivative OVAL lookup + return await _sut.EvalPatchedStatusAsync( + new BackportContext("rocky", 9), + new PackageInstance(new PackageKey("curl", PackageEcosystem.Rpm), "7.76.1-26.el9"), + "CVE-2024-1234"); + } + + [Benchmark] + [BenchmarkCategory("Tier5")] + public async Task Tier5_NvdRange() + { + // Measure Tier 5 latency: NVD range evaluation + return await _sut.EvalPatchedStatusAsync( + new BackportContext("alpine", 318), + new PackageInstance(new PackageKey("zlib", PackageEcosystem.Alpine), "1.2.11-r3"), + "CVE-2024-99999"); + } +} +``` + +**Acceptance Criteria:** + +| Benchmark | Target Latency | Max Allocations | +|-----------|----------------|-----------------| +| Tier1_DerivativeOval | <50ms (P95) | <5 KB | +| Tier2_Changelog | <100ms (P95) | <10 KB | +| Tier5_NvdRange | <50ms (P95) | <3 KB | + +--- + +### 5.2 Bulk Scan Test + +```csharp +[Fact] +public async Task BulkScan_10000Packages_CompletesWithin5Minutes() +{ + // Arrange + var packages = GenerateTestPackages(10_000); + var cves = GenerateTestCves(100); + var stopwatch = Stopwatch.StartNew(); + + // Act + var results = await Task.WhenAll( + packages.SelectMany(p => + cves.Select(cve => + _sut.EvalPatchedStatusAsync( + new BackportContext("ubuntu", 22), + p, + cve)))); + + stopwatch.Stop(); + + // Assert + stopwatch.Elapsed.Should().BeLessThan(TimeSpan.FromMinutes(5)); + results.Should().HaveCount(10_000 * 100); +} +``` + +--- + +## 6. Test Data + +### 6.1 OVAL Fixture Example + +**File:** TestData/oval_fixtures/alma_9_curl_2024_1234.xml + +```xml + + + + + ALSA-2024:1234: curl security update (Important) + + AlmaLinux 9 + + + + + + + + + +``` + +### 6.2 Changelog Fixture Example + +**File:** TestData/changelog_fixtures/debian_curl_12u1.txt + +``` +curl (7.88.1-10+deb12u1) bookworm-security; urgency=high + + * SECURITY UPDATE: + - Fix CVE-2024-1234: buffer overflow in cookie handling + - Fix CVE-2024-5678: denial of service in HTTP/2 parser + - Closes: #987654, #987655 + * Cherry-pick upstream commits: + - a1b2c3d: Validate cookie length before copy + - e4f5g6h: Add bounds check to HTTP/2 header parsing + + -- Debian Security Mon, 30 Dec 2024 10:00:00 +0000 + +curl (7.88.1-10) bookworm; urgency=medium + + * New upstream release + * Update debian/patches for 7.88 series + + -- Maintainer Fri, 15 Dec 2024 14:00:00 +0000 +``` + +### 6.3 Patch Fixture Example + +**File:** TestData/patch_fixtures/curl_cve_2024_1234.patch + +```diff +From a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0 Mon Sep 17 00:00:00 2001 +From: Security Team +Date: Mon, 30 Dec 2024 10:00:00 +0000 +Subject: [PATCH] Fix CVE-2024-1234: buffer overflow in cookie parsing + +Validate cookie length before memcpy to prevent buffer overflow. + +CVE-2024-1234 +--- + lib/cookie.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/lib/cookie.c b/lib/cookie.c +index a1b2c3d..e4f5g6h 100644 +--- a/lib/cookie.c ++++ b/lib/cookie.c +@@ -234,7 +234,10 @@ static int parse_cookie(struct Cookie *cookie, const char *str) + { + size_t len = strlen(str); +- memcpy(cookie->value, str, len); ++ if(len >= sizeof(cookie->value)) { ++ return -1; /* Cookie too long */ ++ } ++ memcpy(cookie->value, str, len + 1); + cookie->value[len] = '\0'; + return 0; + } +-- +2.34.1 +``` + +--- + +## 7. Continuous Integration + +### 7.1 CI Pipeline Configuration + +```yaml +name: Backport Resolver Tests + +on: [push, pull_request] + +jobs: + unit-tests: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-dotnet@v3 + with: + dotnet-version: '8.0.x' + - run: dotnet test tests/StellaOps.Concelier.BackportProof.Tests/Unit --logger "trx;LogFileName=unit-tests.trx" + - run: dotnet test tests/StellaOps.BugTracking.Tests --logger "trx;LogFileName=bug-tracking-tests.trx" + - name: Upload test results + uses: actions/upload-artifact@v3 + with: + name: test-results + path: '**/*.trx' + + integration-tests: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - run: dotnet test tests/StellaOps.Concelier.BackportProof.Tests/Integration --logger "trx" + + golden-tests: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - run: dotnet test tests/StellaOps.Concelier.BackportProof.Tests --filter "Category=Golden" --logger "trx" + + performance-tests: + runs-on: ubuntu-latest + if: github.event_name == 'pull_request' + steps: + - uses: actions/checkout@v3 + - run: dotnet run --project tests/Benchmarks/BackportResolverBenchmarks.csproj -c Release + - name: Compare with baseline + run: | + dotnet run --project tools/benchmark-comparer.csproj baseline.json current.json +``` + +--- + +**End of Test Specification** diff --git a/docs/implplan/SPRINT_20251230_001_BE_backport_resolver_tiered_evidence.md b/docs/implplan/SPRINT_20251230_001_BE_backport_resolver_tiered_evidence.md new file mode 100644 index 000000000..8e58456cb --- /dev/null +++ b/docs/implplan/SPRINT_20251230_001_BE_backport_resolver_tiered_evidence.md @@ -0,0 +1,906 @@ +# SPRINT_20251230_001_BE_backport_resolver_tiered_evidence + +## Sprint Metadata + +| Field | Value | +|-------|-------| +| **Sprint ID** | SPRINT_20251230_001_BE | +| **Topic** | Tiered Evidence Backport Resolver Enhancement | +| **Module** | Concelier.BackportProof, Concelier.SourceIntel, Feedser.Core | +| **Working Directory** | `src/Concelier/__Libraries/StellaOps.Concelier.BackportProof/` | +| **Priority** | P0 - Critical | +| **Estimated Effort** | 5 days | +| **Dependencies** | StellaOps.VersionComparison, StellaOps.Concelier.Merge | + +--- + +## Executive Summary + +This sprint addresses critical gaps in the backport patch resolver that cause false positives/negatives when determining if a CVE is fixed in Linux distribution packages. The current implementation uses string comparison for version matching and lacks derivative distro mapping, resulting in incorrect vulnerability assessments. + +### Key Deliverables + +1. Wire ecosystem-specific version comparators into BackportStatusService +2. Implement RangeRule evaluation for NVD fallback (Tier 5) +3. Add derivative distro mapping for OVAL/CSAF cross-referencing (Tier 1) +4. Enhance changelog parsing with bug ID → CVE mapping (Tier 2) +5. Extract affected functions from patch context (Tier 3/4) +6. Align confidence scoring to five-tier evidence hierarchy + +--- + +## Background & Problem Statement + +### Current State + +The `BackportStatusService` uses `string.Compare()` for version comparison: + +```csharp +// BackportStatusService.cs:198 +var isPatched = string.Compare(package.InstalledVersion, fixedVersion, StringComparison.Ordinal) >= 0; +``` + +**Failures:** +- `1.2.10` vs `1.2.9` → returns `-1` (should be `+1`) +- `1:2.0` vs `3.0` (epoch) → completely wrong +- `1.2.3~beta` vs `1.2.3` (tilde) → wrong order + +### Proposed Five-Tier Evidence Hierarchy + +| Tier | Evidence Source | Confidence | Priority | +|------|-----------------|------------|----------| +| 1 | Derivative OVAL/CSAF (same release) | 0.95-0.98 | 100 | +| 2 | Changelog CVE markers | 0.75-0.85 | 85 | +| 3 | Source patch files (HunkSig) | 0.80-0.95 | 70 | +| 4 | Upstream commit mapping | 0.55-0.85 | 55 | +| 5 | NVD version ranges (fallback) | Low only | 20 | + +--- + +## Delivery Tracker + +### Phase 1: Version Comparator Integration (P0) + +| Task ID | Description | Status | Assignee | Notes | +|---------|-------------|--------|----------|-------| +| BP-101 | Create IVersionComparatorFactory interface | TODO | | DI registration | +| BP-102 | Wire comparators into BackportStatusService | TODO | | RPM, DEB, APK | +| BP-103 | Update EvaluateBoundaryRules with proof lines | TODO | | Audit trail | +| BP-104 | Unit tests for version comparison edge cases | TODO | | Golden datasets | +| BP-105 | Integration test: epoch handling | TODO | | `1:2.0` vs `3.0` | + +### Phase 2: RangeRule Implementation (P0) + +| Task ID | Description | Status | Assignee | Notes | +|---------|-------------|--------|----------|-------| +| BP-201 | Implement EvaluateRangeRules with comparators | TODO | | Min/max bounds | +| BP-202 | Handle inclusive/exclusive boundaries | TODO | | `[` vs `(` | +| BP-203 | Add Low confidence for NVD-sourced ranges | TODO | | Tier 5 | +| BP-204 | Unit tests for range edge cases | TODO | | Open/closed | +| BP-205 | Integration test: NVD fallback path | TODO | | E2E flow | + +### Phase 3: Derivative Distro Mapping (P1) + +| Task ID | Description | Status | Assignee | Notes | +|---------|-------------|--------|----------|-------| +| BP-301 | Create DistroDerivativeMapping model | TODO | | Canonical/derivative | +| BP-302 | Add RHEL ↔ Alma/Rocky/CentOS mappings | TODO | | Major release | +| BP-303 | Add Ubuntu ↔ LinuxMint mappings | TODO | | | +| BP-304 | Add Debian ↔ Ubuntu mappings | TODO | | | +| BP-305 | Integrate into rule fetching with confidence penalty | TODO | | 0.95x multiplier | +| BP-306 | Unit tests for derivative lookup | TODO | | | +| BP-307 | Integration test: cross-distro OVAL | TODO | | RHEL→Rocky | + +### Phase 4: Bug ID → CVE Mapping (P1) + +| Task ID | Description | Status | Assignee | Notes | +|---------|-------------|--------|----------|-------| +| BP-401 | Add Debian bug regex extraction | TODO | | `Closes: #123` | +| BP-402 | Add RHBZ bug regex extraction | TODO | | `RHBZ#123` | +| BP-403 | Add Launchpad bug regex extraction | TODO | | `LP: #123` | +| BP-404 | Create IBugCveMappingService interface | TODO | | Async lookup | +| BP-405 | Implement DebianSecurityTrackerClient | TODO | | API client | +| BP-406 | Implement RedHatErrataClient | TODO | | API client | +| BP-407 | Cache layer for bug→CVE mappings | TODO | | 24h TTL | +| BP-408 | Unit tests for bug ID extraction | TODO | | Regex patterns | +| BP-409 | Integration test: Debian tracker lookup | TODO | | Live API | + +### Phase 5: Affected Functions Extraction (P2) + +| Task ID | Description | Status | Assignee | Notes | +|---------|-------------|--------|----------|-------| +| BP-501 | Create function signature regex patterns | TODO | | C, Go, Python | +| BP-502 | Implement ExtractFunctionsFromContext | TODO | | In HunkSigExtractor | +| BP-503 | Add C/C++ function pattern | TODO | | `void foo(` | +| BP-504 | Add Go function pattern | TODO | | `func (r *R) M(` | +| BP-505 | Add Python function pattern | TODO | | `def foo(` | +| BP-506 | Add Rust function pattern | TODO | | `fn foo(` | +| BP-507 | Unit tests for function extraction | TODO | | Multi-language | +| BP-508 | Enable fuzzy function matching in Tier 3/4 | TODO | | Similarity score | + +### Phase 6: Confidence Tier Alignment (P2) + +| Task ID | Description | Status | Assignee | Notes | +|---------|-------------|--------|----------|-------| +| BP-601 | Expand RulePriority enum | TODO | | 9 levels | +| BP-602 | Update BackportStatusService priority logic | TODO | | Tier ordering | +| BP-603 | Add confidence multipliers per tier | TODO | | | +| BP-604 | Update EvidencePointer with TierSource | TODO | | Audit | +| BP-605 | Unit tests for tier precedence | TODO | | | + +--- + +## Decisions & Risks + +### Decisions Made + +| ID | Decision | Rationale | Date | +|----|----------|-----------|------| +| D-001 | Use existing VersionComparison library | Already implements rpmvercmp, dpkg, apk semantics | 2025-12-30 | +| D-002 | Derivative confidence penalty 0.95x (High) / 0.80x (Medium) | Same ABI rebuilds vs partial compatibility | 2025-12-30 | +| D-003 | Bug→CVE cache TTL 24 hours | Balance freshness vs API rate limits | 2025-12-30 | + +### Open Risks + +| ID | Risk | Mitigation | Status | +|----|------|------------|--------| +| R-001 | Debian Security Tracker API rate limits | Implement exponential backoff + cache | OPEN | +| R-002 | Function extraction may produce false positives | Add confidence penalty for fuzzy matches | OPEN | +| R-003 | Derivative mappings may drift across major releases | Version-specific mapping table | OPEN | + +--- + +## Acceptance Criteria + +### P0 Tasks (Must complete) + +- [ ] `BackportStatusService` uses proper version comparators for all ecosystems +- [ ] `RangeRule` evaluation returns correct verdicts with Low confidence +- [ ] All existing tests pass +- [ ] New golden tests for version edge cases + +### P1 Tasks (Should complete) + +- [ ] Derivative distro mapping works for RHEL family +- [ ] Bug ID extraction finds Debian/RHBZ/LP references +- [ ] Bug→CVE mapping lookup is cached + +### P2 Tasks (Nice to have) + +- [ ] Function extraction works for C, Go, Python, Rust +- [ ] Confidence tiers aligned to five-tier hierarchy + +--- + +## Test Strategy + +### Unit Tests + +| Area | Test File | Coverage Target | +|------|-----------|-----------------| +| Version comparison | `BackportStatusServiceVersionTests.cs` | All ecosystems | +| Range evaluation | `BackportStatusServiceRangeTests.cs` | Boundary conditions | +| Derivative mapping | `DistroDerivativeMappingTests.cs` | All supported distros | +| Bug ID extraction | `ChangelogBugIdExtractionTests.cs` | Regex patterns | +| Function extraction | `HunkSigFunctionExtractionTests.cs` | Multi-language | + +### Integration Tests + +| Scenario | Test File | External Dependencies | +|----------|-----------|----------------------| +| Cross-distro OVAL | `CrossDistroOvalIntegrationTests.cs` | None (fixtures) | +| Bug→CVE lookup | `BugCveMappingIntegrationTests.cs` | Debian Tracker API | +| Full resolver flow | `BackportResolverE2ETests.cs` | PostgreSQL (Testcontainers) | + +### Golden Datasets + +Location: `src/__Tests/__Datasets/backport-resolver/` + +| Dataset | Purpose | +|---------|---------| +| `rpm-version-edge-cases.json` | Epoch, tilde, release variations | +| `deb-version-edge-cases.json` | Epoch, revision, ubuntu suffixes | +| `apk-version-edge-cases.json` | Pre-release suffixes, pkgrel | +| `cross-distro-oval-fixtures/` | RHEL/Rocky/Alma advisory samples | +| `changelog-with-bugids/` | Debian/RPM changelogs with bug refs | + +--- + +## Execution Log + +| Date | Event | Details | +|------|-------|---------| +| 2025-12-30 | Sprint created | Initial planning and gap analysis | + +--- + +## References + +- `src/Concelier/__Libraries/StellaOps.Concelier.BackportProof/Services/BackportStatusService.cs` +- `src/Concelier/__Libraries/StellaOps.Concelier.BackportProof/Models/FixRuleModels.cs` +- `src/Concelier/__Libraries/StellaOps.Concelier.Merge/Comparers/RpmVersionComparer.cs` +- `src/Concelier/__Libraries/StellaOps.Concelier.Merge/Comparers/ApkVersionComparer.cs` +- `src/Concelier/__Libraries/StellaOps.Concelier.SourceIntel/ChangelogParser.cs` +- `src/Feedser/StellaOps.Feedser.Core/HunkSigExtractor.cs` +- `src/VexLens/StellaOps.VexLens/Consensus/VexConsensusEngine.cs` +**Key Improvements:** +- Wire existing version comparators (RpmVersionComparer, ApkVersionComparer, DebianVersionComparer) into BackportStatusService +- Implement NVD range evaluation (Tier 5 fallback) +- Add derivative distro mapping (RHELAlma/Rocky, UbuntuMint) for Tier 1 evidence +- Extend changelog parser to extract bug IDs and map to CVEs +- Extract function signatures from patch hunks for better matching +- Align confidence scoring with 5-tier evidence hierarchy + +**Impact:** +- Eliminates false positives from incorrect version comparisons (e.g., "1.2.10" < "1.2.9") +- Enables cross-distro evidence sharing (e.g., use AlmaLinux OVAL for RHEL) +- Provides auditable, signed VEX statements with evidence trails +- Reduces manual verification workload by 60-80% + +--- + +## Problem Statement + +### Current Implementation Gaps + +| Gap ID | Description | Severity | Current Behavior | Desired Behavior | +|--------|-------------|----------|------------------|------------------| +| GAP-001 | String-based version comparison | **CRITICAL** | "1.2.10" < "1.2.9" returns true | Use ecosystem-specific comparers (EVR, dpkg, apk) | +| GAP-002 | RangeRule returns Unknown | **CRITICAL** | NVD ranges ignored, always Unknown | Evaluate ranges with proper version semantics | +| GAP-003 | No derivative distro mapping | **HIGH** | AlmaLinux OVAL unused for RHEL scans | Map RHELAlma/Rocky, UbuntuMint with confidence | +| GAP-004 | Bug IDCVE mapping missing | **HIGH** | Only direct CVE mentions detected | Extract Debian/RHBZ/LP bug IDs, map to CVEs | +| GAP-005 | AffectedFunctions not extracted | **MEDIUM** | Hunk matching relies only on content hash | Extract C/Python/Go function signatures for fuzzy match | +| GAP-006 | Confidence tiers misaligned | **MEDIUM** | Priority values don't match evidence quality | Align with 5-tier hierarchy (Tier 1=High, Tier 5=Low) | + +### Real-World Example + +**Scenario:** CVE-2024-1234 in curl on Rocky Linux 9 + +**Current behavior:** +``` +- Installed: curl-7.76.1-26.el9_3.2 +- NVD says: "Fixed in 7.77.0" +- String comparison: "7.76.1-26.el9_3.2" < "7.77.0" **VULNERABLE** (WRONG!) +``` + +**Root cause:** Red Hat backported the fix to 7.76.1-26, but string comparison doesn't understand epoch-version-release semantics. + +**Correct behavior (after sprint):** +``` +1. Check AlmaLinux OVAL (Tier 1): Found fix in curl-7.76.1-26.el9_3.2 +2. Map AlmaRocky (High confidence, same ABI) +3. Verdict: **FIXED** , Confidence: High, Evidence: [Alma OVAL advisory ALSA-2024-1234] +``` + +--- + +## 5-Tier Evidence Hierarchy (Target Architecture) + +`mermaid +graph TD + A[CVE + Package + Distro] --> B{Tier 1: Derivative OVAL/CSAF} + B -->|Found| C[Verdict: FIXED/VULNERABLE
Confidence: High 0.95-0.98] + B -->|Not Found| D{Tier 2: Changelog Markers} + D -->|CVE Match| E[Verdict: FIXED
Confidence: High 0.85] + D -->|Bug ID Match| F[Verdict: FIXED
Confidence: Medium 0.75] + D -->|Not Found| G{Tier 3: Source Patch Files} + G -->|Exact Hunk Hash| H[Verdict: FIXED
Confidence: Medium-High 0.90] + G -->|Fuzzy Function Match| I[Verdict: FIXED
Confidence: Medium 0.70] + G -->|Not Found| J{Tier 4: Upstream Commit Mapping} + J -->|100% Hunk Parity| K[Verdict: FIXED
Confidence: Medium 0.80] + J -->|Partial Match| L[Verdict: FIXED
Confidence: Medium-Low 0.60] + J -->|Not Found| M{Tier 5: NVD Range Fallback} + M -->|In Range| N[Verdict: VULNERABLE
Confidence: Low 0.40] + M -->|Out of Range| O[Verdict: FIXED
Confidence: Low 0.50] + M -->|No Data| P[Verdict: UNKNOWN
Confidence: Low 0.30] +` + +--- + +## Sprint Tasks + +### Phase 1: Foundation (P0 - Critical Path) + +#### Task 1.1: Wire Version Comparators into BackportStatusService +- **File:** src/Concelier/__Libraries/StellaOps.Concelier.BackportProof/Services/BackportStatusService.cs +- **Effort:** 2h +- **Dependencies:** StellaOps.Concelier.Merge.Comparers +- **Acceptance Criteria:** + - [ ] Add IReadOnlyDictionary field + - [ ] Inject comparators in constructor (RPM, Debian, Alpine, Conda) + - [ ] Replace string.Compare() in EvaluateBoundaryRules() with comparator.CompareWithProof() + - [ ] Add fallback StringVersionComparer for unknown ecosystems + - [ ] Unit test: "1.2.10" > "1.2.9" for RPM/Deb/Alpine + - [ ] Unit test: Epoch handling "1:2.0" > "3.0" + - [ ] Unit test: Tilde pre-releases "1.2.3~beta" < "1.2.3" + +**Code Snippet:** +```csharp +// BackportStatusService.cs +private readonly IReadOnlyDictionary _comparators; + +public BackportStatusService( + IFixRuleRepository ruleRepository, + IRpmVersionComparer rpmComparer, + IDebianVersionComparer debComparer, + IApkVersionComparer apkComparer) +{ + _comparators = new Dictionary + { + [PackageEcosystem.Rpm] = rpmComparer, + [PackageEcosystem.Deb] = debComparer, + [PackageEcosystem.Alpine] = apkComparer, + }.ToFrozenDictionary(); +} + +private BackportVerdict EvaluateBoundaryRules(...) +{ + var comparator = _comparators.GetValueOrDefault( + package.Key.Ecosystem, + StringVersionComparer.Instance); + + var result = comparator.CompareWithProof( + package.InstalledVersion, + fixedVersion); + + var isPatched = result.Result >= 0; + // ... rest of logic +} +``` + +--- + +#### Task 1.2: Implement RangeRule Evaluation (Tier 5) +- **File:** BackportStatusService.cs::EvaluateRangeRules() +- **Effort:** 3h +- **Acceptance Criteria:** + - [ ] Evaluate AffectedRange.MinVersion and MaxVersion with inclusive/exclusive bounds + - [ ] Return FixStatus.Vulnerable if in range, FixStatus.Fixed if out of range + - [ ] Set VerdictConfidence.Low for all Tier 5 decisions + - [ ] Add evidence pointer to NVD CPE/range definition + - [ ] Handle null min/max (unbounded ranges) + - [ ] Unit test: CVE-2024-1234 with range [1.0.0, 2.0.0) versions 1.5.0 (vuln), 2.0.1 (fixed) + +**Code Snippet:** +```csharp +private BackportVerdict EvaluateRangeRules( + CveId cve, + PackageInstance package, + IReadOnlyList rules) +{ + var comparator = _comparators.GetValueOrDefault( + package.Key.Ecosystem, + StringVersionComparer.Instance); + + foreach (var rule in rules.OrderByDescending(r => r.Priority)) + { + var range = rule.AffectedRange; + var inRange = true; + + if (range.MinVersion != null) + { + var cmp = comparator.Compare(package.InstalledVersion, range.MinVersion); + inRange &= range.MinInclusive ? cmp >= 0 : cmp > 0; + } + + if (range.MaxVersion != null) + { + var cmp = comparator.Compare(package.InstalledVersion, range.MaxVersion); + inRange &= range.MaxInclusive ? cmp <= 0 : cmp < 0; + } + + if (inRange) + { + return new BackportVerdict( + Status: FixStatus.Vulnerable, + Confidence: VerdictConfidence.Low, // Tier 5 always Low + EvidenceSource: RuleType.Range, + EvidencePointer: new EvidencePointer( + Type: "NvdCpeRange", + Uri: $"nvd:cve/{cve}/cpe/{rule.CpeId}", + SourceDigest: ComputeDigest(rule)), + ConflictReason: null); + } + } + + return new BackportVerdict( + Status: FixStatus.Unknown, + Confidence: VerdictConfidence.Low, + ConflictReason: "No matching range rule"); +} +``` + +--- + +### Phase 2: Derivative Distro Mapping (P1) + +#### Task 2.1: Create DistroDerivative Model and Mappings +- **New File:** src/__Libraries/StellaOps.DistroIntel/DistroDerivative.cs +- **Effort:** 2h +- **Acceptance Criteria:** + - [ ] Define DistroDerivative record with canonical/derivative names, release, confidence + - [ ] Create static DistroMappings class with predefined derivatives + - [ ] Support RHELAlma/Rocky (High confidence), UbuntuMint (Medium), DebianUbuntu (Medium) + - [ ] Add FindDerivativesFor(distro, release) query method + - [ ] Unit test: Query "rhel 9" returns ["almalinux 9", "rocky 9"] + +**Code Snippet:** +```csharp +namespace StellaOps.DistroIntel; + +public enum DerivativeConfidence +{ + High, // Same ABI, byte-for-byte rebuilds (Alma/Rocky from RHEL) + Medium // Derivative with modifications (Ubuntu from Debian, Mint from Ubuntu) +} + +public sealed record DistroDerivative( + string CanonicalDistro, + string DerivativeDistro, + int MajorRelease, + DerivativeConfidence Confidence); + +public static class DistroMappings +{ + public static readonly ImmutableArray Derivatives = + [ + new("rhel", "almalinux", 9, DerivativeConfidence.High), + new("rhel", "rocky", 9, DerivativeConfidence.High), + new("rhel", "centos", 9, DerivativeConfidence.High), + new("rhel", "almalinux", 8, DerivativeConfidence.High), + new("rhel", "rocky", 8, DerivativeConfidence.High), + new("ubuntu", "linuxmint", 22, DerivativeConfidence.Medium), + new("ubuntu", "linuxmint", 20, DerivativeConfidence.Medium), + new("debian", "ubuntu", 12, DerivativeConfidence.Medium), + ]; + + public static IEnumerable FindDerivativesFor( + string distro, + int majorRelease) + { + return Derivatives.Where(d => + d.CanonicalDistro.Equals(distro, StringComparison.OrdinalIgnoreCase) && + d.MajorRelease == majorRelease); + } + + public static decimal GetConfidenceMultiplier(DerivativeConfidence conf) => + conf switch + { + DerivativeConfidence.High => 0.95m, + DerivativeConfidence.Medium => 0.80m, + _ => 0.70m + }; +} +``` + +--- + +#### Task 2.2: Integrate Derivative Mapping into BackportStatusService +- **File:** BackportStatusService.cs +- **Effort:** 2h +- **Acceptance Criteria:** + - [ ] After fetching rules for target distro, if empty, try derivative mappings + - [ ] Query derivative rules and apply confidence penalty + - [ ] Annotate evidence with derivative source + - [ ] Integration test: Scan Rocky 9 with only AlmaLinux OVAL data success + +**Code Snippet:** +```csharp +private async ValueTask> FetchRulesWithDerivativeMapping( + BackportContext context, + PackageInstance package, + CveId cve) +{ + // Try direct distro first + var rules = await _ruleRepository.GetRulesAsync(context, package, cve); + + if (rules.Count == 0) + { + var derivatives = DistroMappings.FindDerivativesFor( + context.Distro, + context.Release); + + foreach (var derivative in derivatives.OrderByDescending(d => d.Confidence)) + { + var derivativeContext = context with + { + Distro = derivative.DerivativeDistro + }; + + var derivativeRules = await _ruleRepository.GetRulesAsync( + derivativeContext, + package, + cve); + + if (derivativeRules.Count > 0) + { + // Apply confidence penalty + var multiplier = DistroMappings.GetConfidenceMultiplier( + derivative.Confidence); + + rules = derivativeRules.Select(r => r with + { + Confidence = r.Confidence * multiplier, + EvidencePointer = r.EvidencePointer with + { + Uri = $"derivative:{derivative.DerivativeDistro}{context.Distro}:{r.EvidencePointer.Uri}" + } + }).ToList(); + + break; // Use first successful derivative + } + } + } + + return rules; +} +``` + +--- + +### Phase 3: Bug ID CVE Mapping (P1) + +#### Task 3.1: Extend ChangelogParser with Bug ID Extraction +- **File:** src/Concelier/__Libraries/StellaOps.Concelier.SourceIntel/ChangelogParser.cs +- **Effort:** 3h +- **Acceptance Criteria:** + - [ ] Add regex patterns for Debian (Closes: #123456), RHBZ (RHBZ#123456), Launchpad (LP: #123456) + - [ ] Extract bug IDs alongside CVE IDs + - [ ] Return ChangelogEntry with both CveIds and BugIds collections + - [ ] Unit test: Parse Debian changelog with "Closes: #987654" bug ID extracted + +**Code Snippet:** +```csharp +[GeneratedRegex(@"Closes:\s*#(\d+)", RegexOptions.IgnoreCase)] +private static partial Regex DebianBugRegex(); + +[GeneratedRegex(@"(?:RHBZ|rhbz)#(\d+)", RegexOptions.IgnoreCase)] +private static partial Regex RhBugzillaRegex(); + +[GeneratedRegex(@"LP:\s*#(\d+)", RegexOptions.IgnoreCase)] +private static partial Regex LaunchpadBugRegex(); + +public sealed record ChangelogEntry( + string Version, + DateTimeOffset Date, + IReadOnlyList CveIds, + IReadOnlyList BugIds, // NEW + string Description); + +public sealed record BugId(string Tracker, string Id) +{ + public override string ToString() => $"{Tracker}#{Id}"; +} + +private static IReadOnlyList ExtractBugIds(string line) +{ + var bugs = new List(); + + foreach (Match m in DebianBugRegex().Matches(line)) + bugs.Add(new BugId("Debian", m.Groups[1].Value)); + + foreach (Match m in RhBugzillaRegex().Matches(line)) + bugs.Add(new BugId("RHBZ", m.Groups[1].Value)); + + foreach (Match m in LaunchpadBugRegex().Matches(line)) + bugs.Add(new BugId("Launchpad", m.Groups[1].Value)); + + return bugs; +} +``` + +--- + +#### Task 3.2: Implement BugCVE Mapping Service +- **New File:** src/__Libraries/StellaOps.BugTracking/IBugCveMappingService.cs +- **Effort:** 4h (including API clients) +- **Acceptance Criteria:** + - [ ] Define IBugCveMappingService.LookupCvesAsync(BugId) + - [ ] Implement Debian Security Tracker API client (https://security-tracker.debian.org/tracker/data/json) + - [ ] Implement Red Hat Bugzilla API stub (cache-based, due to auth complexity) + - [ ] Implement Ubuntu CVE Tracker scraper (https://ubuntu.com/security/cves) + - [ ] Cache results (1 hour TTL) + - [ ] Integration test: Debian bug #987654 CVE-2024-1234 + +**Stub Implementation:** +```csharp +public interface IBugCveMappingService +{ + ValueTask> LookupCvesAsync( + BugId bugId, + CancellationToken cancellationToken = default); +} + +public sealed class DebianSecurityTrackerClient : IBugCveMappingService +{ + private readonly HttpClient _http; + private readonly IMemoryCache _cache; + + public async ValueTask> LookupCvesAsync( + BugId bugId, + CancellationToken ct = default) + { + if (bugId.Tracker != "Debian") + return []; + + var cacheKey = $"debian:bug:{bugId.Id}"; + if (_cache.TryGetValue(cacheKey, out IReadOnlyList? cached)) + return cached!; + + var json = await _http.GetStringAsync( + "https://security-tracker.debian.org/tracker/data/json", + ct); + + // Parse JSON, extract CVEs for bug ID + var cves = ParseDebianTrackerJson(json, bugId.Id); + + _cache.Set(cacheKey, cves, TimeSpan.FromHours(1)); + return cves; + } +} +``` + +--- + +### Phase 4: Function Extraction from Hunks (P2) + +#### Task 4.1: Add Function Signature Extraction to HunkSigExtractor +- **File:** src/Feedser/StellaOps.Feedser.Core/HunkSigExtractor.cs +- **Effort:** 4h +- **Acceptance Criteria:** + - [ ] Extract C/C++ functions (static void foo(, int main() + - [ ] Extract Python functions (def foo(, class Foo:) + - [ ] Extract Go functions ( unc (r *Receiver) Method() + - [ ] Populate PatchHunkSig.AffectedFunctions + - [ ] Unit test: C patch with static int ssl_verify(SSL *ssl) function extracted + +**Code Snippet:** +```csharp +[GeneratedRegex(@"^\s*(?:static\s+|inline\s+)?(?:\w+\s+)+(\w+)\s*\(", RegexOptions.Multiline)] +private static partial Regex CFunctionRegex(); + +[GeneratedRegex(@"^\s*def\s+(\w+)\s*\(", RegexOptions.Multiline)] +private static partial Regex PythonFunctionRegex(); + +[GeneratedRegex(@"^\s*func\s+(?:\(\w+\s+\*?\w+\)\s+)?(\w+)\s*\(", RegexOptions.Multiline)] +private static partial Regex GoFunctionRegex(); + +private static IReadOnlyList ExtractFunctionsFromContext(PatchHunk hunk) +{ + var functions = new HashSet(); + var context = hunk.Context; + + foreach (Match m in CFunctionRegex().Matches(context)) + functions.Add(m.Groups[1].Value); + + foreach (Match m in PythonFunctionRegex().Matches(context)) + functions.Add(m.Groups[1].Value); + + foreach (Match m in GoFunctionRegex().Matches(context)) + functions.Add(m.Groups[1].Value); + + return functions.ToArray(); +} + +// Update ExtractHunkSigs: +AffectedFunctions = ExtractFunctionsFromContext(hunk), +``` + +--- + +### Phase 5: Confidence Tier Realignment (P2) + +#### Task 5.1: Update RulePriority Enum +- **File:** src/Concelier/__Libraries/StellaOps.Concelier.BackportProof/Models/FixRuleModels.cs +- **Effort:** 1h +- **Acceptance Criteria:** + - [ ] Rename/add priority values to match 5-tier hierarchy + - [ ] Ensure tier ordering: Tier 1 > Tier 2 > ... > Tier 5 + - [ ] Update existing rule creation code to use new priorities + - [ ] Unit test: Verify priority ordering in resolver + +**Code Snippet:** +```csharp +public enum RulePriority +{ + // Tier 1: Derivative OVAL/CSAF + DistroNativeOval = 100, + DerivativeOvalHigh = 95, // Alma/Rocky for RHEL + DerivativeOvalMedium = 90, // Mint for Ubuntu + + // Tier 2: Changelog markers + ChangelogExplicitCve = 85, + ChangelogBugIdMapped = 75, + + // Tier 3: Source patch files + SourcePatchExactMatch = 70, + SourcePatchFuzzyMatch = 60, + + // Tier 4: Upstream commit mapping + UpstreamCommitExactParity = 55, + UpstreamCommitPartialMatch = 45, + + // Tier 5: NVD range fallback + NvdRangeHeuristic = 20 +} +``` + +--- + +#### Task 5.2: Map Priorities to Confidence Levels +- **File:** BackportStatusService.cs +- **Effort:** 1h +- **Acceptance Criteria:** + - [ ] Add GetConfidenceForPriority(RulePriority) helper + - [ ] Return VerdictConfidence.High for Tier 1-2, Medium for Tier 3-4, Low for Tier 5 + - [ ] Use in all verdict creation paths + - [ ] Unit test: Priority 100 High, Priority 20 Low + +**Code Snippet:** +```csharp +private static VerdictConfidence GetConfidenceForPriority(RulePriority priority) => + priority switch + { + >= RulePriority.ChangelogBugIdMapped => VerdictConfidence.High, + >= RulePriority.UpstreamCommitPartialMatch => VerdictConfidence.Medium, + _ => VerdictConfidence.Low + }; +``` + +--- + +## Testing Strategy + +### Unit Tests (Per Task) +- Task 1.1: BackportStatusServiceTests.cs::VersionComparatorIntegration +- Task 1.2: BackportStatusServiceTests.cs::RangeRuleEvaluation +- Task 2.1: DistroMappingsTests.cs +- Task 2.2: BackportStatusServiceTests.cs::DerivativeDistroMapping +- Task 3.1: ChangelogParserTests.cs::BugIdExtraction +- Task 3.2: BugCveMappingServiceTests.cs +- Task 4.1: HunkSigExtractorTests.cs::FunctionExtraction +- Task 5.1/5.2: FixRuleModelsTests.cs::ConfidenceMapping + +### Integration Tests (Golden Cases) + +#### Test Case 1: CVE-2024-26130 (OpenSSL on Rocky 9) +```yaml +Scenario: Backported fix with derivative OVAL +Given: + - CVE: CVE-2024-26130 + - Package: openssl-3.0.7-24.el9 + - Distro: rocky 9 + - OVAL exists for: almalinux 9 (not rocky 9) +Expected: + - Status: FIXED + - Confidence: High (0.95) + - Evidence: AlmaLinux OVAL ALSA-2024-1234, mapped to Rocky + - Tier: 1 (Derivative OVAL) +``` + +#### Test Case 2: CVE-2023-12345 (curl on Debian with bug ID) +```yaml +Scenario: Changelog with Debian bug ID +Given: + - CVE: CVE-2023-12345 + - Package: curl-7.88.1-10+deb12u1 + - Distro: debian 12 + - Changelog: "Closes: #987654" (maps to CVE-2023-12345) +Expected: + - Status: FIXED + - Confidence: Medium (0.75) + - Evidence: Debian changelog, bug #987654 CVE-2023-12345 + - Tier: 2 (Changelog bug ID) +``` + +#### Test Case 3: CVE-2024-99999 (zlib with NVD range only) +```yaml +Scenario: Fallback to NVD range +Given: + - CVE: CVE-2024-99999 + - Package: zlib-1.2.11-r3 + - Distro: alpine 3.18 + - No OVAL, no changelog, no patches + - NVD range: [1.2.0, 1.2.12) vulnerable +Expected: + - Status: VULNERABLE + - Confidence: Low (0.40) + - Evidence: NVD CPE range heuristic + - Tier: 5 (NVD fallback) +``` + +### Performance Tests +- Measure resolver latency: target <50ms for Tier 1-3, <500ms for Tier 4 (upstream git) +- Bulk scan: 10,000 CVEpackage combinations should complete within 5 minutes +- Cache hit rate for bugCVE mapping: target >80% + +--- + +## Rollout Plan + +### Phase 1 (Week 1): P0 Tasks +- Days 1-2: Task 1.1 (Version comparators) + Task 1.2 (Range rules) +- Day 3: Unit tests + integration testing +- Day 4: Deploy to staging, validate with golden cases +- Day 5: Production canary (10% traffic) + +### Phase 2 (Week 2): P1 Tasks +- Days 1-2: Task 2.1 + 2.2 (Derivative mapping) +- Days 3-4: Task 3.1 + 3.2 (Bug ID mapping) +- Day 5: Full production rollout + +### Phase 3 (Week 3): P2 Polish +- Days 1-2: Task 4.1 (Function extraction) +- Day 3: Task 5.1 + 5.2 (Confidence realignment) +- Days 4-5: Documentation + observability dashboards + +--- + +## Success Metrics + +| Metric | Baseline (Current) | Target (Post-Sprint) | Measurement | +|--------|-------------------|----------------------|-------------| +| False positive rate | 35% | <5% | Manual audit of 500 random verdicts | +| False negative rate | 12% | <3% | Regression test suite (50 known vulns) | +| Tier 1 evidence usage | 0% | >40% | % verdicts using derivative OVAL | +| Tier 5 fallback rate | 100% | <20% | % verdicts from NVD ranges only | +| Average confidence score | 0.50 (Medium) | >0.75 (Medium-High) | Weighted average of verdicts | +| Time to verdict | 150ms | <100ms | P95 latency for single CVE evaluation | + +--- + +## Risk Mitigation + +| Risk | Likelihood | Impact | Mitigation | +|------|-----------|--------|------------| +| Version comparer regressions | Medium | High | Extensive unit tests, gradual rollout with canary | +| Derivative OVAL mismatch (NEVRA drift) | Low | Medium | Require exact NEVRA match, log mismatches | +| Bug tracker APIs rate-limit/fail | High | Medium | Aggressive caching (1h TTL), fallback to direct CVE only | +| Function extraction false positives | Medium | Low | Fuzzy matching with threshold, manual review for P2 | +| Confidence inflation | Low | High | Audit trail of all evidence, periodic manual validation | + +--- + +## Appendix + +### A. File Modification Checklist +- [ ] BackportStatusService.cs (Tasks 1.1, 1.2, 2.2, 5.2) +- [ ] FixRuleModels.cs (Task 5.1) +- [ ] ChangelogParser.cs (Task 3.1) +- [ ] HunkSigExtractor.cs (Task 4.1) +- [ ] New: DistroDerivative.cs (Task 2.1) +- [ ] New: IBugCveMappingService.cs + implementations (Task 3.2) + +### B. Dependency Updates +```xml + + + + + +``` + +### C. Configuration Changes +```json +{ + "BackportResolver": { + "EnableDerivativeMapping": true, + "DerivativeConfidencePenalty": 0.05, + "BugTrackerCache": { + "TtlHours": 1, + "MaxEntries": 10000 + }, + "TierTimeouts": { + "Tier1Ms": 500, + "Tier2Ms": 200, + "Tier3Ms": 300, + "Tier4Ms": 2000, + "Tier5Ms": 100 + } + } +} +``` + +--- + +**End of Sprint Document** diff --git a/docs/modules/cli/architecture.md b/docs/modules/cli/architecture.md index 5cb6df26a..433702158 100644 --- a/docs/modules/cli/architecture.md +++ b/docs/modules/cli/architecture.md @@ -105,6 +105,9 @@ src/ * `config set/get` — endpoint & defaults. * `whoami` — short auth display. * `version` — CLI + protocol versions; release channel. +* `tools policy-dsl-validate [--strict] [--json]` +* `tools policy-schema-export [--output ] [--repo-root ]` +* `tools policy-simulation-smoke [--scenario-root ] [--output ] [--repo-root ] [--fixed-time ]` ### 2.9 Aggregation-only guard helpers diff --git a/docs/modules/findings-ledger/README.md b/docs/modules/findings-ledger/README.md index eaa36c87b..d7ec5b296 100644 --- a/docs/modules/findings-ledger/README.md +++ b/docs/modules/findings-ledger/README.md @@ -11,6 +11,7 @@ Immutable, append-only event ledger for tracking vulnerability findings, policy ## Quick links - FL1–FL10 remediation tracker: `gaps-FL1-FL10.md` +- Implementation plan: `implementation_plan.md` - Schema catalog (events/projections/exports): `schema-catalog.md` - Merkle & external anchor policy: `merkle-anchor-policy.md` - Tenant isolation & redaction manifest: `tenant-isolation-redaction.md` diff --git a/docs/modules/findings-ledger/implementation_plan.md b/docs/modules/findings-ledger/implementation_plan.md new file mode 100644 index 000000000..510e9f70f --- /dev/null +++ b/docs/modules/findings-ledger/implementation_plan.md @@ -0,0 +1,33 @@ +# Findings Ledger Implementation Plan + +## Purpose +Define the delivery plan for the Findings Ledger service, replay harness, observability, and air-gap provenance so audits can verify deterministic state reconstruction. + +## Active work +- No active sprint tracked here yet. Use `docs/modules/findings-ledger/gaps-FL1-FL10.md` for remediation tracking. + +## Near-term deliverables +- Observability baselines: metrics, logs, traces, dashboards, and alert rules per `docs/modules/findings-ledger/observability.md`. +- Determinism harness: replay CLI, fixtures, and signed reports per `docs/modules/findings-ledger/replay-harness.md`. +- Deployment collateral: Compose/Helm overlays, migrations, and backup/restore runbooks per `docs/modules/findings-ledger/deployment.md`. +- Provenance extensions: air-gap bundle metadata, staleness enforcement, and sealed-mode timeline entries per `docs/modules/findings-ledger/airgap-provenance.md`. + +## Dependencies +- Observability schema approval for metrics and dashboards. +- Orchestrator export schema freeze for provenance linkage. +- QA lab capacity for >=5M findings/tenant replay harness. +- DevOps review of Compose/Helm overlays and offline kit packaging. + +## Evidence of completion +- `src/Findings/StellaOps.Findings.Ledger` and `src/Findings/tools/LedgerReplayHarness` updated with deterministic behavior and tests. +- Replay harness reports (`harness-report.json` + DSSE) stored under approved offline kit locations. +- Dashboard JSON and alert rules committed under `offline/telemetry/dashboards/ledger` or `ops/devops/findings-ledger/**`. +- Deployment and backup guidance validated against `docs/modules/findings-ledger/deployment.md`. + +## Reference docs +- `docs/modules/findings-ledger/schema.md` +- `docs/modules/findings-ledger/replay-harness.md` +- `docs/modules/findings-ledger/observability.md` +- `docs/modules/findings-ledger/deployment.md` +- `docs/modules/findings-ledger/airgap-provenance.md` +- `docs/modules/findings-ledger/workflow-inference.md` diff --git a/docs/product-advisories/30-Dec-2025 - Binary Diff Signatures for Patch Detection.md b/docs/product-advisories/30-Dec-2025 - Binary Diff Signatures for Patch Detection.md new file mode 100644 index 000000000..1400f4407 --- /dev/null +++ b/docs/product-advisories/30-Dec-2025 - Binary Diff Signatures for Patch Detection.md @@ -0,0 +1,1146 @@ +Here’s a compact, practical blueprint for detecting patched vulnerabilities in Linux binaries—even when distros backport fixes and version strings lie—by using **low‑entropy delta signatures** over ELF segments. + +--- + +# Why this helps + +Version numbers and CVE notes are noisy. Distros often **backport** a fix without bumping upstream versions. A fast, reproducible **code‑delta fingerprint** lets Stella Ops verify “is the fix present in *this* binary?” without trusting package metadata. + +# Core idea (plain English) + +1. Extract the binary’s executable/read‑only segments (`.text`, `.rodata`, and optionally `.got/.plt`). +2. **Normalize** away relocation noise (addresses, section offsets, build‑IDs). +3. Hash the normalized bytes with **SHA‑256**. +4. Compare that hash (or a tiny set of chunk hashes) against a **reference signature** for the *patched* and *vulnerable* states of the function(s) touched by the CVE. +5. Verdict: “Patched”, “Still vulnerable”, or “Indeterminate (needs deeper diff)”. + +# What we store (the “delta signature”) + +For each CVE fix (per arch, per compiler family if needed): + +* Target ELF: `soname`, `symbol(s)` affected (e.g., `ssl3_accept`, `png_handle_iCCP`) +* Segment scope: `.text` (always), `.rodata` (optional) +* **Normalization recipe**: strip relocations, zero relocation slots, canonicalize NOP runs, normalize jump tables +* **Hash schema**: + + * Whole‑region SHA‑256, **and**/or + * Rolling chunk hashes (e.g., 1–4 KiB windows) for resilience +* Build meta: arch (`x86_64`, `aarch64`), endianness, ABI hints, compiler hardening flags that *don’t* affect normalized output +* Confidence notes (e.g., “ROP‑safe change only in function X”) + +# Normalization rules (pragmatic) + +* Apply relocations to get final bytes, then **zero out** relocation targets and absolute addresses. +* Canonicalize: + + * NOP sleds → single `NOP` + * PLT/GOT stub patterns → canonical tokens + * Jump tables: rewrite 32/64‑bit absolute entries to **relative deltas** then zero base + * Padding → zero +* Strip `.comment`, `.note.*`, `.symtab` (keep `.dynsym` for symbol mapping only). + +# Minimal C# sketch (Stella Ops scanner.webservice) + +```csharp +public sealed class ElfDeltaHasher +{ + public record SignatureSpec(string SoName, string[] Symbols, string Arch, bool IncludeRodata); + + public record DeltaResult(string Arch, string SoName, string Symbol, + string Alg, byte[] Hash, int Size); + + public static IEnumerable Compute(Stream elfStream, SignatureSpec spec) + { + var elf = ElfFile.Load(elfStream); // use an internal reader (no P/Invoke) + if (elf.DynamicLibraries?.Any(s => s.Contains(spec.SoName)) == false && + elf.SONAME != spec.SoName) yield break; + + foreach (var sym in ResolveSymbols(elf, spec.Symbols)) + { + var textBytes = ExtractNormalized(elf, sym, sections: new[]{".text"}); + yield return HashChunk("sha256:text", spec.SoName, sym.Name, textBytes); + + if (spec.IncludeRodata) + { + var roBytes = ExtractNormalized(elf, sym, sections: new[]{".rodata",".rodata.rel.ro"}); + yield return HashChunk("sha256:ro", spec.SoName, sym.Name, roBytes); + } + } + } + + static DeltaResult HashChunk(string alg, string so, string sym, ReadOnlySpan bytes) + { + using var sha = System.Security.Cryptography.SHA256.Create(); + var h = sha.ComputeHash(bytes.ToArray()); + return new DeltaResult(arch: RuntimeArch(), so, sym, alg, h, bytes.Length); + } +} +``` + +*(Your real code: implement `ElfFile`, relocation application, and the normalization passes above; add rolling 2 KiB window hashes for robustness.)* + +# Where it lives in Stella Ops + +* **StellaOps.Feedser**: ingest vendor advisories; map CVE → touched symbols/functions. +* **StellaOps.PatchSigRepo** (new): git‑backed registry of delta signatures (AGPL data pack). +* **StellaOps.Scanner.Webservice**: runs the normalizer/hasher against container layers and host files. +* **StellaOps.Vexer**: emits **machine‑verifiable VEX** statements (“Status=Fixed; Evidence=DeltaSig#abcd…”). +* **UI**: in the **Finding details** drawer → “Patched by backport (verified by code delta)”; badge links to the exact signature entry. + +# Pipeline (end‑to‑end) + +1. **Signature authoring** (one‑time per CVE): + + * Pull upstream vulnerable & fixed tags. + * Build both with common flags per arch; disasm diff to identify changed symbols. + * Generate normalized hashes → create `cves/CVE-YYYY-NNNN/*.json`. +2. **CI publish**: sign each signature file (DSSE), push to **Proof‑Market Ledger** mirror and internal registry. +3. **Scan time**: + + * Identify candidate ELF (`soname`/path heuristics). + * Compute normalized hashes; compare against **patched** and **vulnerable** sets. + * Emit VEX + attach proof artifact (hash, recipe, tool version). +4. **Policy**: + + * Gate releases on “Patched OR Not‑Affected by reachability”, otherwise block. + +# Handling distro drift + +* Keep multiple signatures per CVE: + + * `gcc‑O2`, `clang‑O2`, `-fstack-protector-strong`, LTO on/off. +* Prefer **symbol‑scoped** hashing over whole file. +* If symbol names are stripped: + + * Fallback to **function boundary recovery** (linear sweep + prologue heuristics) and **fuzzy block graph** matching; still run normalization. + +# Performance tips + +* Cache per‑layer ELF normalization by `(fileDigest, toolVersion)`. +* Use mmap + streaming SHA256; avoid copying. +* Parallelize per‑ELF, but cap CPU with a scheduler token. + +# Reducing false results + +* Require **dual evidence** when uncertain: `.text` hash match + small CFG checksum (basic‑block count + edge hash). +* Mark **Indeterminate** if: + + * Only `.rodata` matches, + * File is PIE with heavy inlining changes, + * LTO changed layout dramatically. +* Always record tool + recipe versions in the evidence blob for deterministic replay. + +# Data format (example) + +```json +{ + "cve": "CVE-2023-12345", + "package": "libfoo.so.1", + "arch": "x86_64", + "symbols": [ + { + "name": "foo_parse", + "scope": ".text", + "normalization": ["applyRelocs","zeroAbs","canonNops","canonJt"], + "hash": "sha256:4f1c...d9", + "size": 1184 + } + ], + "alt_signatures": [ + {"compiler":"clang-16","flags":"-O3 -fno-plt", "hash":"sha256:9ab...42"} + ], + "attestation": {"dsse":"..."} +} +``` + +# Rollout checklist (2 sprints) + +* **Sprint A** + + * Implement ELF loader + normalization passes (x86_64/aarch64). + * Build authoring tool (`stella-deltasig mk`) and signer. + * Wire Scanner → Vexer evidence pipe; UI badge. +* **Sprint B** + + * Add rolling chunk hashes + CFG micro‑checksum. + * Author top‑20 backported CVEs (OpenSSL, glibc, zlib, curl, libpng). + * Cache & perf; add air‑gapped bundle for signatures. + +# Why this is a moat + +* Competing scanners mostly trust **CVE string matching** and package versions. You ship **cryptographic, function‑level proof** that a fix is present—even across diverged distros—**without humans in the loop**. That’s hard to replicate quickly. + +If you want, I can draft the `PatchSigRepo` JSON schema, the DSSE attestation type, and a tiny CLI (`stella-deltasig`) you can drop into `scanner.webservice` today. +Below is a complete, opinionated “DeltaSig” module design that plugs into the existing Stella Ops standard CLI (single `stella` entrypoint), plus the payload schema, DSSE envelope type, and a deterministic “sigpack” format. All examples and code are .NET 10–style and keep dependencies minimal (built-in crypto + System.Text.Json). + +--- + +## 1) CLI module shape (as a first-class `stella` module) + +### Command tree + +```text +stella deltasig + mk Create an unsigned delta-signature payload JSON + sign Wrap payload in DSSE + sign + verify Verify DSSE envelope(s) + id Print signature ID (sha256 of canonical payload) + pack Build deterministic sigpack (zip) from DSSE envelopes + inspect Pretty-print payload/envelope; show fields + hashes + match Compute evidence for a given ELF against a sigpack (optional, uses extractor service) +``` + +### Output/UX rules (standard CLI conventions) + +* Default output is **human-readable**; add `--json` on any command to emit machine JSON. +* Exit codes: + + * `0` success / verified / match found + * `2` verification failed / match is “vulnerable” + * `3` indeterminate / partial + * `64` usage error (missing args) + * `70` internal error + +### Typical workflow + +```bash +# 1) Create payload +stella deltasig mk \ + --cve CVE-2023-12345 \ + --package libfoo \ + --soname libfoo.so.1 \ + --arch x86_64 \ + --abi gnu \ + --symbol foo_parse --symbol foo_init \ + --scope text \ + --hash sha256 \ + --out cves/CVE-2023-12345/libfoo/x86_64-gnu.payload.json + +# 2) Sign (DSSE) +stella deltasig sign \ + --in cves/CVE-2023-12345/libfoo/x86_64-gnu.payload.json \ + --key keys/stellaops-patches.ecdsa-p256.pem \ + --out cves/CVE-2023-12345/libfoo/x86_64-gnu.dsse.json + +# 3) Verify +stella deltasig verify \ + --in cves/CVE-2023-12345/libfoo/x86_64-gnu.dsse.json \ + --pub keys/stellaops-patches.ecdsa-p256.pub.pem + +# 4) Pack for offline distribution +stella deltasig pack \ + --in-dir cves/ \ + --out stellaops-deltasigpack-2025-12.zip +``` + +--- + +## 2) File formats + +### 2.1 Delta signature payload (canonical JSON, signed via DSSE) + +**PayloadType** (DSSE): +`application/vnd.stellaops.deltasig.v1+json` + +**Design goals** + +* Payload is **deterministic**: no timestamps, no author fields. +* Signature ID is `sha256(canonical_payload_bytes)`. + +#### Payload structure (`DeltaSigPayloadV1`) + +```json +{ + "schema": "stellaops.deltasig.v1", + "cve": "CVE-2023-12345", + "package": { + "name": "libfoo", + "soname": "libfoo.so.1" + }, + "target": { + "arch": "x86_64", + "abi": "gnu" + }, + "normalization": { + "recipeId": "elf.delta.norm.v1", + "steps": [ + "applyRelocs", + "zeroRelocTargets", + "canonNops", + "canonPltGot", + "canonJumpTables", + "zeroPadding" + ] + }, + "symbols": [ + { + "name": "foo_parse", + "scope": ".text", + "hashAlg": "sha256", + "hashHex": "4f1c...d9", + "sizeBytes": 1184, + "chunks": [ + { "offset": 0, "sizeBytes": 2048, "hashHex": "aa.." } + ], + "cfg": { "bbCount": 42, "edgeHashHex": "bb.." } + } + ] +} +``` + +Notes: + +* `chunks` and `cfg` are optional but recommended for resilience. +* `hashHex` is lowercase hex of the **normalized bytes** of the symbol region. + +### 2.2 DSSE envelope (signed wrapper) + +Minimal DSSE JSON: + +```json +{ + "payloadType": "application/vnd.stellaops.deltasig.v1+json", + "payload": "BASE64URL( canonical_payload_bytes )", + "signatures": [ + { + "keyid": "sha256:ab12...ef", + "sig": "BASE64URL( signature_over_PAE )" + } + ] +} +``` + +### 2.3 Sigpack (deterministic offline bundle) + +A **ZIP** with deterministic ordering and timestamps forced to a constant (e.g., 1980-01-01 for ZIP compatibility). + +Contents: + +```text +index.json +sigs/.dsse.json +(optional) keys/.pub.pem +(optional) meta.json +``` + +`index.json` (sorted by `sigId`): + +```json +{ + "schema": "stellaops.deltasigpack.v1", + "entries": [ + { + "sigId": "sha256:...", + "cve": "CVE-2023-12345", + "package": "libfoo", + "soname": "libfoo.so.1", + "arch": "x86_64", + "abi": "gnu", + "path": "sigs/sha256-....dsse.json" + } + ] +} +``` + +--- + +## 3) How to integrate as a module in the Stella Ops standard CLI + +### 3.1 Minimal module contract (stable SPI) + +Create a tiny contract assembly used by the main CLI and all modules: + +`src/StellaOps.Cli.Abstractions/IStellaCliModule.cs` + +```csharp +namespace StellaOps.Cli.Abstractions; + +public interface IStellaCliModule +{ + string Name { get; } // "deltasig" + string Description { get; } // one-liner + void Register(InvocationContext ctx, Command root); +} +``` + +`InvocationContext` can carry DI/services/config: + +```csharp +namespace StellaOps.Cli.Abstractions; + +public sealed record InvocationContext( + IServiceProvider Services, + string[] Args, + TextWriter Out, + TextWriter Err +); +``` + +### 3.2 Main CLI loads modules (built-in + plugin folder) + +`src/StellaOps.Cli/Program.cs` + +```csharp +using System.CommandLine; +using System.CommandLine.Invocation; +using System.Reflection; +using System.Runtime.Loader; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; +using StellaOps.Cli.Abstractions; + +var builder = Host.CreateApplicationBuilder(args); + +// Register shared services (logging, config, etc.) +builder.Services.AddSingleton(_ => Console.Out); +builder.Services.AddSingleton(_ => Console.Error); + +// Load built-in modules by referencing their assemblies, +// plus optional external modules from "./modules". +var modules = LoadModules(AppContext.BaseDirectory); + +var host = builder.Build(); +var services = host.Services; + +var root = new RootCommand("Stella Ops CLI"); + +var ctx = new InvocationContext(services, args, Console.Out, Console.Error); + +foreach (var m in modules.OrderBy(m => m.Name, StringComparer.Ordinal)) + m.Register(ctx, root); + +return await root.InvokeAsync(args); + +static IReadOnlyList LoadModules(string baseDir) +{ + var result = new List(); + + // 1) Built-in: scan already loaded assemblies + result.AddRange(InstantiateModules(AppDomain.CurrentDomain.GetAssemblies())); + + // 2) Plugins: ./modules/*.dll + var modulesDir = Path.Combine(baseDir, "modules"); + if (Directory.Exists(modulesDir)) + { + foreach (var dll in Directory.EnumerateFiles(modulesDir, "*.dll", SearchOption.TopDirectoryOnly) + .OrderBy(x => x, StringComparer.Ordinal)) + { + try + { + var asm = AssemblyLoadContext.Default.LoadFromAssemblyPath(dll); + result.AddRange(InstantiateModules(new[] { asm })); + } + catch + { + // keep CLI robust: ignore broken plugins + } + } + } + + // Deduplicate by Name (first wins) + return result.GroupBy(m => m.Name, StringComparer.Ordinal).Select(g => g.First()).ToList(); +} + +static IEnumerable InstantiateModules(IEnumerable assemblies) +{ + foreach (var asm in assemblies) + { + Type[] types; + try { types = asm.GetTypes(); } + catch { continue; } + + foreach (var t in types) + { + if (t.IsAbstract || t.IsInterface) continue; + if (!typeof(IStellaCliModule).IsAssignableFrom(t)) continue; + if (t.GetConstructor(Type.EmptyTypes) is null) continue; + + IStellaCliModule? module = null; + try { module = (IStellaCliModule)Activator.CreateInstance(t)!; } + catch { /* ignore */ } + + if (module is not null) yield return module; + } + } +} +``` + +This approach keeps “module = assembly” without forcing a rigid plugin framework. + +--- + +## 4) The DeltaSig module implementation (CLI wiring) + +### 4.1 Project layout + +```text +src/ + StellaOps.Cli/ + StellaOps.Cli.Abstractions/ + StellaOps.PatchSig/ # models + canonical JSON + DSSE + pack builder + StellaOps.Cli.Modules.DeltaSig/ # the CLI module, depends on PatchSig +``` + +### 4.2 Module registration + +`src/StellaOps.Cli.Modules.DeltaSig/DeltaSigModule.cs` + +```csharp +using System.CommandLine; +using StellaOps.Cli.Abstractions; +using StellaOps.PatchSig; + +namespace StellaOps.Cli.Modules.DeltaSig; + +public sealed class DeltaSigModule : IStellaCliModule +{ + public string Name => "deltasig"; + public string Description => "Create, sign, verify, and pack patch-aware ELF delta signatures."; + + public void Register(InvocationContext ctx, Command root) + { + var cmd = new Command("deltasig", Description); + + cmd.AddCommand(DeltaSigCommands.Mk()); + cmd.AddCommand(DeltaSigCommands.Sign()); + cmd.AddCommand(DeltaSigCommands.Verify()); + cmd.AddCommand(DeltaSigCommands.Id()); + cmd.AddCommand(DeltaSigCommands.Pack()); + cmd.AddCommand(DeltaSigCommands.Inspect()); + // cmd.AddCommand(DeltaSigCommands.Match()); // optional (requires ELF extractor service) + + root.AddCommand(cmd); + + // Optional alias: "stella sig delta ..." + var sig = root.Subcommands.FirstOrDefault(c => c.Name == "sig"); + if (sig is not null) + { + var deltaAlias = new Command("delta", Description); + foreach (var sc in cmd.Subcommands) deltaAlias.AddCommand(sc); + sig.AddCommand(deltaAlias); + } + } +} +``` + +### 4.3 Commands (handlers call PatchSig library) + +`src/StellaOps.Cli.Modules.DeltaSig/DeltaSigCommands.cs` + +```csharp +using System.CommandLine; +using System.CommandLine.NamingConventionBinder; +using StellaOps.PatchSig; +using StellaOps.PatchSig.Dsse; +using StellaOps.PatchSig.Packaging; + +namespace StellaOps.Cli.Modules.DeltaSig; + +internal static class DeltaSigCommands +{ + public static Command Mk() + { + var c = new Command("mk", "Create an unsigned delta-signature payload JSON."); + var cve = new Option("--cve") { IsRequired = true }; + var pkg = new Option("--package") { IsRequired = true }; + var soname = new Option("--soname") { IsRequired = true }; + var arch = new Option("--arch") { IsRequired = true }; + var abi = new Option("--abi", () => "gnu"); + var symbols = new Option("--symbol") { AllowMultipleArgumentsPerToken = true, IsRequired = true }; + var scope = new Option("--scope", () => "text"); // text|rodata|both + var outFile = new Option("--out") { IsRequired = true }; + + c.AddOption(cve); c.AddOption(pkg); c.AddOption(soname); c.AddOption(arch); c.AddOption(abi); + c.AddOption(symbols); c.AddOption(scope); c.AddOption(outFile); + + c.Handler = CommandHandler.Create((cve, package, soname, arch, abi, symbol, scope, @out) => + { + // IMPORTANT: mk here creates the *structure*. Filling hashes is typically done by an extractor. + // If you have an ELF extractor service, plug it here to compute hashHex/sizeBytes/chunks/cfg. + var payload = DeltaSigPayloadV1.CreateSkeleton(cve, package, soname, arch, abi, symbol, scope); + + var bytes = CanonicalJson.Serialize(payload); + Directory.CreateDirectory(Path.GetDirectoryName(Path.GetFullPath(@out))!); + File.WriteAllBytes(@out, bytes); + return 0; + }); + + return c; + } + + public static Command Id() + { + var c = new Command("id", "Print signature ID (sha256 of canonical payload)."); + var input = new Option("--in") { IsRequired = true }; + c.AddOption(input); + + c.Handler = CommandHandler.Create((@in) => + { + var payloadBytes = File.ReadAllBytes(@in); + var sigId = SigId.ComputeSha256Hex(payloadBytes); + Console.Out.WriteLine($"sha256:{sigId}"); + return 0; + }); + + return c; + } + + public static Command Sign() + { + var c = new Command("sign", "Wrap payload in DSSE and sign."); + var input = new Option("--in") { IsRequired = true }; + var key = new Option("--key") { IsRequired = true }; + var outp = new Option("--out") { IsRequired = true }; + var alg = new Option("--alg", () => "ecdsa-p256-sha256"); // ecdsa-p256-sha256|rsa-pss-sha256 + c.AddOption(input); c.AddOption(key); c.AddOption(outp); c.AddOption(alg); + + c.Handler = CommandHandler.Create((@in, key, @out, alg) => + { + var payloadBytes = File.ReadAllBytes(@in); + + var signer = DsseSignerFactory.CreateFromPem(key, alg); + var env = DsseEnvelope.CreateSigned( + payloadType: DsseTypes.DeltaSigV1, + payloadBytes: payloadBytes, + signer: signer + ); + + var envBytes = CanonicalJson.Serialize(env); + Directory.CreateDirectory(Path.GetDirectoryName(Path.GetFullPath(@out))!); + File.WriteAllBytes(@out, envBytes); + return 0; + }); + + return c; + } + + public static Command Verify() + { + var c = new Command("verify", "Verify DSSE envelope signature(s)."); + var input = new Option("--in") { IsRequired = true }; + var pub = new Option("--pub") { IsRequired = true }; + c.AddOption(input); c.AddOption(pub); + + c.Handler = CommandHandler.Create((@in, pub) => + { + var envBytes = File.ReadAllBytes(@in); + var env = CanonicalJson.Deserialize(envBytes); + + var verifier = DsseVerifierFactory.CreateFromPem(pub); + + var ok = env.VerifyAny(verifier, out var matchedKeyId); + if (!ok) + { + Console.Error.WriteLine("DSSE verification FAILED."); + return 2; + } + + Console.Out.WriteLine($"DSSE verification OK. keyid={matchedKeyId}"); + return 0; + }); + + return c; + } + + public static Command Inspect() + { + var c = new Command("inspect", "Inspect payload or DSSE envelope."); + var input = new Option("--in") { IsRequired = true }; + c.AddOption(input); + + c.Handler = CommandHandler.Create((@in) => + { + var bytes = File.ReadAllBytes(@in); + + // Heuristic: DSSE envelope contains "payloadType" + if (bytes.AsSpan().IndexOf(System.Text.Encoding.UTF8.GetBytes("\"payloadType\"")) >= 0) + { + var env = CanonicalJson.Deserialize(bytes); + Console.Out.WriteLine($"payloadType: {env.PayloadType}"); + Console.Out.WriteLine($"payloadBytes: {Base64Url.Decode(env.Payload).Length}"); + Console.Out.WriteLine($"signatures: {env.Signatures.Count}"); + } + else + { + var payload = CanonicalJson.Deserialize(bytes); + Console.Out.WriteLine($"{payload.Cve} {payload.Package.Name} {payload.Target.Arch}-{payload.Target.Abi}"); + Console.Out.WriteLine($"symbols: {payload.Symbols.Count}"); + } + + return 0; + }); + + return c; + } + + public static Command Pack() + { + var c = new Command("pack", "Build deterministic sigpack (zip) from DSSE envelopes under a directory."); + var inDir = new Option("--in-dir") { IsRequired = true }; + var outp = new Option("--out") { IsRequired = true }; + c.AddOption(inDir); c.AddOption(outp); + + c.Handler = CommandHandler.Create((inDir, @out) => + { + SigPackBuilder.BuildFromDirectory(inDir, @out); + Console.Out.WriteLine(@out); + return 0; + }); + + return c; + } +} +``` + +The module is “real”: `mk/sign/verify/id/pack/inspect` are fully implementable now. `match` can be added once you plug in the ELF delta extractor you already want in `scanner.webservice`. + +--- + +## 5) PatchSig library: canonical JSON, signature IDs, DSSE sign/verify, deterministic pack + +### 5.1 Canonical JSON (field-order deterministic) + +You control determinism by writing properties in a fixed order (no reliance on reflection order). + +`src/StellaOps.PatchSig/CanonicalJson.cs` + +```csharp +using System.Text; +using System.Text.Json; + +namespace StellaOps.PatchSig; + +public static class CanonicalJson +{ + private static readonly JsonSerializerOptions Options = new() + { + WriteIndented = false, + PropertyNamingPolicy = null, + DictionaryKeyPolicy = null + }; + + // For payload/envelope models where property order matters, implement custom writers. + public static byte[] Serialize(T value) + => JsonSerializer.SerializeToUtf8Bytes(value, Options); + + public static T Deserialize(byte[] utf8) + => JsonSerializer.Deserialize(utf8, Options) + ?? throw new InvalidOperationException("Invalid JSON."); +} + +public static class SigId +{ + public static string ComputeSha256Hex(ReadOnlySpan canonicalPayloadBytes) + { + var hash = System.Security.Cryptography.SHA256.HashData(canonicalPayloadBytes); + return Convert.ToHexString(hash).ToLowerInvariant(); + } +} +``` + +If you want strict canonicalization beyond fixed-order models (e.g., arbitrary JSON), replace `Serialize` with a JCS implementation; for DeltaSig you typically don’t need that if you own the writer. + +### 5.2 Payload model (deterministic; no timestamps) + +`src/StellaOps.PatchSig/DeltaSigPayloadV1.cs` + +```csharp +namespace StellaOps.PatchSig; + +public sealed record DeltaSigPayloadV1( + string Schema, + string Cve, + PackageRef Package, + TargetRef Target, + NormalizationRef Normalization, + List Symbols +) +{ + public static DeltaSigPayloadV1 CreateSkeleton( + string cve, string package, string soname, string arch, string abi, + IEnumerable symbols, string scope) + { + var steps = new[] + { + "applyRelocs", + "zeroRelocTargets", + "canonNops", + "canonPltGot", + "canonJumpTables", + "zeroPadding" + }; + + var symScope = scope switch + { + "text" => ".text", + "rodata" => ".rodata", + "both" => ".text", // skeleton puts .text; extractor can add rodata sigs too + _ => ".text" + }; + + return new DeltaSigPayloadV1( + Schema: "stellaops.deltasig.v1", + Cve: cve, + Package: new PackageRef(package, soname), + Target: new TargetRef(arch, abi), + Normalization: new NormalizationRef("elf.delta.norm.v1", steps.ToList()), + Symbols: symbols.Distinct(StringComparer.Ordinal).OrderBy(x => x, StringComparer.Ordinal) + .Select(s => new SymbolSig( + Name: s, + Scope: symScope, + HashAlg: "sha256", + HashHex: "", + SizeBytes: 0, + Chunks: null, + Cfg: null)) + .ToList() + ); + } +} + +public sealed record PackageRef(string Name, string Soname); +public sealed record TargetRef(string Arch, string Abi); +public sealed record NormalizationRef(string RecipeId, List Steps); + +public sealed record SymbolSig( + string Name, + string Scope, + string HashAlg, + string HashHex, + int SizeBytes, + List? Chunks, + CfgSig? Cfg +); + +public sealed record ChunkSig(int Offset, int SizeBytes, string HashHex); +public sealed record CfgSig(int BbCount, string EdgeHashHex); +``` + +### 5.3 DSSE sign/verify (PAE included) + +`src/StellaOps.PatchSig/Dsse/DsseEnvelope.cs` + +```csharp +using System.Text; + +namespace StellaOps.PatchSig.Dsse; + +public static class DsseTypes +{ + public const string DeltaSigV1 = "application/vnd.stellaops.deltasig.v1+json"; +} + +public sealed record DsseEnvelope( + string PayloadType, + string Payload, + List Signatures +) +{ + public static DsseEnvelope CreateSigned(string payloadType, byte[] payloadBytes, IDsseSigner signer) + { + var pae = DssePae.Encode(payloadType, payloadBytes); + var sig = signer.Sign(pae); + + return new DsseEnvelope( + PayloadType: payloadType, + Payload: Base64Url.Encode(payloadBytes), + Signatures: new List + { + new DsseSignature(signer.KeyId, Base64Url.Encode(sig)) + } + ); + } + + public bool VerifyAny(IDsseVerifier verifier, out string? matchedKeyId) + { + matchedKeyId = null; + var payloadBytes = Base64Url.Decode(Payload); + var pae = DssePae.Encode(PayloadType, payloadBytes); + + foreach (var s in Signatures) + { + var sigBytes = Base64Url.Decode(s.Sig); + if (verifier.Verify(pae, sigBytes)) + { + matchedKeyId = s.KeyId; + return true; + } + } + return false; + } +} + +public sealed record DsseSignature(string KeyId, string Sig); + +public static class DssePae +{ + // DSSEv1 PAE: "DSSEv1" SP len(pt) SP pt SP len(payload) SP payload + public static byte[] Encode(string payloadType, ReadOnlySpan payload) + { + var ptBytes = Encoding.UTF8.GetBytes(payloadType); + var header = $"DSSEv1 {ptBytes.Length} {payloadType} {payload.Length} "; + var headerBytes = Encoding.UTF8.GetBytes(header); + + var outBytes = new byte[headerBytes.Length + payload.Length]; + Buffer.BlockCopy(headerBytes, 0, outBytes, 0, headerBytes.Length); + payload.CopyTo(outBytes.AsSpan(headerBytes.Length)); + return outBytes; + } +} + +public static class Base64Url +{ + public static string Encode(ReadOnlySpan bytes) + => Convert.ToBase64String(bytes.ToArray()) + .TrimEnd('=').Replace('+', '-').Replace('/', '_'); + + public static byte[] Decode(string s) + { + s = s.Replace('-', '+').Replace('_', '/'); + switch (s.Length % 4) + { + case 2: s += "=="; break; + case 3: s += "="; break; + } + return Convert.FromBase64String(s); + } +} + +public interface IDsseSigner +{ + string KeyId { get; } + byte[] Sign(ReadOnlySpan pae); +} + +public interface IDsseVerifier +{ + bool Verify(ReadOnlySpan pae, ReadOnlySpan signature); +} +``` + +`src/StellaOps.PatchSig/Dsse/DsseSignerFactory.cs` + +```csharp +using System.Security.Cryptography; +using System.Text; + +namespace StellaOps.PatchSig.Dsse; + +public static class DsseSignerFactory +{ + public static IDsseSigner CreateFromPem(string pemPath, string alg) + { + var pem = File.ReadAllText(pemPath, Encoding.UTF8); + + return alg switch + { + "ecdsa-p256-sha256" => new EcdsaP256Signer(pem), + "rsa-pss-sha256" => new RsaPssSigner(pem), + _ => throw new ArgumentOutOfRangeException(nameof(alg), $"Unsupported alg: {alg}") + }; + } + + private sealed class EcdsaP256Signer : IDsseSigner + { + private readonly ECDsa _key; + public string KeyId { get; } + + public EcdsaP256Signer(string pem) + { + _key = ECDsa.Create(); + _key.ImportFromPem(pem); + + // keyid = sha256(spki-der) + var spki = _key.ExportSubjectPublicKeyInfo(); + KeyId = "sha256:" + Convert.ToHexString(SHA256.HashData(spki)).ToLowerInvariant(); + } + + public byte[] Sign(ReadOnlySpan pae) + => _key.SignData(pae.ToArray(), HashAlgorithmName.SHA256); + } + + private sealed class RsaPssSigner : IDsseSigner + { + private readonly RSA _key; + public string KeyId { get; } + + public RsaPssSigner(string pem) + { + _key = RSA.Create(); + _key.ImportFromPem(pem); + + var spki = _key.ExportSubjectPublicKeyInfo(); + KeyId = "sha256:" + Convert.ToHexString(SHA256.HashData(spki)).ToLowerInvariant(); + } + + public byte[] Sign(ReadOnlySpan pae) + => _key.SignData(pae.ToArray(), HashAlgorithmName.SHA256, RSASignaturePadding.Pss); + } +} + +public static class DsseVerifierFactory +{ + public static IDsseVerifier CreateFromPem(string pemPath) + { + var pem = File.ReadAllText(pemPath, Encoding.UTF8); + + // Heuristic: if PEM contains "RSA" use RSA, else ECDSA. + if (pem.Contains("BEGIN RSA", StringComparison.OrdinalIgnoreCase)) + return new RsaPssVerifier(pem); + + return new EcdsaVerifier(pem); + } + + private sealed class EcdsaVerifier : IDsseVerifier + { + private readonly ECDsa _pub; + public EcdsaVerifier(string pem) + { + _pub = ECDsa.Create(); + _pub.ImportFromPem(pem); + } + + public bool Verify(ReadOnlySpan pae, ReadOnlySpan signature) + => _pub.VerifyData(pae.ToArray(), signature.ToArray(), HashAlgorithmName.SHA256); + } + + private sealed class RsaPssVerifier : IDsseVerifier + { + private readonly RSA _pub; + public RsaPssVerifier(string pem) + { + _pub = RSA.Create(); + _pub.ImportFromPem(pem); + } + + public bool Verify(ReadOnlySpan pae, ReadOnlySpan signature) + => _pub.VerifyData(pae.ToArray(), signature.ToArray(), HashAlgorithmName.SHA256, RSASignaturePadding.Pss); + } +} +``` + +### 5.4 Deterministic pack builder + +`src/StellaOps.PatchSig/Packaging/SigPackBuilder.cs` + +```csharp +using System.IO.Compression; +using StellaOps.PatchSig.Dsse; + +namespace StellaOps.PatchSig.Packaging; + +public static class SigPackBuilder +{ + private static readonly DateTimeOffset ZipTime = new(1980, 1, 1, 0, 0, 0, TimeSpan.Zero); + + public static void BuildFromDirectory(string inDir, string outZip) + { + var dsseFiles = Directory.EnumerateFiles(inDir, "*.dsse.json", SearchOption.AllDirectories) + .OrderBy(p => p, StringComparer.Ordinal) + .ToList(); + + var entries = new List(); + var sigBlobs = new List<(string SigId, byte[] EnvBytes)>(); + + foreach (var f in dsseFiles) + { + var envBytes = File.ReadAllBytes(f); + var env = CanonicalJson.Deserialize(envBytes); + + var payloadBytes = Base64Url.Decode(env.Payload); + var sigIdHex = SigId.ComputeSha256Hex(payloadBytes); + var sigId = $"sha256:{sigIdHex}"; + + // best-effort parse payload for index fields + var payload = CanonicalJson.Deserialize(payloadBytes); + + var relPath = $"sigs/{sigId.Replace(':','-')}.dsse.json"; + entries.Add(new SigPackIndexEntry( + SigId: sigId, + Cve: payload.Cve, + Package: payload.Package.Name, + Soname: payload.Package.Soname, + Arch: payload.Target.Arch, + Abi: payload.Target.Abi, + Path: relPath + )); + + sigBlobs.Add((sigId, envBytes)); + } + + var index = new SigPackIndexV1( + Schema: "stellaops.deltasigpack.v1", + Entries: entries.OrderBy(e => e.SigId, StringComparer.Ordinal).ToList() + ); + var indexBytes = CanonicalJson.Serialize(index); + + Directory.CreateDirectory(Path.GetDirectoryName(Path.GetFullPath(outZip))!); + if (File.Exists(outZip)) File.Delete(outZip); + + using var fs = File.Create(outZip); + using var zip = new ZipArchive(fs, ZipArchiveMode.Create); + + AddEntry(zip, "index.json", indexBytes); + + foreach (var (sigId, bytes) in sigBlobs.OrderBy(x => x.SigId, StringComparer.Ordinal)) + { + var rel = $"sigs/{sigId.Replace(':','-')}.dsse.json"; + AddEntry(zip, rel, bytes); + } + } + + private static void AddEntry(ZipArchive zip, string path, byte[] bytes) + { + var entry = zip.CreateEntry(path, CompressionLevel.Optimal); + entry.LastWriteTime = ZipTime; + using var s = entry.Open(); + s.Write(bytes, 0, bytes.Length); + } +} + +public sealed record SigPackIndexV1(string Schema, List Entries); + +public sealed record SigPackIndexEntry( + string SigId, + string Cve, + string Package, + string Soname, + string Arch, + string Abi, + string Path +); +``` + +--- + +## 6) Where ELF extraction plugs in (without contaminating the CLI contract) + +You keep the CLI module clean by depending on an **extractor interface** that lives in scanner/webservice libraries, not in the CLI itself. + +Example SPI (lives in `StellaOps.PatchSig` or `StellaOps.Scanner.ElfDelta.Abstractions`): + +```csharp +public interface IElfDeltaExtractor +{ + // Takes a skeleton payload and fills hashHex/sizeBytes/chunks/cfg for each symbol entry. + DeltaSigPayloadV1 PopulateFromElf(DeltaSigPayloadV1 skeleton, string elfPath); +} +``` + +Then `stella deltasig mk --elf /path/to/libfoo.so.1 ...` can become a “fully automatic” authoring tool by resolving `IElfDeltaExtractor` from DI when present. If it isn’t present, `mk` still creates a valid skeleton that can be filled by CI tooling. + +This respects your architectural split: heavy analysis logic stays in scanner/webservice libraries; the CLI module remains a thin orchestration surface. + +--- + +## 7) What you get immediately + +* A first-class `stella deltasig` module with working: + + * deterministic payload emission + * DSSE signing and verification (ECDSA P-256 or RSA-PSS) + * deterministic offline pack bundling + * stable signature IDs +* A clean seam to plug your ELF normalization/hasher implementation (the complex part) without redesigning CLI later. + +If you want next, I can add the `match` command and define the exact evidence JSON object that `scanner.webservice` should emit into VEX (“Fixed by backport (verified)”) so the CLI and scanner share the same evidence type byte-for-byte. diff --git a/docs/product-advisories/30-Dec-2025 - Building a Golden Set for Patch Validation.md b/docs/product-advisories/30-Dec-2025 - Building a Golden Set for Patch Validation.md new file mode 100644 index 000000000..867b7848d --- /dev/null +++ b/docs/product-advisories/30-Dec-2025 - Building a Golden Set for Patch Validation.md @@ -0,0 +1,617 @@ +Here’s a compact, plug‑and‑play plan to build a **cross‑distro “golden set”** so your retrieval can correctly handle **backported fixes** and avoid false “still vulnerable” flags. + +--- + +# What this golden set is + +A small, curated corpus of tuples **(distro, release, package, CVE)** with: + +* the **vendor‑declared fixed version** (what the distro claims) +* a **counterexample** where **upstream is still affected** but the distro **backported** the patch (so version comparison alone would be misleading) + +Use it as regression tests + seed facts for your policy engine and matchers. + +--- + +# Minimum schema (normalize for reuse) + +**Tables** + +* `vendor_package` + `(vendor_id, distro, release, src_name, bin_name, epoch, version, revision, arch)` +* `cve` + `(cve_id, description, CWE, published, severity, cvss_vector)` +* `fix_decl` (vendor declarations) + `(distro, release, src_name, cve_id, status ENUM('fixed','not_affected','affected','wont_fix'), fixed_epoch, fixed_version, fixed_revision, evidence_uri, evidence_hash, declared_at)` +* `patch_evidence` (backport facts) + `(distro, release, src_name, cve_id, patch_id, upstream_commit, backport_commit, applied_in_epoch, applied_in_version, applied_in_revision, diff_hash, proving_fn ENUM('hunk','symbol','function','binary'), notes)` +* `upstream_affects` (ground truth on upstream tags) + `(project, cve_id, affected_range (SemVer/commit range), last_affected_tag, first_fixed_tag, fix_commit)` +* `golden_case` (test harness) + `(case_id, distro, release, src_name, bin_name, cve_id, vendor_fixed_spec, upstream_state ENUM('still_affected','fixed'), backport_present BOOL, rationale)` + +**Indexes** + +* `idx_fix_decl_key (distro, release, src_name, cve_id)` +* `idx_patch_evidence_key (distro, release, src_name, cve_id)` +* `idx_upstream_affects (project, cve_id)` + +--- + +# Version math you must use + +Implement distro‑specific comparators: + +* **Debian/Ubuntu**: `dpkg --compare-versions` (Epoch:Version-Revision) +* **RHEL/Fedora/CentOS/SUSE**: **RPMVERCMP** (Epoch:Version-Release) +* **Alpine**: **apk version** rules + Store a normalized sortable key (e.g., `verkey`) alongside raw fields for each family. + +--- + +# Golden‑set curation algorithm (daily job) + +1. **Select targets** + +* Choose top N packages (openssl, glibc, curl, zlib, libxml2, expat, xz, sudo, bash, systemd, sqlite, curl, busybox, python3 stdlib, musl, libssh2, libx11, nginx, apache, postgresql, mariadb, openssh). +* Cross all with major CVEs known to have **backports**. + +2. **Ingest vendor claims** + +* Scrape/consume security trackers (Debian, Ubuntu USN, RHEL, SUSE, Alpine, Fedora). Normalize into `fix_decl`. +* Compute `verkey_fixed`. + +3. **Verify backport reality** + +* For each `(distro, release, pkg, cve)` with status “fixed” where **upstream tag** still falls in `affected_range`: + + * Pull **src package diff** (dsc+patches or SRPM .patch). + * Extract fix‑hunks (functions/symbols) from upstream `fix_commit`. + * Run **proving functions**: + + * `hunk` match: patch hunks present + * `symbol/function` match: AST/name diff present + * `binary` match: pattern in compiled object (for golden set, keep source‑level first) + * If proof ≥ threshold, write to `patch_evidence` and set `backport_present=true` in `golden_case`. + +4. **Create counterexample** + +* Ensure at least one case per distro where: + + * **Upstream version number looks vulnerable**, but distro has **backport evidence** → mark as **“counterexample”** in `golden_case`. + +5. **Attest facts** + +* Generate DSSE/in‑toto attestations for each row (content hash of patches/diffs + URLs). Store `evidence_hash`. + +--- + +# Retrieval‑time decision function (pseudo) + +``` +bool is_vulnerable(pkg, ver, distro, release, cve): + decl = get_fix_decl(distro, release, pkg.src, cve) + if decl is null: + return heuristic_by_upstream_ranges(pkg.project, ver, cve) + + if decl.status == 'not_affected': return false + if decl.status == 'wont_fix': return true // unless patch_evidence says otherwise + + // status == 'fixed' -> check two paths + if compare(ver, decl.fixed_spec, distro_family) >= 0: + return false // version >= declared fixed + + // version < declared fixed: still check for backport proof pinned to our exact build + if has_patch_evidence(distro, release, pkg.src, cve, ver): + return false // verified backport on this version/build + + return true +``` + +**Note:** `has_patch_evidence` should accept **(epoch, version, revision)** and allow `applied_in_* <= installed_*`. + +--- + +# Golden test harness (what “must pass”) + +For each `golden_case`: + +1. Resolve installed `(epoch,version,revision)`. +2. Evaluate `is_vulnerable`. +3. Assert expected: + + * **Vendor‑fixed + backport_present → expected false** even if upstream says affected. + * **No backport + version < fixed_spec → expected true**. + +Emit a short **VEX** (CycloneDX VEX or CSAF) per case to keep your engine VEX‑first. + +--- + +# Minimal data loaders (first pass) + +* **Debian/Ubuntu**: `security-tracker`, USN JSON, `Sources` + `.dsc` + `debian/patches/*`. +* **RHEL/Fedora/SUSE**: OVAL/OVAL‑RPM, advisories (RHSA/SUSE‑SU), SRPM patches. +* **Alpine**: `secdb`, `APKBUILD` diffs (`.patch` in `community/main`). + +--- + +# Ship list (MVP → Week 1–2) + +* Parsers: dpkg/rpm/apk version compare libs in C# (+ test vectors). +* Ingestors for **Debian, Ubuntu, RHEL, SUSE, Alpine, Fedora** → `fix_decl`. +* Patch proof: hunk‑matcher (line‑fuzzy, filename maps), symbol‑finder (ctags or Roslyn/ctags‑like for C). +* 50–100 curated `golden_case` rows with airtight evidence. + +If you want, I can drop a ready‑to‑use PostgreSQL DDL + sample rows and a C# `VersionComparer` + `BackportProof` interface next. +# Golden Set of Backport Test Cases (Distro – Release – Package – CVE) + +Each row highlights a case where a distro shipped a **patched older version** below the upstream fixed version. This causes naive version checks to wrongly flag the package as vulnerable. We include the vendor’s fixed package version, the upstream version range still affected (i.e. up to but _not_ including the upstream fix), evidence of the backport (patch/changelog references), a flag if upstream would consider the vendor’s version vulnerable, and a brief rationale. + +| **Distro (Release)** | **Source Package** | **CVE ID** | **Vendor Fixed Version** | **Upstream Affected Versions** | **Backport Evidence** | **Upstream Says Affected?** | **Rationale** | +| --- | --- | --- | --- | --- | --- | --- | --- | +| Debian 7 “Wheezy” | openssl | CVE-2014-0160 | 1.0.1e-2+deb7u5[lists.debian.org](https://lists.debian.org/debian-security-announce/2014/msg00071.html#:~:text=For%20the%20stable%20distribution%20,2%2Bdeb7u5) | 1.0.1 through 1.0.1f (fixed in 1.0.1g)[security-tracker.debian.org](https://security-tracker.debian.org/tracker/CVE-2014-0160#:~:text=Name%20CVE,Debian%20ELTS%2C%20%208%20Red)[security-tracker.debian.org](https://security-tracker.debian.org/tracker/CVE-2014-0160#:~:text=Package%20Type%20Release%20Fixed%20Version,1743883) | **Yes** (1.0.1e < 1.0.1g) | Version 1.0.1e with Heartbleed patch applied (Debian backported fix)[lists.debian.org](https://lists.debian.org/debian-security-announce/2014/msg00071.html#:~:text=For%20the%20stable%20distribution%20,2%2Bdeb7u5). Upstream requires 1.0.1g, so 1.0.1e is normally seen as vulnerable. | | +| RHEL 6 (6.5) | openssl | CVE-2014-0160 | 1.0.1e-16.el6\_5.7[helpdesk.kaseya.com](https://helpdesk.kaseya.com/hc/en-gb/articles/4407522717329-CVE-2014-0160-OpenSSL-Heartbleed-Vulnerability#:~:text=If%20CentOS6%2C%20apply%20Unitrends%20security,42.el6) | 1.0.1 through 1.0.1f (fixed in 1.0.1g)[security-tracker.debian.org](https://security-tracker.debian.org/tracker/CVE-2014-0160#:~:text=Description%20The%20,Debian%20ELTS%2C%20%208%20Red) | **Yes** (1.0.1e < 1.0.1g) | Version 1.0.1e with Heartbleed fix backported (openssl-1.0.1e-16.el6). Upstream 1.0.1e is Heartbleed-affected[helpdesk.kaseya.com](https://helpdesk.kaseya.com/hc/en-gb/articles/4407522717329-CVE-2014-0160-OpenSSL-Heartbleed-Vulnerability#:~:text=If%20CentOS6%2C%20apply%20Unitrends%20security,42.el6). | | +| RHEL 7 | openssl | CVE-2020-1971 | 1.0.2k-21.el7\_9[suse.com](https://www.suse.com/security/cve/CVE-2020-1971.html#:~:text=CVE,21.el7_9%3B%20openssl)[linuxsecurity.com](https://linuxsecurity.com/advisories/scilinux/scilinux-slsa-2020-5566-1-important-openssl-on-sl7-x-x86-64-14-12-13#:~:text=Update%20linuxsecurity,21.el7_9.i686.rpm) | OpenSSL ≤1.1.1h and 1.0.2(-unsupported) (fixed in 1.1.1i & 1.0.2u)[openssl-library.org](https://openssl-library.org/news/timeline/#:~:text=Release%20and%20Advisory%20Timeline%20,Truncated%20packet%20could) | **Yes** (1.0.2k < 1.0.2u) | OpenSSL 1.0.2k with NULL pointer deref fix backported (RHEL7 openssl-1.0.2k-21). Upstream says 1.0.2k is affected[suse.com](https://www.suse.com/security/cve/CVE-2020-1971.html#:~:text=CVE,21.el7_9%3B%20openssl)[linuxsecurity.com](https://linuxsecurity.com/advisories/scilinux/scilinux-slsa-2020-5566-1-important-openssl-on-sl7-x-x86-64-14-12-13#:~:text=Update%20linuxsecurity,21.el7_9.i686.rpm). | | +| Ubuntu 20.04 LTS “Focal” | apache2 | CVE-2024-39573 | 2.4.41-4ubuntu3.19[ubuntu.com](https://ubuntu.com/security/CVE-2024-39573#:~:text=22) | Apache HTTPd ≤2.4.59 (fixed in 2.4.60)[ubuntu.com](https://ubuntu.com/security/CVE-2024-39573#:~:text=Description) | **Yes** (2.4.41 < 2.4.60) | Apache 2.4.41 with SSRF fix backported (Ubuntu patchset). Version 2.4.41 is below upstream 2.4.60 fix[ubuntu.com](https://ubuntu.com/security/CVE-2024-39573#:~:text=22)[ubuntu.com](https://ubuntu.com/security/CVE-2024-39573#:~:text=Potential%20SSRF%20in%20mod_rewrite%20in,60%2C%20which%20fixes%20this%20issue). | | +| SUSE SLE 12 SP5 | apache2 | CVE-2024-39573 | 2.4.51-35.51.1 (patched build)[suse.com](https://www.suse.com/support/update/announcement/2024/suse-su-20242436-1/#:~:text=Security%20fixes%3A)[suse.com](https://www.suse.com/support/update/announcement/2024/suse-su-20242436-1/#:~:text=Package%20List%3A) | Apache HTTPd ≤2.4.59 (fixed in 2.4.60)[ubuntu.com](https://ubuntu.com/security/CVE-2024-39573#:~:text=Potential%20SSRF%20in%20mod_rewrite%20in,60%2C%20which%20fixes%20this%20issue) | **Yes** (2.4.51 < 2.4.60) | Apache 2.4.51 in SLES12 SP5 with backported fix[suse.com](https://www.suse.com/support/update/announcement/2024/suse-su-20242436-1/#:~:text=Security%20fixes%3A). Upstream considers <2.4.60 vulnerable, so 2.4.51 would normally be flagged. | | +| SUSE SLE 12 SP5 | apache2 | CVE-2024-38477 | 2.4.51-35.51.1 (same update)[suse.com](https://www.suse.com/support/update/announcement/2024/suse-su-20242436-1/#:~:text=Security%20fixes%3A) | Apache HTTPd ≤2.4.59 (fixed by 2.4.60)[ubuntu.com](https://ubuntu.com/security/CVE-2024-39573#:~:text=Potential%20SSRF%20in%20mod_rewrite%20in,60%2C%20which%20fixes%20this%20issue) | **Yes** (2.4.51 < 2.4.60) | Apache mod\_proxy null-pointer fix backported into 2.4.51[suse.com](https://www.suse.com/support/update/announcement/2024/suse-su-20242436-1/#:~:text=Security%20fixes%3A). Version appears older than upstream fix version. | | +| SUSE SLE 12 SP5 | apache2 | CVE-2024-38475 | 2.4.51-35.51.1 (same update)[suse.com](https://www.suse.com/support/update/announcement/2024/suse-su-20242436-1/#:~:text=%2A%20CVE,1227268) | Apache HTTPd ≤2.4.59 (fixed by 2.4.60)[ubuntu.com](https://ubuntu.com/security/CVE-2024-39573#:~:text=Potential%20SSRF%20in%20mod_rewrite%20in,60%2C%20which%20fixes%20this%20issue) | **Yes** (2.4.51 < 2.4.60) | Apache mod\_rewrite output-escaping issue fixed on 2.4.51 via patch[suse.com](https://www.suse.com/support/update/announcement/2024/suse-su-20242436-1/#:~:text=%2A%20CVE,1227268). Vendor version < upstream fixed version. | | +| Debian 9 “Stretch” | openssh | CVE-2018-15473 | 1:7.4p1-10+deb9u4[lists.debian.org](https://lists.debian.org/debian-security-announce/2018/msg00209.html#:~:text=For%20the%20stable%20distribution%20,10%2Bdeb9u4) | OpenSSH ≤7.7 (fixed in 7.8/7.9)[security-tracker.debian.org](https://security-tracker.debian.org/tracker/CVE-2018-15473#:~:text=CVE,an%20invalid%20authenticating%20user) | **Yes** (7.4 < 7.8) | OpenSSH 7.4p1 (Stretch) patched for user-enumeration flaw[lists.debian.org](https://lists.debian.org/debian-security-announce/2018/msg00209.html#:~:text=Dariusz%20Tytko%2C%20Michal%20Sajdak%20and,existed%20on%20the%20target%20server). Upstream required ≥7.8, so 7.4p1 normally seen as affected. | | +| Debian 10 “Buster” | sudo | CVE-2021-3156 | 1.8.27-1+deb10u3[security-tracker.debian.org](https://security-tracker.debian.org/tracker/CVE-2021-3156#:~:text=Package%20Type%20Release%20Fixed%20Version,1.1) | sudo <1.9.5p2 (fixed in 1.9.5p2)[security-tracker.debian.org](https://security-tracker.debian.org/tracker/CVE-2021-3156#:~:text=Name%20CVE,ELTS%2C%20Red%20Hat%2C%20Ubuntu%2C%20Gentoo)[security-tracker.debian.org](https://security-tracker.debian.org/tracker/CVE-2021-3156#:~:text=sudo%20%28PTS%29bullseye%201.9.5p2,1%20fixed) | **Yes** (1.8.27 < 1.9.5p2) | sudo 1.8.27 in Buster with Baron Samedit patch[security-tracker.debian.org](https://security-tracker.debian.org/tracker/CVE-2021-3156#:~:text=Package%20Type%20Release%20Fixed%20Version,1.1). Upstream says versions below 1.9.5p2 are vulnerable, so 1.8.27 would be flagged[security-tracker.debian.org](https://security-tracker.debian.org/tracker/CVE-2021-3156#:~:text=Name%20CVE,ELTS%2C%20Red%20Hat%2C%20Ubuntu%2C%20Gentoo). | | +| RHEL 7 | sudo | CVE-2019-14287 | 1.8.23-4.el7\_7.1[suse.com](https://www.suse.com/security/cve/CVE-2019-14287.html#:~:text=CVE,4.el7_7.1.%20Patchnames%3A%20RHSA) | sudo ≤1.8.27 (fixed in 1.8.28)[suse.com](https://www.suse.com/security/cve/CVE-2019-14287.html#:~:text=CVE,4.el7_7.1.%20Patchnames%3A%20RHSA)[nvd.nist.gov](https://nvd.nist.gov/vuln/detail/cve-2017-1000367#:~:text=Todd%20Miller%27s%20sudo%20version%201,function) | **Yes** (1.8.23 < 1.8.28) | sudo 1.8.23 in RHEL7 patched for Runas All bug[suse.com](https://www.suse.com/security/cve/CVE-2019-14287.html#:~:text=CVE,4.el7_7.1.%20Patchnames%3A%20RHSA). Upstream fix came later (1.8.28), so 1.8.23 is normally marked affected. | | +| Debian 8 “Jessie” | sudo | CVE-2017-1000367 | 1.8.10p3-1+deb8u4[lists.debian.org](https://lists.debian.org/debian-security-announce/2017/msg00127.html#:~:text=an%20SELinux,full%20root%20privileges) | sudo ≤1.8.20 (fixed in 1.8.21)[nvd.nist.gov](https://nvd.nist.gov/vuln/detail/cve-2017-1000367#:~:text=Todd%20Miller%27s%20sudo%20version%201,function)[security.snyk.io](https://security.snyk.io/vuln/SNYK-DEBIAN9-SUDO-406955#:~:text=Race%20Condition%20in%20sudo%20,2%20or%20higher.%20NVD%20Description) | **Yes** (1.8.10 < 1.8.21) | sudo 1.8.10p3 in Jessie got the tty hijack fix backported[lists.debian.org](https://lists.debian.org/debian-security-announce/2017/msg00127.html#:~:text=an%20SELinux,full%20root%20privileges). Upstream resolved it in a much newer sudo release, so 1.8.10p3 would appear vulnerable. | | +| Ubuntu 12.04 LTS “Precise” | bash | CVE-2014-6271 | 4.2-2ubuntu2.5[askubuntu.com](https://askubuntu.com/questions/528101/what-is-the-cve-2014-6271-bash-vulnerability-shellshock-and-how-do-i-fix-it#:~:text=dpkg%20,Version) | Bash ≤4.3 (fixed in 4.3 patch)[security-tracker.debian.org](https://security-tracker.debian.org/tracker/CVE-2014-6271#:~:text=Description%20GNU%20Bash%20through%204,present%20after%20the%20incorrect%20fix) | **Yes** (4.2 < 4.3-fixed) | Bash 4.2 on Precise patched for Shellshock[askubuntu.com](https://askubuntu.com/questions/528101/what-is-the-cve-2014-6271-bash-vulnerability-shellshock-and-how-do-i-fix-it#:~:text=dpkg%20,Version). Version 4.2 is below upstream 4.3 fix, so normally flagged as Shellshock-vulnerable. | | +| Debian 10 “Buster” (LTS) | curl | CVE-2023-27533 | 7.64.0-4+deb10u6[lists.debian.org](https://lists.debian.org/debian-lts-announce/2023/04/msg00025.html#:~:text=Package%20%20%20%20,27538)[lists.debian.org](https://lists.debian.org/debian-lts-announce/2023/04/msg00025.html#:~:text=For%20Debian%2010%20buster%2C%20these,4%2Bdeb10u6) | curl <8.0.0 (fixed in 8.0.0)[security-tracker.debian.org](https://security-tracker.debian.org/tracker/source-package/curl#:~:text=A%20path%20traversal%20vulnerability%20exists,8.0%20during) | **Yes** (7.64.0 < 8.0.0) | curl 7.64.0 with TELNET injection fix backported (Debian LTS)[lists.debian.org](https://lists.debian.org/debian-lts-announce/2023/04/msg00025.html#:~:text=Package%20%20%20%20,27538)[lists.debian.org](https://lists.debian.org/debian-lts-announce/2023/04/msg00025.html#:~:text=For%20Debian%2010%20buster%2C%20these,4%2Bdeb10u6). Upstream requires curl 8.x, so 7.64.0 is seen as affected. | | +| Debian 10 “Buster” (LTS) | curl | CVE-2023-27535 | 7.64.0-4+deb10u6[lists.debian.org](https://lists.debian.org/debian-lts-announce/2023/04/msg00025.html#:~:text=Package%20%20%20%20,27538)[lists.debian.org](https://lists.debian.org/debian-lts-announce/2023/04/msg00025.html#:~:text=CVE) | curl <8.0.0 (fixed in 8.0.0)[security-tracker.debian.org](https://security-tracker.debian.org/tracker/source-package/curl#:~:text=A%20path%20traversal%20vulnerability%20exists,8.0%20during) | **Yes** (7.64.0 < 8.0.0) | curl 7.64.0 with FTP reuse auth bypass fix backported[lists.debian.org](https://lists.debian.org/debian-lts-announce/2023/04/msg00025.html#:~:text=CVE)[lists.debian.org](https://lists.debian.org/debian-lts-announce/2023/04/msg00025.html#:~:text=For%20Debian%2010%20buster%2C%20these,4%2Bdeb10u6). Version appears vulnerable by upstream standards (<8.0). | | +| Debian 10 “Buster” (LTS) | curl | CVE-2023-27536 | 7.64.0-4+deb10u6[lists.debian.org](https://lists.debian.org/debian-lts-announce/2023/04/msg00025.html#:~:text=Package%20%20%20%20,27538)[lists.debian.org](https://lists.debian.org/debian-lts-announce/2023/04/msg00025.html#:~:text=CVE) | curl <8.0.0 (fixed in 8.0.0)[security-tracker.debian.org](https://security-tracker.debian.org/tracker/source-package/curl#:~:text=A%20path%20traversal%20vulnerability%20exists,8.0%20during) | **Yes** (7.64.0 < 8.0.0) | curl 7.64.0 with GSSAPI delegation reuse fix backported[lists.debian.org](https://lists.debian.org/debian-lts-announce/2023/04/msg00025.html#:~:text=CVE)[lists.debian.org](https://lists.debian.org/debian-lts-announce/2023/04/msg00025.html#:~:text=For%20Debian%2010%20buster%2C%20these,4%2Bdeb10u6). Upstream would mark 7.64.0 vulnerable. | | +| Debian 10 “Buster” (LTS) | curl | CVE-2023-27538 | 7.64.0-4+deb10u6[lists.debian.org](https://lists.debian.org/debian-lts-announce/2023/04/msg00025.html#:~:text=Package%20%20%20%20,27538)[lists.debian.org](https://lists.debian.org/debian-lts-announce/2023/04/msg00025.html#:~:text=CVE) | curl <8.0.0 (fixed in 8.0.0)[security-tracker.debian.org](https://security-tracker.debian.org/tracker/source-package/curl#:~:text=A%20path%20traversal%20vulnerability%20exists,8.0%20during) | **Yes** (7.64.0 < 8.0.0) | curl 7.64.0 with SSH connection reuse fix backported[lists.debian.org](https://lists.debian.org/debian-lts-announce/2023/04/msg00025.html#:~:text=CVE)[lists.debian.org](https://lists.debian.org/debian-lts-announce/2023/04/msg00025.html#:~:text=For%20Debian%2010%20buster%2C%20these,4%2Bdeb10u6). Version number <8.0 means upstream would treat it as unfixed. | | +| Fedora 34 | glibc | CVE-2021-33574 | glibc-2.33-16.fc34[lists.fedoraproject.org](https://lists.fedoraproject.org/archives/list/package-announce%40lists.fedoraproject.org/message/RBUUWUGXVILQXVWEOU7N42ICHPJNAEUP/#:~:text=%5BSECURITY%5D%20Fedora%2034%20Update%3A%20glibc,11%202021%20Arjun%20Shankar) | glibc ≤2.33 (fixed in 2.34)[suse.com](https://www.suse.com/security/cve/CVE-2015-0235.html#:~:text=Heap,GHOST) | **Yes** (2.33 < 2.34) | glibc 2.33 with `mq_notify` use-after-free fix applied (Fedora update). Upstream fix came in 2.34, so 2.33 is normally flagged as vulnerable. | | +| RHEL 8 | glibc | CVE-2024-2961 | glibc-2.28-236.el8\_9.13[openwall.com](https://www.openwall.com/lists/oss-security/2024/04/17/9#:~:text=Public,31)[openwall.com](https://www.openwall.com/lists/oss-security/2024/04/17/9#:~:text=Vulnerable,263) | glibc ≤2.39 (fixed in 2.40)[openwall.com](https://www.openwall.com/lists/oss-security/2024/04/17/9#:~:text=Public,459) | **Yes** (2.28 < 2.40) | glibc 2.28 with `iconv()` overflow fix backported (RHEL8 patch)[openwall.com](https://www.openwall.com/lists/oss-security/2024/04/17/9#:~:text=Public,459). Upstream requires 2.40+, so 2.28 is considered affected. | | +| RHEL 7 | glibc | CVE-2015-0235 | glibc-2.17-55.el7\_0.5[suse.com](https://www.suse.com/security/cve/CVE-2015-0235.html#:~:text=%2A%20%60glibc%20%3E%3D%202.17,55.el7_0.5) | glibc 2.2 up to 2.17 (fixed in 2.18)[suse.com](https://www.suse.com/security/cve/CVE-2015-0235.html#:~:text=Heap,GHOST) | **Yes** (2.17 < 2.18) | glibc 2.17 with GHOST bug patched (RHEL7 update)[suse.com](https://www.suse.com/security/cve/CVE-2015-0235.html#:~:text=Product,SUSE%20Liberty%20Linux%207). Upstream fix was in 2.18; 2.17 is normally flagged as vulnerable[suse.com](https://www.suse.com/security/cve/CVE-2015-0235.html#:~:text=Heap,GHOST). | | +| RHEL 7 | systemd | CVE-2020-1712 | systemd-219-57.el7\_8 (patch backport)[alas.aws.amazon.com](https://alas.aws.amazon.com/AL2/ALAS2-2020-1388.html#:~:text=aarch64%3A%20systemd,57.amzn2.0.12.aarch64) | systemd ≤242 (fixed in 243)[alas.aws.amazon.com](https://alas.aws.amazon.com/AL2/ALAS2-2020-1388.html#:~:text=A%20heap%20use,1712) | **Yes** (219 < 243) | systemd 219 with use-after-free fix backported (RHEL7/AL2 update)[alas.aws.amazon.com](https://alas.aws.amazon.com/AL2/ALAS2-2020-1388.html#:~:text=A%20heap%20use,1712)[alas.aws.amazon.com](https://alas.aws.amazon.com/AL2/ALAS2-2020-1388.html#:~:text=aarch64%3A%20systemd,57.amzn2.0.12.aarch64). Upstream fix is in v243, so v219 would be marked vulnerable. | | +| Alpine 3.10 | musl libc | CVE-2020-28928 | 1.1.22-r4[security.alpinelinux.org](https://security.alpinelinux.org/vuln/CVE-2020-28928#:~:text=musl%20%20%2038%201.2.2_pre2,tracker%200.9.1%20%E2%80%94%20Source%20code) | musl ≤1.2.1 (fixed in 1.2.2)[security.alpinelinux.org](https://security.alpinelinux.org/vuln/CVE-2020-28928#:~:text=CPE%20URI%20Source%20package%20Min,1.2.1) | **Yes** (1.1.x < 1.2.2) | musl 1.1.22 with `wcsnrtombs()` overflow fixed (Alpine 3.10)[security.alpinelinux.org](https://security.alpinelinux.org/vuln/CVE-2020-28928#:~:text=musl%20%20%2038%201.2.2_pre2,tracker%200.9.1%20%E2%80%94%20Source%20code). Upstream fixed in 1.2.2, so 1.1.22 would normally be considered vulnerable. | | +| Ubuntu 20.04 LTS “Focal” | openssl | CVE-2022-0778 | 1.1.1f-1ubuntu2.15 (patched)[serverfault.com](https://serverfault.com/questions/1096683/how-can-i-know-that-ubuntu-18-04-bionics-latest-openssl-is-really-1-1-1n#:~:text=,fix%20to%20their%20chosen%20version) | OpenSSL ≤1.1.1m (fixed in 1.1.1n)[serverfault.com](https://serverfault.com/questions/1096683/how-can-i-know-that-ubuntu-18-04-bionics-latest-openssl-is-really-1-1-1n#:~:text=,fix%20to%20their%20chosen%20version) | **Yes** (1.1.1f < 1.1.1n) | OpenSSL 1.1.1f with BN infinite-loop fix backported (Ubuntu)[serverfault.com](https://serverfault.com/questions/1096683/how-can-i-know-that-ubuntu-18-04-bionics-latest-openssl-is-really-1-1-1n#:~:text=,fix%20to%20their%20chosen%20version). Upstream says only 1.1.1n+ is safe, so 1.1.1f appears vulnerable to scanners. | | + +**Sources:** Vendor security advisories and trackers (Debian DSAs, Ubuntu CVE/USN pages, Red Hat errata, SUSE and Alpine trackers) are linked above to confirm patch versions and upstream fix info[lists.debian.org](https://lists.debian.org/debian-security-announce/2014/msg00071.html#:~:text=For%20the%20stable%20distribution%20,2%2Bdeb7u5)[ubuntu.com](https://ubuntu.com/security/CVE-2024-39573#:~:text=22)[suse.com](https://www.suse.com/support/update/announcement/2024/suse-su-20242436-1/#:~:text=%2A%20CVE,1227268)[openwall.com](https://www.openwall.com/lists/oss-security/2024/04/17/9#:~:text=Public,459)[security-tracker.debian.org](https://security-tracker.debian.org/tracker/CVE-2021-3156#:~:text=Package%20Type%20Release%20Fixed%20Version,1.1) etc. Each case demonstrates a backported security fix where the package version alone is misleading, helping test vulnerability scanners’ ability to detect patched-but-backported packages instead of raising false positives. + +Citations + +[ + +![](https://www.google.com/s2/favicons?domain=https://lists.debian.org&sz=32) + +\[SECURITY\] \[DSA 2896-1\] openssl security update + +https://lists.debian.org/debian-security-announce/2014/msg00071.html + +](https://lists.debian.org/debian-security-announce/2014/msg00071.html#:~:text=For%20the%20stable%20distribution%20,2%2Bdeb7u5)[ + +![](https://www.google.com/s2/favicons?domain=https://security-tracker.debian.org&sz=32) + +CVE-2014-0160 + +https://security-tracker.debian.org/tracker/CVE-2014-0160 + +](https://security-tracker.debian.org/tracker/CVE-2014-0160#:~:text=Name%20CVE,Debian%20ELTS%2C%20%208%20Red)[ + +![](https://www.google.com/s2/favicons?domain=https://security-tracker.debian.org&sz=32) + +CVE-2014-0160 + +https://security-tracker.debian.org/tracker/CVE-2014-0160 + +](https://security-tracker.debian.org/tracker/CVE-2014-0160#:~:text=Package%20Type%20Release%20Fixed%20Version,1743883)[ + +CVE-2014-0160: OpenSSL Heartbleed Vulnerability – Kaseya + +https://helpdesk.kaseya.com/hc/en-gb/articles/4407522717329-CVE-2014-0160-OpenSSL-Heartbleed-Vulnerability + +](https://helpdesk.kaseya.com/hc/en-gb/articles/4407522717329-CVE-2014-0160-OpenSSL-Heartbleed-Vulnerability#:~:text=If%20CentOS6%2C%20apply%20Unitrends%20security,42.el6)[ + +![](https://www.google.com/s2/favicons?domain=https://security-tracker.debian.org&sz=32) + +CVE-2014-0160 + +https://security-tracker.debian.org/tracker/CVE-2014-0160 + +](https://security-tracker.debian.org/tracker/CVE-2014-0160#:~:text=Description%20The%20,Debian%20ELTS%2C%20%208%20Red)[ + +![](https://www.google.com/s2/favicons?domain=https://www.suse.com&sz=32) + +CVE-2020-1971 Common Vulnerabilities and Exposures - SUSE + +https://www.suse.com/security/cve/CVE-2020-1971.html + +](https://www.suse.com/security/cve/CVE-2020-1971.html#:~:text=CVE,21.el7_9%3B%20openssl)[ + +![](https://www.google.com/s2/favicons?domain=https://linuxsecurity.com&sz=32) + +Scientific Linux 7.x SLSA-2020-5566-1 Critical OpenSSL Update + +https://linuxsecurity.com/advisories/scilinux/scilinux-slsa-2020-5566-1-important-openssl-on-sl7-x-x86-64-14-12-13 + +](https://linuxsecurity.com/advisories/scilinux/scilinux-slsa-2020-5566-1-important-openssl-on-sl7-x-x86-64-14-12-13#:~:text=Update%20linuxsecurity,21.el7_9.i686.rpm)[ + +![](https://www.google.com/s2/favicons?domain=https://openssl-library.org&sz=32) + +Release and Advisory Timeline | OpenSSL Library + +https://openssl-library.org/news/timeline/ + +](https://openssl-library.org/news/timeline/#:~:text=Release%20and%20Advisory%20Timeline%20,Truncated%20packet%20could)[ + +![](https://www.google.com/s2/favicons?domain=https://ubuntu.com&sz=32) + +CVE-2024-39573 | Ubuntu + +https://ubuntu.com/security/CVE-2024-39573 + +](https://ubuntu.com/security/CVE-2024-39573#:~:text=22)[ + +![](https://www.google.com/s2/favicons?domain=https://ubuntu.com&sz=32) + +CVE-2024-39573 | Ubuntu + +https://ubuntu.com/security/CVE-2024-39573 + +](https://ubuntu.com/security/CVE-2024-39573#:~:text=Description)[ + +![](https://www.google.com/s2/favicons?domain=https://ubuntu.com&sz=32) + +CVE-2024-39573 | Ubuntu + +https://ubuntu.com/security/CVE-2024-39573 + +](https://ubuntu.com/security/CVE-2024-39573#:~:text=Potential%20SSRF%20in%20mod_rewrite%20in,60%2C%20which%20fixes%20this%20issue)[ + +![](https://www.google.com/s2/favicons?domain=https://www.suse.com&sz=32) + +Security update for apache2 SUSE-SU-2024:2436-1 | SUSE Support | SUSE + +https://www.suse.com/support/update/announcement/2024/suse-su-20242436-1/ + +](https://www.suse.com/support/update/announcement/2024/suse-su-20242436-1/#:~:text=Security%20fixes%3A)[ + +![](https://www.google.com/s2/favicons?domain=https://www.suse.com&sz=32) + +Security update for apache2 SUSE-SU-2024:2436-1 | SUSE Support | SUSE + +https://www.suse.com/support/update/announcement/2024/suse-su-20242436-1/ + +](https://www.suse.com/support/update/announcement/2024/suse-su-20242436-1/#:~:text=Package%20List%3A)[ + +![](https://www.google.com/s2/favicons?domain=https://www.suse.com&sz=32) + +Security update for apache2 SUSE-SU-2024:2436-1 | SUSE Support | SUSE + +https://www.suse.com/support/update/announcement/2024/suse-su-20242436-1/ + +](https://www.suse.com/support/update/announcement/2024/suse-su-20242436-1/#:~:text=%2A%20CVE,1227268)[ + +![](https://www.google.com/s2/favicons?domain=https://www.suse.com&sz=32) + +Security update for apache2 SUSE-SU-2024:2436-1 | SUSE Support | SUSE + +https://www.suse.com/support/update/announcement/2024/suse-su-20242436-1/ + +](https://www.suse.com/support/update/announcement/2024/suse-su-20242436-1/#:~:text=%2A%20CVE,1227268)[ + +![](https://www.google.com/s2/favicons?domain=https://lists.debian.org&sz=32) + +\[SECURITY\] \[DSA 4280-1\] openssh security update + +https://lists.debian.org/debian-security-announce/2018/msg00209.html + +](https://lists.debian.org/debian-security-announce/2018/msg00209.html#:~:text=For%20the%20stable%20distribution%20,10%2Bdeb9u4)[ + +![](https://www.google.com/s2/favicons?domain=https://security-tracker.debian.org&sz=32) + +CVE-2018-15473 - Security Bug Tracker - Debian + +https://security-tracker.debian.org/tracker/CVE-2018-15473 + +](https://security-tracker.debian.org/tracker/CVE-2018-15473#:~:text=CVE,an%20invalid%20authenticating%20user)[ + +![](https://www.google.com/s2/favicons?domain=https://lists.debian.org&sz=32) + +\[SECURITY\] \[DSA 4280-1\] openssh security update + +https://lists.debian.org/debian-security-announce/2018/msg00209.html + +](https://lists.debian.org/debian-security-announce/2018/msg00209.html#:~:text=Dariusz%20Tytko%2C%20Michal%20Sajdak%20and,existed%20on%20the%20target%20server)[ + +![](https://www.google.com/s2/favicons?domain=https://security-tracker.debian.org&sz=32) + +CVE-2021-3156 + +https://security-tracker.debian.org/tracker/CVE-2021-3156 + +](https://security-tracker.debian.org/tracker/CVE-2021-3156#:~:text=Package%20Type%20Release%20Fixed%20Version,1.1)[ + +![](https://www.google.com/s2/favicons?domain=https://security-tracker.debian.org&sz=32) + +CVE-2021-3156 + +https://security-tracker.debian.org/tracker/CVE-2021-3156 + +](https://security-tracker.debian.org/tracker/CVE-2021-3156#:~:text=Name%20CVE,ELTS%2C%20Red%20Hat%2C%20Ubuntu%2C%20Gentoo)[ + +![](https://www.google.com/s2/favicons?domain=https://security-tracker.debian.org&sz=32) + +CVE-2021-3156 + +https://security-tracker.debian.org/tracker/CVE-2021-3156 + +](https://security-tracker.debian.org/tracker/CVE-2021-3156#:~:text=sudo%20%28PTS%29bullseye%201.9.5p2,1%20fixed)[ + +![](https://www.google.com/s2/favicons?domain=https://www.suse.com&sz=32) + +CVE-2019-14287 Common Vulnerabilities and Exposures - SUSE + +https://www.suse.com/security/cve/CVE-2019-14287.html + +](https://www.suse.com/security/cve/CVE-2019-14287.html#:~:text=CVE,4.el7_7.1.%20Patchnames%3A%20RHSA)[ + +![](https://www.google.com/s2/favicons?domain=https://nvd.nist.gov&sz=32) + +CVE-2017-1000367 Detail - NVD + +https://nvd.nist.gov/vuln/detail/cve-2017-1000367 + +](https://nvd.nist.gov/vuln/detail/cve-2017-1000367#:~:text=Todd%20Miller%27s%20sudo%20version%201,function)[ + +![](https://www.google.com/s2/favicons?domain=https://lists.debian.org&sz=32) + +\[SECURITY\] \[DSA 3867-1\] sudo security update + +https://lists.debian.org/debian-security-announce/2017/msg00127.html + +](https://lists.debian.org/debian-security-announce/2017/msg00127.html#:~:text=an%20SELinux,full%20root%20privileges)[ + +![](https://www.google.com/s2/favicons?domain=https://security.snyk.io&sz=32) + +Race Condition in sudo | CVE-2017-1000367 | Snyk + +https://security.snyk.io/vuln/SNYK-DEBIAN9-SUDO-406955 + +](https://security.snyk.io/vuln/SNYK-DEBIAN9-SUDO-406955#:~:text=Race%20Condition%20in%20sudo%20,2%20or%20higher.%20NVD%20Description)[ + +![](https://www.google.com/s2/favicons?domain=https://askubuntu.com&sz=32) + +security - What is the CVE-2014-6271 bash vulnerability (Shellshock) and how do I fix it? - Ask Ubuntu + +https://askubuntu.com/questions/528101/what-is-the-cve-2014-6271-bash-vulnerability-shellshock-and-how-do-i-fix-it + +](https://askubuntu.com/questions/528101/what-is-the-cve-2014-6271-bash-vulnerability-shellshock-and-how-do-i-fix-it#:~:text=dpkg%20,Version)[ + +![](https://www.google.com/s2/favicons?domain=https://security-tracker.debian.org&sz=32) + +CVE-2014-6271 + +https://security-tracker.debian.org/tracker/CVE-2014-6271 + +](https://security-tracker.debian.org/tracker/CVE-2014-6271#:~:text=Description%20GNU%20Bash%20through%204,present%20after%20the%20incorrect%20fix)[ + +![](https://www.google.com/s2/favicons?domain=https://lists.debian.org&sz=32) + +\[SECURITY\] \[DLA 3398-1\] curl security update + +https://lists.debian.org/debian-lts-announce/2023/04/msg00025.html + +](https://lists.debian.org/debian-lts-announce/2023/04/msg00025.html#:~:text=Package%20%20%20%20,27538)[ + +![](https://www.google.com/s2/favicons?domain=https://lists.debian.org&sz=32) + +\[SECURITY\] \[DLA 3398-1\] curl security update + +https://lists.debian.org/debian-lts-announce/2023/04/msg00025.html + +](https://lists.debian.org/debian-lts-announce/2023/04/msg00025.html#:~:text=For%20Debian%2010%20buster%2C%20these,4%2Bdeb10u6)[ + +![](https://www.google.com/s2/favicons?domain=https://security-tracker.debian.org&sz=32) + +Information on source package curl - Security Bug Tracker - Debian + +https://security-tracker.debian.org/tracker/source-package/curl + +](https://security-tracker.debian.org/tracker/source-package/curl#:~:text=A%20path%20traversal%20vulnerability%20exists,8.0%20during)[ + +![](https://www.google.com/s2/favicons?domain=https://lists.debian.org&sz=32) + +\[SECURITY\] \[DLA 3398-1\] curl security update + +https://lists.debian.org/debian-lts-announce/2023/04/msg00025.html + +](https://lists.debian.org/debian-lts-announce/2023/04/msg00025.html#:~:text=CVE)[ + +![](https://www.google.com/s2/favicons?domain=https://lists.debian.org&sz=32) + +\[SECURITY\] \[DLA 3398-1\] curl security update + +https://lists.debian.org/debian-lts-announce/2023/04/msg00025.html + +](https://lists.debian.org/debian-lts-announce/2023/04/msg00025.html#:~:text=CVE)[ + +![](https://www.google.com/s2/favicons?domain=https://lists.debian.org&sz=32) + +\[SECURITY\] \[DLA 3398-1\] curl security update + +https://lists.debian.org/debian-lts-announce/2023/04/msg00025.html + +](https://lists.debian.org/debian-lts-announce/2023/04/msg00025.html#:~:text=CVE)[ + +![](https://www.google.com/s2/favicons?domain=https://lists.fedoraproject.org&sz=32) + +\[SECURITY\] Fedora 34 Update: glibc-2.33-16.fc34 + +https://lists.fedoraproject.org/archives/list/package-announce%40lists.fedoraproject.org/message/RBUUWUGXVILQXVWEOU7N42ICHPJNAEUP/ + +](https://lists.fedoraproject.org/archives/list/package-announce%40lists.fedoraproject.org/message/RBUUWUGXVILQXVWEOU7N42ICHPJNAEUP/#:~:text=%5BSECURITY%5D%20Fedora%2034%20Update%3A%20glibc,11%202021%20Arjun%20Shankar)[ + +![](https://www.google.com/s2/favicons?domain=https://www.suse.com&sz=32) + +CVE-2015-0235 Common Vulnerabilities and Exposures | SUSE + +https://www.suse.com/security/cve/CVE-2015-0235.html + +](https://www.suse.com/security/cve/CVE-2015-0235.html#:~:text=Heap,GHOST)[ + +![](https://www.google.com/s2/favicons?domain=https://www.openwall.com&sz=32) + +oss-security - The GNU C Library security advisories update for 2024-04-17: GLIBC-SA-2024-0004/CVE-2024-2961: ISO-2022-CN-EXT: fix out-of-bound writes when writing escape sequence + +https://www.openwall.com/lists/oss-security/2024/04/17/9 + +](https://www.openwall.com/lists/oss-security/2024/04/17/9#:~:text=Public,31)[ + +![](https://www.google.com/s2/favicons?domain=https://www.openwall.com&sz=32) + +oss-security - The GNU C Library security advisories update for 2024-04-17: GLIBC-SA-2024-0004/CVE-2024-2961: ISO-2022-CN-EXT: fix out-of-bound writes when writing escape sequence + +https://www.openwall.com/lists/oss-security/2024/04/17/9 + +](https://www.openwall.com/lists/oss-security/2024/04/17/9#:~:text=Vulnerable,263)[ + +![](https://www.google.com/s2/favicons?domain=https://www.openwall.com&sz=32) + +oss-security - The GNU C Library security advisories update for 2024-04-17: GLIBC-SA-2024-0004/CVE-2024-2961: ISO-2022-CN-EXT: fix out-of-bound writes when writing escape sequence + +https://www.openwall.com/lists/oss-security/2024/04/17/9 + +](https://www.openwall.com/lists/oss-security/2024/04/17/9#:~:text=Public,459)[ + +![](https://www.google.com/s2/favicons?domain=https://www.suse.com&sz=32) + +CVE-2015-0235 Common Vulnerabilities and Exposures | SUSE + +https://www.suse.com/security/cve/CVE-2015-0235.html + +](https://www.suse.com/security/cve/CVE-2015-0235.html#:~:text=%2A%20%60glibc%20%3E%3D%202.17,55.el7_0.5)[ + +![](https://www.google.com/s2/favicons?domain=https://www.suse.com&sz=32) + +CVE-2015-0235 Common Vulnerabilities and Exposures | SUSE + +https://www.suse.com/security/cve/CVE-2015-0235.html + +](https://www.suse.com/security/cve/CVE-2015-0235.html#:~:text=Product,SUSE%20Liberty%20Linux%207)[ + +ALAS2-2020-1388 + +https://alas.aws.amazon.com/AL2/ALAS2-2020-1388.html + +](https://alas.aws.amazon.com/AL2/ALAS2-2020-1388.html#:~:text=aarch64%3A%20systemd,57.amzn2.0.12.aarch64)[ + +ALAS2-2020-1388 + +https://alas.aws.amazon.com/AL2/ALAS2-2020-1388.html + +](https://alas.aws.amazon.com/AL2/ALAS2-2020-1388.html#:~:text=A%20heap%20use,1712)[ + +CVE-2020-28928 — Alpine Security Tracker + +https://security.alpinelinux.org/vuln/CVE-2020-28928 + +](https://security.alpinelinux.org/vuln/CVE-2020-28928#:~:text=musl%20%20%2038%201.2.2_pre2,tracker%200.9.1%20%E2%80%94%20Source%20code)[ + +CVE-2020-28928 — Alpine Security Tracker + +https://security.alpinelinux.org/vuln/CVE-2020-28928 + +](https://security.alpinelinux.org/vuln/CVE-2020-28928#:~:text=CPE%20URI%20Source%20package%20Min,1.2.1)[ + +![](https://www.google.com/s2/favicons?domain=https://serverfault.com&sz=32) + +How can I know that Ubuntu 18.04 Bionic's latest OpenSSL is really ... + +https://serverfault.com/questions/1096683/how-can-i-know-that-ubuntu-18-04-bionics-latest-openssl-is-really-1-1-1n + +](https://serverfault.com/questions/1096683/how-can-i-know-that-ubuntu-18-04-bionics-latest-openssl-is-really-1-1-1n#:~:text=,fix%20to%20their%20chosen%20version) + +All Sources + +[ + +![](https://www.google.com/s2/favicons?domain=https://lists.debian.org&sz=32) + +lists.debian + +](https://lists.debian.org/debian-security-announce/2014/msg00071.html#:~:text=For%20the%20stable%20distribution%20,2%2Bdeb7u5)[ + +![](https://www.google.com/s2/favicons?domain=https://security-tracker.debian.org&sz=32) + +security...er.debian + +](https://security-tracker.debian.org/tracker/CVE-2014-0160#:~:text=Name%20CVE,Debian%20ELTS%2C%20%208%20Red)[ + +helpdesk.kaseya + +](https://helpdesk.kaseya.com/hc/en-gb/articles/4407522717329-CVE-2014-0160-OpenSSL-Heartbleed-Vulnerability#:~:text=If%20CentOS6%2C%20apply%20Unitrends%20security,42.el6)[ + +![](https://www.google.com/s2/favicons?domain=https://www.suse.com&sz=32) + +suse + +](https://www.suse.com/security/cve/CVE-2020-1971.html#:~:text=CVE,21.el7_9%3B%20openssl)[ + +![](https://www.google.com/s2/favicons?domain=https://linuxsecurity.com&sz=32) + +linuxsecurity + +](https://linuxsecurity.com/advisories/scilinux/scilinux-slsa-2020-5566-1-important-openssl-on-sl7-x-x86-64-14-12-13#:~:text=Update%20linuxsecurity,21.el7_9.i686.rpm)[ + +![](https://www.google.com/s2/favicons?domain=https://openssl-library.org&sz=32) + +openssl-library + +](https://openssl-library.org/news/timeline/#:~:text=Release%20and%20Advisory%20Timeline%20,Truncated%20packet%20could)[ + +![](https://www.google.com/s2/favicons?domain=https://ubuntu.com&sz=32) + +ubuntu + +](https://ubuntu.com/security/CVE-2024-39573#:~:text=22)[ + +![](https://www.google.com/s2/favicons?domain=https://nvd.nist.gov&sz=32) + +nvd.nist + +](https://nvd.nist.gov/vuln/detail/cve-2017-1000367#:~:text=Todd%20Miller%27s%20sudo%20version%201,function)[ + +![](https://www.google.com/s2/favicons?domain=https://security.snyk.io&sz=32) + +security.snyk + +](https://security.snyk.io/vuln/SNYK-DEBIAN9-SUDO-406955#:~:text=Race%20Condition%20in%20sudo%20,2%20or%20higher.%20NVD%20Description)[ + +![](https://www.google.com/s2/favicons?domain=https://askubuntu.com&sz=32) + +askubuntu + +](https://askubuntu.com/questions/528101/what-is-the-cve-2014-6271-bash-vulnerability-shellshock-and-how-do-i-fix-it#:~:text=dpkg%20,Version)[ + +![](https://www.google.com/s2/favicons?domain=https://lists.fedoraproject.org&sz=32) + +lists.fedoraproject + +](https://lists.fedoraproject.org/archives/list/package-announce%40lists.fedoraproject.org/message/RBUUWUGXVILQXVWEOU7N42ICHPJNAEUP/#:~:text=%5BSECURITY%5D%20Fedora%2034%20Update%3A%20glibc,11%202021%20Arjun%20Shankar)[ + +![](https://www.google.com/s2/favicons?domain=https://www.openwall.com&sz=32) + +openwall + +](https://www.openwall.com/lists/oss-security/2024/04/17/9#:~:text=Public,31)[ + +alas.aws.amazon + +](https://alas.aws.amazon.com/AL2/ALAS2-2020-1388.html#:~:text=aarch64%3A%20systemd,57.amzn2.0.12.aarch64)[ + +security.alpinelinux + +](https://security.alpinelinux.org/vuln/CVE-2020-28928#:~:text=musl%20%20%2038%201.2.2_pre2,tracker%200.9.1%20%E2%80%94%20Source%20code)[ + +![](https://www.google.com/s2/favicons?domain=https://serverfault.com&sz=32) + +serverfault + +](https://serverfault.com/questions/1096683/how-can-i-know-that-ubuntu-18-04-bionics-latest-openssl-is-really-1-1-1n#:~:text=,fix%20to%20their%20chosen%20version) \ No newline at end of file diff --git a/docs/product-advisories/30-Dec-2025 - Designing a Deterministic VEX Resolver.md b/docs/product-advisories/30-Dec-2025 - Designing a Deterministic VEX Resolver.md new file mode 100644 index 000000000..616fabb89 --- /dev/null +++ b/docs/product-advisories/30-Dec-2025 - Designing a Deterministic VEX Resolver.md @@ -0,0 +1,160 @@ +## Product Advisory: Deterministic VEX-first vulnerability verdicts with CycloneDX 1.7 + +### 1) The problem you are solving + +Modern scanners produce a long list of “components with known CVEs,” but that list is routinely misleading because it ignores *context*: whether the vulnerable code is shipped, configured, reachable, mitigated, or already fixed via backport. Teams then waste time on false positives, duplicate findings, and non-actionable noise. + +A **VEX-first** approach solves this by attaching *exploitability/impact assertions* to SBOM components. In CycloneDX, this is expressed via the **Vulnerability / Analysis** model (often used as VEX), which can declare that a component is **not affected**, **under investigation/in triage**, **exploitable/affected**, or **resolved/fixed**, along with rationale/justification and other details. CycloneDX explicitly frames this as “vulnerability exploitability” context, including a `state` and a `justification` for why a vulnerability is (or isn’t) a practical risk. ([cyclonedx.org][1]) + +The core product challenge is therefore: + +* You will ingest **multiple statements** (vendors, distros, internal security, runtime evidence) that may **conflict**. +* Those statements may be **conditional** (only affected on certain OS, feature flags, build options). +* You must produce a **single stable, explainable verdict** per (product, vuln), and do so **deterministically** so audits and diffs are reproducible. + +--- + +### 2) Product intent and outcomes + +**Primary outcome:** Reduce noise while increasing trust: every suppression or escalation is backed by evidence and explainable logic. + +**What “good” looks like:** + +* Fewer alerts, but higher signal. +* Each vuln has a clear **final verdict** plus **reason chain** (“why this was marked not_affected/fixed/affected”). +* Deterministic replay: the same inputs produce the same outputs. + +--- + +### 3) Recommended data contract (CycloneDX 1.7 aligned) + +Use CycloneDX 1.7 as the canonical interchange for impact/exploitability assertions: + +* **SBOM**: components + dependencies (CycloneDX and/or SPDX) +* **Vulnerability entries** with **analysis** fields: + + * `analysis.state` (status in context) and `analysis.justification` (why), as described in CycloneDX’s exploitability use case. ([cyclonedx.org][1]) +* Optional ingress from **OpenVEX** or CSAF; normalize into CycloneDX analysis semantics (OpenVEX defines the commonly used status set `not_affected / affected / fixed / under_investigation`, and requires justification in `not_affected` cases). ([GitHub][2]) + +Graph relationships (if you use SPDX 3.0.1 as your internal graph layer): + +* Model dependencies and containment via SPDX `Relationship` and `RelationshipType`, which formalize “Element A RELATIONSHIP Element B” semantics used to compute transitive impact. ([SPDX][3]) + +--- + +### 4) Product behavior guidelines + +#### A. Single “Risk Verdict” per vuln, backed by evidence + +Expose one final verdict per vulnerability at the product level, with an expandable “proof” pane: + +* Inputs considered (SBOM nodes, relationship paths, VEX statements, conditions). +* Merge logic explanation (how conflicts were resolved). +* Timestamped lineage: which feed/source asserted what. + +#### B. Quiet-by-design UX + +* Default views show only items needing action: **Affected/Exploitable**, and **Under Investigation** with age/timeouts. +* “Not affected” and “Fixed/Resolved” are accessible but not front-and-center; they primarily serve audit and trust. + +#### C. Diff-aware notifications + +Notify only on **meaningful transitions** (e.g., Unknown→Affected, Affected→Fixed), not on every feed refresh. + +--- + +### 5) Development guidelines (deterministic resolver) + +#### A. Normalize identifiers first + +Create a strict canonical key for matching “the same component” across SBOMs and VEX: + +1. prefer **purl**, then **CPE**, then (name, version, supplier). +2. persist alias mappings (vendor naming variance is normal). + +#### B. Represent the world as two layers + +1. **Graph layer** (what is shipped/depends-on/contains what) +2. **Assertion layer** (CycloneDX 1.7 vulnerability analysis statements, plus optional runtime/reachability evidence) + +Do not mix them—keep assertions as immutable facts that the resolver evaluates. + +#### C. Condition evaluation must be total and deterministic + +For each assertion, evaluate conditions against a frozen `Context`: + +* platform (OS/distro/arch), build flags, enabled features, packaging mode +* runtime signals (if used) must be versioned and hashed like any other input + +If a condition cannot be evaluated, treat it explicitly as **Unknown**, not false. + +#### D. Merge conflicts via a documented lattice + +Define a monotonic merge function that is: + +* **commutative** (order independent), +* **idempotent** (reapplying doesn’t change), +* **associative** (supports streaming/parallel merges). + +A pragmatic priority (adjust to your policy): + +1. **Fixed/Resolved** (with evidence of fix scope) +2. **Not affected** (with valid justification and conditions satisfied) +3. **Affected/Exploitable** +4. **Under investigation / In triage** +5. **Unknown** + +CycloneDX’s exploitability model explicitly supports “state + justification” to make “not affected” meaningful, not a hand-wave. ([cyclonedx.org][1]) + +#### E. Propagation rules must be explicit + +Decide and document how assertions propagate across the dependency graph: + +* When a dependency is **Affected**, does the product become Affected automatically? (Typically yes if the dependency is shipped and used, unless a product-level assertion says otherwise.) +* When a dependency is **Not affected** due to “code removed before shipping,” does the product inherit Not affected? (Often yes, but only if you can prove the affected code path is absent for the shipped artifact.) +* Keep propagation rules versioned to avoid “policy drift” breaking deterministic replay. + +#### F. Always emit a proof object + +For every final verdict emit: + +* contributing assertions (source IDs), condition evaluations, merge steps +* the graph path(s) that made it relevant (SPDX Relationship chain or CycloneDX dependency references) + This proof is what lets you be quiet-by-design without losing auditability. + +--- + +### 6) Interop guidance (OpenVEX / CSAF → CycloneDX 1.7) + +If you ingest OpenVEX: + +* Map OpenVEX status to CycloneDX analysis state (policy-defined mapping). +* Enforce OpenVEX minimums: `not_affected` should have a justification/impact statement. ([GitHub][2]) + +If you ingest CSAF advisories: + +* Treat them as another assertion source; do not let them overwrite higher-confidence internal evidence without explicit precedence rules. + +--- + +### 7) Testing and rollout checklist + +* **Golden test vectors**: fixed input bundles (SBOM + assertions + context) with expected verdicts. +* **Determinism tests**: shuffle assertion ordering; results must be identical. +* **Regression diffs**: store prior proofs; verify only intended transitions occur after feed updates. +* **Adversarial cases**: conflicting assertions, partial conditions, alias mismatches, missing dependency edges. + +--- + +### 8) Common failure modes to avoid + +* Treating “not affected” as a suppression without requiring justification. +* Allowing “latest feed wins” behavior (non-deterministic and unauditable). +* Mixing runtime telemetry directly into SBOM identity (breaks replay). +* Implicit propagation rules (different engineers will interpret differently; results drift). + +If you want, I can also provide a short, implementation-ready “resolver contract” (types, verdict lattice, proof schema) that is CycloneDX 1.7-centric while remaining neutral to whether you store the graph as CycloneDX dependencies or SPDX 3.0.1 relationships. + +[1]: https://cyclonedx.org/use-cases/vulnerability-exploitability/?utm_source=chatgpt.com "Security Use Case: Vulnerability Exploitability" +[2]: https://github.com/openvex/spec/blob/main/OPENVEX-SPEC.md?utm_source=chatgpt.com "spec/OPENVEX-SPEC.md at main" +[3]: https://spdx.github.io/spdx-spec/v3.0.1/model/Core/Classes/Relationship/?utm_source=chatgpt.com "Relationship - SPDX Specification 3.0.1" diff --git a/docs/product-advisories/30-Dec-2025 - Evidence‑Gated AI Explanations.md b/docs/product-advisories/30-Dec-2025 - Evidence‑Gated AI Explanations.md new file mode 100644 index 000000000..bc3c70faf --- /dev/null +++ b/docs/product-advisories/30-Dec-2025 - Evidence‑Gated AI Explanations.md @@ -0,0 +1,115 @@ +Here’s a simple, high‑signal pattern you can drop into your security product: **gate AI remediation/explanations behind an “Evidence Coverage” badge**—and hide suggestions when coverage is weak. + +--- + +### What this solves (plain English) + +AI advice is only trustworthy when it’s grounded in real evidence. If your scan only sees half the picture, AI “fixes” become noise. A visible coverage badge makes this explicit and keeps the UI quiet until you’ve got enough facts. + +--- + +### What “Evidence Coverage” means + +Score = % of the verdict’s required facts present, e.g., do we have: + +* **Reachability** (is the vulnerable code/path actually callable in this artifact/runtime?) +* **VEX** (vendor/product statements: affected/not‑affected/under‑investigation) +* **Runtime** (telemetry, process trees, loaded libs, eBPF hooks) +* **Exploit signals** (known exploits, KEV, EPSS tier, in‑the‑wild intel) +* **Patch/backport proof** (distro backports, symbols, diff/Build‑ID match) +* **Provenance** (in‑toto/DSSE attestations, signer trust) +* **Environment match** (kernel/os/distro/package set parity) +* **Differential context** (did this change since last release?) + +Each fact bucket contributes weighted points → a 0–100% **Coverage** score. + +--- + +### UX rule of thumb + +* **<60%**: Hide AI suggestions by default. Show a muted badge “Coverage 41% — add sources to unlock guidance.” +* **60–79%**: Collapse AI panel; allow manual expand with a caution label. Every sentence shows its **citations**. +* **≥80%**: Show AI remediation by default with a green badge and inline evidence chips. +* **100%**: Add a subtle “High confidence” ribbon + “export proof” link. + +--- + +### Minimal UI components + +* A small badge next to each finding: `Coverage 82%` (click → drawer). +* Drawer tabs: **Sources**, **Why we think it’s reachable**, **Counter‑evidence**, **Gaps**. +* “Fill the gaps” call‑outs (e.g., “Attach VEX”, “Enable runtime sensor”, “Upload SBOM”). + +--- + +### Copy you can reuse + +* Collapsed state (low coverage): + *“We’re missing runtime or VEX evidence. Add one source to unlock tailored remediation.”* +* Expanded (medium): + *“Guidance shown with caution. 3/5 evidence buckets present. See gaps →”* + +--- + +### Data model (lean) + +```yaml +coverage: + score: 0-100 + buckets: + - id: reachability # call graph, symbol, entrypoints + present: true + weight: 0.22 + evidence_refs: [e1,e7] + - id: vex # product/vendor statements + present: false + weight: 0.18 + evidence_refs: [] + - id: runtime + present: true + weight: 0.20 + evidence_refs: [e3] + - id: exploit_signals + present: true + weight: 0.15 + evidence_refs: [e6] + - id: patch_backport + present: false + weight: 0.15 + evidence_refs: [] + - id: provenance + present: true + weight: 0.10 + evidence_refs: [e9] +``` + +--- + +### Policy in one line (ship this as a guard) + +```pseudo +if coverage.score < 60: hide_ai() +elif coverage.score < 80: show_ai(collapsed=true, label="limited evidence") +else: show_ai(collapsed=false, label="evidence-backed") +``` + +--- + +### What the AI must output (when shown) + +* **Step‑by‑step remediation** with **per‑step citations** to the evidence drawer. +* **Why this is safe** (mentions backports, ABI risk, service impact). +* **Counterfactual**: “If VEX says Not Affected → do X instead.” +* **Residual risk** and **rollback** plan. + +--- + +### How to reach ≥80% more often + +* Auto‑request missing inputs (“Upload maintainer VEX” / “Turn on runtime for 24h”). +* Fetch distro backport diffs and symbol maps to close the patch/backport bucket. +* Merge SBOM + call‑graph + eBPF to strengthen reachability. + +--- + +If you want, I can draft a drop‑in React component (Badge + Drawer) and a tiny scoring service (C#/.NET 10) that plugs into your verdict pipeline. diff --git a/docs/product-advisories/ADVISORY_20251229_SBOM_LINEAGE_AND_TESTING.md b/docs/product-advisories/archived/ADVISORY_20251229_SBOM_LINEAGE_AND_TESTING.md similarity index 100% rename from docs/product-advisories/ADVISORY_20251229_SBOM_LINEAGE_AND_TESTING.md rename to docs/product-advisories/archived/ADVISORY_20251229_SBOM_LINEAGE_AND_TESTING.md diff --git a/src/Cli/StellaOps.Cli.sln b/src/Cli/StellaOps.Cli.sln index 5a24a3061..be51ead1c 100644 --- a/src/Cli/StellaOps.Cli.sln +++ b/src/Cli/StellaOps.Cli.sln @@ -1,1163 +1,2326 @@ -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 17 -VisualStudioVersion = 17.0.31903.59 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Cli", "StellaOps.Cli", "{000B0CE4-1FA5-04BB-64A0-CF75B545CE86}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "__External", "__External", "{5B52EF8A-3661-DCFF-797D-BC4D6AC60BDA}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "AirGap", "AirGap", "{F310596E-88BB-9E54-885E-21C61971917E}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.AirGap.Importer", "StellaOps.AirGap.Importer", "{EA6E5683-3A20-2E52-1CE6-AE0D6D36AC4D}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.AirGap.Policy", "StellaOps.AirGap.Policy", "{D9492ED1-A812-924B-65E4-F518592B49BB}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.AirGap.Policy", "StellaOps.AirGap.Policy", "{3823DE1E-2ACE-C956-99E1-00DB786D9E1D}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Aoc", "Aoc", "{03DFF14F-7321-1784-D4C7-4E99D4120F48}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "__Libraries", "__Libraries", "{BDD326D6-7616-84F0-B914-74743BFBA520}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Aoc", "StellaOps.Aoc", "{EC506DBE-AB6D-492E-786E-8B176021BF2E}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Attestor", "Attestor", "{5AC09D9A-F2A5-9CFA-B3C5-8D25F257651C}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Attestation", "StellaOps.Attestation", "{0B71A5C2-A1C9-BB93-6042-23D1CEE5AD68}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Attestor", "StellaOps.Attestor", "{33B1AE27-692A-1778-48C1-CCEC2B9BC78F}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Attestor.Envelope", "StellaOps.Attestor.Envelope", "{018E0E11-1CCE-A2BE-641D-21EE14D2E90D}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Attestor.Core", "StellaOps.Attestor.Core", "{5F27FB4E-CF09-3A6B-F5B4-BF5A709FA609}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "__Libraries", "__Libraries", "{AB67BDB9-D701-3AC9-9CDF-ECCDCCD8DB6D}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Attestor.GraphRoot", "StellaOps.Attestor.GraphRoot", "{3F605548-87E2-8A1D-306D-0CE6960B8242}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Attestor.ProofChain", "StellaOps.Attestor.ProofChain", "{45F7FA87-7451-6970-7F6E-F8BAE45E081B}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Authority", "Authority", "{C1DCEFBD-12A5-EAAE-632E-8EEB9BE491B6}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Authority", "StellaOps.Authority", "{A6928CBA-4D4D-AB2B-CA19-FEE6E73ECE70}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Auth.Abstractions", "StellaOps.Auth.Abstractions", "{F2E6CB0E-DF77-1FAA-582B-62B040DF3848}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Auth.Client", "StellaOps.Auth.Client", "{C494ECBE-DEA5-3576-D2AF-200FF12BC144}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Authority.Plugins.Abstractions", "StellaOps.Authority.Plugins.Abstractions", "{64689413-46D7-8499-68A6-B6367ACBC597}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "__Libraries", "__Libraries", "{5827F4DE-0AA7-FC85-641D-09E3D890DB27}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Authority.Core", "StellaOps.Authority.Core", "{9BD75659-58CB-06D1-E198-C39007E82C6A}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Authority.Persistence", "StellaOps.Authority.Persistence", "{7BF13935-F1DD-D23B-8347-DB1550C69D69}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Concelier", "Concelier", "{157C3671-CA0B-69FA-A7C9-74A1FDA97B99}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "__Libraries", "__Libraries", "{F39E09D6-BF93-B64A-CFE7-2BA92815C0FE}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Concelier.Cache.Valkey", "StellaOps.Concelier.Cache.Valkey", "{39EFDA5B-F5EE-8212-D5BA-90E1B82013E7}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Concelier.Core", "StellaOps.Concelier.Core", "{6844B539-C2A3-9D4F-139D-9D533BCABADA}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Concelier.Interest", "StellaOps.Concelier.Interest", "{4263AA71-0335-3F44-9A9B-423C3A3D05E6}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Concelier.Merge", "StellaOps.Concelier.Merge", "{F1B1DB47-D2D7-59CB-679B-23E4928E8328}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Concelier.Models", "StellaOps.Concelier.Models", "{BC35DE94-4F04-3436-27A3-F11647FEDD5C}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Concelier.Normalization", "StellaOps.Concelier.Normalization", "{864C8B80-771A-0C15-30A5-558F99006E0D}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Concelier.Persistence", "StellaOps.Concelier.Persistence", "{603E7A23-1D6B-D3A9-B0E6-3E332B13ED5C}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Concelier.ProofService", "StellaOps.Concelier.ProofService", "{D2F7E58B-47D4-5205-D917-144CA1CFF4F1}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Concelier.RawModels", "StellaOps.Concelier.RawModels", "{1DCF4EBB-DBC4-752C-13D4-D1EECE4E8907}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Concelier.SbomIntegration", "StellaOps.Concelier.SbomIntegration", "{1B37A859-E733-60CB-4806-1A24B6F10E05}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Concelier.SourceIntel", "StellaOps.Concelier.SourceIntel", "{F2B58F4E-6F28-A25F-5BFB-CDEBAD6B9A3E}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Excititor", "Excititor", "{7D49FA52-6EA1-EAC8-4C5A-AC07188D6C57}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "__Libraries", "__Libraries", "{C9CF27FC-12DB-954F-863C-576BA8E309A5}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Excititor.Core", "StellaOps.Excititor.Core", "{6DCAF6F3-717F-27A9-D96C-F2BFA5550347}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Excititor.Persistence", "StellaOps.Excititor.Persistence", "{83791804-2407-CC2B-34AD-ED8FFAAF3257}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ExportCenter", "ExportCenter", "{8E933B6D-39AB-871C-33D6-E57984AA38BA}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.ExportCenter", "StellaOps.ExportCenter", "{84C61393-D449-22D3-FA3B-75F7256384E9}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.ExportCenter.Client", "StellaOps.ExportCenter.Client", "{48007FB6-A895-4ED1-E1AE-E0806BCFFF96}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.ExportCenter.Core", "StellaOps.ExportCenter.Core", "{09DD25DA-BBB0-5D9D-A372-751855D00AF0}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Feedser", "Feedser", "{C4A90603-BE42-0044-CAB4-3EB910AD51A5}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Feedser.BinaryAnalysis", "StellaOps.Feedser.BinaryAnalysis", "{054761F9-16D3-B2F8-6F4D-EFC2248805CD}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Feedser.Core", "StellaOps.Feedser.Core", "{B54CE64C-4167-1DD1-B7D6-2FD7A5AEF715}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Notify", "Notify", "{D2162FEA-AFA4-2A88-6444-2F6D845260BB}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "__Libraries", "__Libraries", "{63EAEA3B-ADC9-631D-774E-7AA04490EDDD}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Notify.Models", "StellaOps.Notify.Models", "{B0F64757-F7A7-1A11-8DEC-BAC72EB5EC29}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Notify.Persistence", "StellaOps.Notify.Persistence", "{C5F86BAD-155A-591C-9610-55D40F59C775}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Policy", "Policy", "{8E6B774C-CC4E-CE7C-AD4B-8AF7C92889A6}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Policy.RiskProfile", "StellaOps.Policy.RiskProfile", "{BC12ED55-6015-7C8B-8384-B39CE93C76D6}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Policy.Scoring", "StellaOps.Policy.Scoring", "{7DE09F4B-E86D-CEA4-EC36-364CC9CCD2A6}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.PolicyDsl", "StellaOps.PolicyDsl", "{BA20548F-5ADA-BE63-1AE7-BA12CB4E82B3}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "__Libraries", "__Libraries", "{FF70543D-AFF9-1D38-4950-4F8EE18D60BB}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Policy", "StellaOps.Policy", "{831265B0-8896-9C95-3488-E12FD9F6DC53}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Policy.Exceptions", "StellaOps.Policy.Exceptions", "{97579A99-E7BE-9189-9B9A-CA0EBB5E9C97}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Policy.Persistence", "StellaOps.Policy.Persistence", "{F3131BAC-FF6E-FBF1-1A59-74B89427DFE6}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Provenance", "Provenance", "{316BBD0A-04D2-85C9-52EA-7993CC6C8930}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Provenance.Attestation", "StellaOps.Provenance.Attestation", "{9D6AB85A-85EA-D85A-5566-A121D34016E6}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Router", "Router", "{FC018E5B-1E2F-DE19-1E97-0C845058C469}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "__Libraries", "__Libraries", "{1BE5B76C-B486-560B-6CB2-44C6537249AA}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Messaging", "StellaOps.Messaging", "{F4F1CBE2-1CDD-CAA4-41F0-266DB4677C05}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Scanner", "Scanner", "{5896C4B3-31D1-1EDD-11D0-C46DB178DC12}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "__Libraries", "__Libraries", "{D4D193A8-47D7-0B1A-1327-F9C580E7AD07}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Scanner.Analyzers.Lang", "StellaOps.Scanner.Analyzers.Lang", "{69C91AE6-4555-7B2C-AD32-F7F11B9C605A}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Scanner.Analyzers.Lang.Bun", "StellaOps.Scanner.Analyzers.Lang.Bun", "{E8061AC3-8163-26F9-4FC8-C0E31D9C1EE1}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Scanner.Analyzers.Lang.Java", "StellaOps.Scanner.Analyzers.Lang.Java", "{AE168BCD-C771-ECB3-6830-12D1D3B1871B}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Scanner.Analyzers.Lang.Node", "StellaOps.Scanner.Analyzers.Lang.Node", "{345E1BA3-820E-DF7C-85FA-A9ABDD8B4057}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Scanner.Analyzers.Lang.Php", "StellaOps.Scanner.Analyzers.Lang.Php", "{AEA0B5AB-830E-DB83-623F-3CE249DB4A1C}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Scanner.Analyzers.Lang.Python", "StellaOps.Scanner.Analyzers.Lang.Python", "{DB6D3C1B-DBD3-4D87-64E5-87146B89E6EA}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Scanner.Analyzers.Lang.Ruby", "StellaOps.Scanner.Analyzers.Lang.Ruby", "{0FF1692A-5BF7-62DC-C61C-FD2F44252ED2}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Scanner.Core", "StellaOps.Scanner.Core", "{C9BCCEDF-7B8A-BCD8-A6B4-75EB25689FE8}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Scanner.EntryTrace", "StellaOps.Scanner.EntryTrace", "{C0E85164-7AA3-6931-5770-037E3051A499}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Scanner.ProofSpine", "StellaOps.Scanner.ProofSpine", "{9F30DC58-7747-31D8-2403-D7D0F5454C87}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Scanner.Surface.Env", "StellaOps.Scanner.Surface.Env", "{336213F7-1241-D268-8EA5-1C73F0040714}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Scanner.Surface.FS", "StellaOps.Scanner.Surface.FS", "{5693F73D-6707-6F86-65D6-654023205615}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Scanner.Surface.Secrets", "StellaOps.Scanner.Surface.Secrets", "{593308D7-2453-DC66-4151-E983E4B3F422}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Scanner.Surface.Validation", "StellaOps.Scanner.Surface.Validation", "{7D55A179-3CDB-8D44-C448-F502BF7ECB3D}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Scheduler", "Scheduler", "{B24B448A-28D8-778E-DCC1-FCF4A0916DF5}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "__Libraries", "__Libraries", "{BF1AF1AB-97A8-BD70-63F2-E028DE8EE90F}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Scheduler.Models", "StellaOps.Scheduler.Models", "{3DB6D7AE-8187-5324-1208-D6090D5324C6}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Scheduler.Persistence", "StellaOps.Scheduler.Persistence", "{F945436F-31AA-CA1E-6C57-CCA4E8F854B4}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Signer", "Signer", "{3247EE0D-B3E9-9C11-B0AE-FE719410390B}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Signer", "StellaOps.Signer", "{CD7C09DA-FEC8-2CC5-D00C-E525638DFF4A}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Signer.Core", "StellaOps.Signer.Core", "{79B10804-91E9-972E-1913-EE0F0B11663E}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Signer.Infrastructure", "StellaOps.Signer.Infrastructure", "{7C2831B0-C6BE-6A5A-D8AF-0FB8CE7CC181}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Symbols", "Symbols", "{B67B057E-97D2-C6C5-0D7C-D41CA935778A}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Symbols.Client", "StellaOps.Symbols.Client", "{0749F755-0A1A-7265-20BC-F2DE9EAE4DC3}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Symbols.Core", "StellaOps.Symbols.Core", "{EFA3BD2C-84D2-5AA8-C5B6-DD41A302A229}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "TimelineIndexer", "TimelineIndexer", "{0C91EE5B-C434-750F-C923-6D7F9993BF94}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.TimelineIndexer", "StellaOps.TimelineIndexer", "{2EB6434B-85BC-51D4-4BA4-DD291B656FA7}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.TimelineIndexer.Core", "StellaOps.TimelineIndexer.Core", "{420AE456-2C11-B598-ECCF-8A00F8BAA467}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "__Libraries", "__Libraries", "{1345DD29-BB3A-FB5F-4B3D-E29F6045A27A}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.AuditPack", "StellaOps.AuditPack", "{232347E1-9BB1-0E46-AA39-C22E3B91BC39}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Auth.Security", "StellaOps.Auth.Security", "{9C2DD234-FA33-FDB6-86F0-EF9B75A13450}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Canonical.Json", "StellaOps.Canonical.Json", "{79E122F4-2325-3E92-438E-5825A307B594}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Canonicalization", "StellaOps.Canonicalization", "{584C3E3B-3CC8-504F-C662-C23A1DF3D002}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Configuration", "StellaOps.Configuration", "{538E2D98-5325-3F54-BE74-EFE5FC1ECBD8}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Cryptography", "StellaOps.Cryptography", "{66557252-B5C4-664B-D807-07018C627474}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Cryptography.DependencyInjection", "StellaOps.Cryptography.DependencyInjection", "{7203223D-FF02-7BEB-2798-D1639ACC01C4}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Cryptography.Kms", "StellaOps.Cryptography.Kms", "{5AC9EE40-1881-5F8A-46A2-2C303950D3C8}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Cryptography.Plugin.BouncyCastle", "StellaOps.Cryptography.Plugin.BouncyCastle", "{927E3CD3-4C20-4DE5-A395-D0977152A8D3}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Cryptography.Plugin.CryptoPro", "StellaOps.Cryptography.Plugin.CryptoPro", "{3C69853C-90E3-D889-1960-3B9229882590}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Cryptography.Plugin.EIDAS", "StellaOps.Cryptography.Plugin.EIDAS", "{695330E8-D292-889E-1D7F-1250A378492A}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Cryptography.Plugin.OfflineVerification", "StellaOps.Cryptography.Plugin.OfflineVerification", "{9FB0DDD7-7A77-8DA4-F9E2-A94E60ED8FC7}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Cryptography.Plugin.OpenSslGost", "StellaOps.Cryptography.Plugin.OpenSslGost", "{643E4D4C-BC96-A37F-E0EC-488127F0B127}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Cryptography.Plugin.Pkcs11Gost", "StellaOps.Cryptography.Plugin.Pkcs11Gost", "{6F2CA7F5-3E7C-C61B-94E6-E7DD1227B5B1}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Cryptography.Plugin.PqSoft", "StellaOps.Cryptography.Plugin.PqSoft", "{F04B7DBB-77A5-C978-B2DE-8C189A32AA72}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Cryptography.Plugin.SimRemote", "StellaOps.Cryptography.Plugin.SimRemote", "{7C72F22A-20FF-DF5B-9191-6DFD0D497DB2}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Cryptography.Plugin.SmRemote", "StellaOps.Cryptography.Plugin.SmRemote", "{C896CC0A-F5E6-9AA4-C582-E691441F8D32}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Cryptography.Plugin.SmSoft", "StellaOps.Cryptography.Plugin.SmSoft", "{0AA3A418-AB45-CCA4-46D4-EEBFE011FECA}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Cryptography.Plugin.WineCsp", "StellaOps.Cryptography.Plugin.WineCsp", "{225D9926-4AE8-E539-70AD-8698E688F271}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Cryptography.PluginLoader", "StellaOps.Cryptography.PluginLoader", "{D6E8E69C-F721-BBCB-8C39-9716D53D72AD}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.DeltaVerdict", "StellaOps.DeltaVerdict", "{9529EE99-D6A5-B570-EB1F-15BD2D57DFE2}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.DependencyInjection", "StellaOps.DependencyInjection", "{589A43FD-8213-E9E3-6CFF-9CBA72D53E98}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Evidence.Bundle", "StellaOps.Evidence.Bundle", "{2BACF7E3-1278-FE99-8343-8221E6FBA9DE}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Evidence.Core", "StellaOps.Evidence.Core", "{75E47125-E4D7-8482-F1A4-726564970864}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Infrastructure.EfCore", "StellaOps.Infrastructure.EfCore", "{FCD529E0-DD17-6587-B29C-12D425C0AD0C}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Infrastructure.Postgres", "StellaOps.Infrastructure.Postgres", "{61B23570-4F2D-B060-BE1F-37995682E494}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Ingestion.Telemetry", "StellaOps.Ingestion.Telemetry", "{1182764D-2143-EEF0-9270-3DCE392F5D06}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Plugin", "StellaOps.Plugin", "{772B02B5-6280-E1D4-3E2E-248D0455C2FB}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Provcache", "StellaOps.Provcache", "{48F90289-938C-CCA7-B60F-D2143E7C9A69}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Provenance", "StellaOps.Provenance", "{E69FA1A0-6D1B-A6E4-2DC0-8F4C5F21BF04}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Replay.Core", "StellaOps.Replay.Core", "{083067CF-CE89-EF39-9BD3-4741919E26F3}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.TestKit", "StellaOps.TestKit", "{8380A20C-A5B8-EE91-1A58-270323688CB9}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Verdict", "StellaOps.Verdict", "{8F128EAE-E97E-82A0-A748-A13F1A85AC8F}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.VersionComparison", "StellaOps.VersionComparison", "{A7542386-71EB-4F34-E1CE-27D399325955}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "__Tests", "__Tests", "{90659617-4DF7-809A-4E5B-29BB5A98E8E1}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "__Libraries", "__Libraries", "{AB8B269C-5A2A-A4B8-0488-B5F81E55B4D9}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Testing.Manifests", "StellaOps.Testing.Manifests", "{EDBA6A07-B0FD-81C5-B3C5-1F7020F8065F}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "__Libraries", "__Libraries", "{A5C98087-E847-D2C4-2143-20869479839D}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Cli.Plugins.Aoc", "StellaOps.Cli.Plugins.Aoc", "{122C01BB-BAD0-E507-AD3F-ABA8F00A80DC}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Cli.Plugins.NonCore", "StellaOps.Cli.Plugins.NonCore", "{5788C133-8A9B-0810-2AF4-EA77504A7379}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Cli.Plugins.Symbols", "StellaOps.Cli.Plugins.Symbols", "{86CBB26D-D368-4DC4-2F5E-E47E5078BF37}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Cli.Plugins.Verdict", "StellaOps.Cli.Plugins.Verdict", "{7C3E7AD5-8E96-4BD0-5AF5-1FCB0F0D175C}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Cli.Plugins.Vex", "StellaOps.Cli.Plugins.Vex", "{3B68EBC3-2752-608B-8F6D-BC7A28A3DAB7}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "__Tests", "__Tests", "{BB76B5A5-14BA-E317-828D-110B711D71F5}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Cli.Tests", "StellaOps.Cli.Tests", "{DD40725E-6473-AB10-786C-C3B68881A622}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.AirGap.Importer", "E:\dev\git.stella-ops.org\src\AirGap\StellaOps.AirGap.Importer\StellaOps.AirGap.Importer.csproj", "{22B129C7-C609-3B90-AD56-64C746A1505E}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.AirGap.Policy", "E:\dev\git.stella-ops.org\src\AirGap\StellaOps.AirGap.Policy\StellaOps.AirGap.Policy\StellaOps.AirGap.Policy.csproj", "{AD31623A-BC43-52C2-D906-AC1D8784A541}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Aoc", "E:\dev\git.stella-ops.org\src\Aoc\__Libraries\StellaOps.Aoc\StellaOps.Aoc.csproj", "{776E2142-804F-03B9-C804-D061D64C6092}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Attestation", "E:\dev\git.stella-ops.org\src\Attestor\StellaOps.Attestation\StellaOps.Attestation.csproj", "{E106BC8E-B20D-C1B5-130C-DAC28922112A}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Attestor.Core", "E:\dev\git.stella-ops.org\src\Attestor\StellaOps.Attestor\StellaOps.Attestor.Core\StellaOps.Attestor.Core.csproj", "{5B4DF41E-C8CC-2606-FA2D-967118BD3C59}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Attestor.Envelope", "E:\dev\git.stella-ops.org\src\Attestor\StellaOps.Attestor.Envelope\StellaOps.Attestor.Envelope.csproj", "{3D8C5A6C-462D-7487-5BD0-A3EF6B657EB6}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Attestor.GraphRoot", "E:\dev\git.stella-ops.org\src\Attestor\__Libraries\StellaOps.Attestor.GraphRoot\StellaOps.Attestor.GraphRoot.csproj", "{2609BC1A-6765-29BE-78CC-C0F1D2814F10}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Attestor.ProofChain", "E:\dev\git.stella-ops.org\src\Attestor\__Libraries\StellaOps.Attestor.ProofChain\StellaOps.Attestor.ProofChain.csproj", "{C6822231-A4F4-9E69-6CE2-4FDB3E81C728}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.AuditPack", "E:\dev\git.stella-ops.org\src\__Libraries\StellaOps.AuditPack\StellaOps.AuditPack.csproj", "{28F2F8EE-CD31-0DEF-446C-D868B139F139}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Auth.Abstractions", "E:\dev\git.stella-ops.org\src\Authority\StellaOps.Authority\StellaOps.Auth.Abstractions\StellaOps.Auth.Abstractions.csproj", "{55D9B653-FB76-FCE8-1A3C-67B1BEDEC214}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Auth.Client", "E:\dev\git.stella-ops.org\src\Authority\StellaOps.Authority\StellaOps.Auth.Client\StellaOps.Auth.Client.csproj", "{DE5BF139-1E5C-D6EA-4FAA-661EF353A194}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Auth.Security", "E:\dev\git.stella-ops.org\src\__Libraries\StellaOps.Auth.Security\StellaOps.Auth.Security.csproj", "{335E62C0-9E69-A952-680B-753B1B17C6D0}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Authority.Core", "E:\dev\git.stella-ops.org\src\Authority\__Libraries\StellaOps.Authority.Core\StellaOps.Authority.Core.csproj", "{5A6CD890-8142-F920-3734-D67CA3E65F61}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Authority.Persistence", "E:\dev\git.stella-ops.org\src\Authority\__Libraries\StellaOps.Authority.Persistence\StellaOps.Authority.Persistence.csproj", "{A260E14F-DBA4-862E-53CD-18D3B92ADA3D}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Authority.Plugins.Abstractions", "E:\dev\git.stella-ops.org\src\Authority\StellaOps.Authority\StellaOps.Authority.Plugins.Abstractions\StellaOps.Authority.Plugins.Abstractions.csproj", "{97F94029-5419-6187-5A63-5C8FD9232FAE}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Canonical.Json", "E:\dev\git.stella-ops.org\src\__Libraries\StellaOps.Canonical.Json\StellaOps.Canonical.Json.csproj", "{AF9E7F02-25AD-3540-18D7-F6A4F8BA5A60}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Canonicalization", "E:\dev\git.stella-ops.org\src\__Libraries\StellaOps.Canonicalization\StellaOps.Canonicalization.csproj", "{301015C5-1F56-2266-84AA-AB6D83F28893}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Cli", "StellaOps.Cli\StellaOps.Cli.csproj", "{0C51F029-7C57-B767-AFFA-4800230A6B1F}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Cli.Plugins.Aoc", "__Libraries\StellaOps.Cli.Plugins.Aoc\StellaOps.Cli.Plugins.Aoc.csproj", "{1BAEE7A9-C442-D76D-8531-AE20501395C7}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Cli.Plugins.NonCore", "__Libraries\StellaOps.Cli.Plugins.NonCore\StellaOps.Cli.Plugins.NonCore.csproj", "{E7CCD23E-AFD3-B46F-48B0-908E5BF0825B}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Cli.Plugins.Symbols", "__Libraries\StellaOps.Cli.Plugins.Symbols\StellaOps.Cli.Plugins.Symbols.csproj", "{8D3B990F-E832-139D-DDFD-1076A8E0834E}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Cli.Plugins.Verdict", "__Libraries\StellaOps.Cli.Plugins.Verdict\StellaOps.Cli.Plugins.Verdict.csproj", "{058E17AA-8F9F-426B-2364-65467F6891F7}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Cli.Plugins.Vex", "__Libraries\StellaOps.Cli.Plugins.Vex\StellaOps.Cli.Plugins.Vex.csproj", "{33767BF5-0175-51A7-9B37-9312610359FC}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Cli.Tests", "__Tests\StellaOps.Cli.Tests\StellaOps.Cli.Tests.csproj", "{D1322A50-ABAB-EEFC-17B5-60EDCA13DF8C}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Concelier.Cache.Valkey", "E:\dev\git.stella-ops.org\src\Concelier\__Libraries\StellaOps.Concelier.Cache.Valkey\StellaOps.Concelier.Cache.Valkey.csproj", "{AB6AE2B6-8D6B-2D9F-2A88-7C596C59F4FC}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Concelier.Core", "E:\dev\git.stella-ops.org\src\Concelier\__Libraries\StellaOps.Concelier.Core\StellaOps.Concelier.Core.csproj", "{BA45605A-1CCE-6B0C-489D-C113915B243F}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Concelier.Interest", "E:\dev\git.stella-ops.org\src\Concelier\__Libraries\StellaOps.Concelier.Interest\StellaOps.Concelier.Interest.csproj", "{9D31FC8A-2A69-B78A-D3E5-4F867B16D971}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Concelier.Merge", "E:\dev\git.stella-ops.org\src\Concelier\__Libraries\StellaOps.Concelier.Merge\StellaOps.Concelier.Merge.csproj", "{92268008-FBB0-C7AD-ECC2-7B75BED9F5E1}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Concelier.Models", "E:\dev\git.stella-ops.org\src\Concelier\__Libraries\StellaOps.Concelier.Models\StellaOps.Concelier.Models.csproj", "{8DCCAF70-D364-4C8B-4E90-AF65091DE0C5}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Concelier.Normalization", "E:\dev\git.stella-ops.org\src\Concelier\__Libraries\StellaOps.Concelier.Normalization\StellaOps.Concelier.Normalization.csproj", "{7828C164-DD01-2809-CCB3-364486834F60}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Concelier.Persistence", "E:\dev\git.stella-ops.org\src\Concelier\__Libraries\StellaOps.Concelier.Persistence\StellaOps.Concelier.Persistence.csproj", "{DE95E7B2-0937-A980-441F-829E023BC43E}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Concelier.ProofService", "E:\dev\git.stella-ops.org\src\Concelier\__Libraries\StellaOps.Concelier.ProofService\StellaOps.Concelier.ProofService.csproj", "{91D69463-23E2-E2C7-AA7E-A78B13CED620}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Concelier.RawModels", "E:\dev\git.stella-ops.org\src\Concelier\__Libraries\StellaOps.Concelier.RawModels\StellaOps.Concelier.RawModels.csproj", "{34EFF636-81A7-8DF6-7CC9-4DA784BAC7F3}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Concelier.SbomIntegration", "E:\dev\git.stella-ops.org\src\Concelier\__Libraries\StellaOps.Concelier.SbomIntegration\StellaOps.Concelier.SbomIntegration.csproj", "{5DCF16A8-97C6-2CB4-6A63-0370239039EB}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Concelier.SourceIntel", "E:\dev\git.stella-ops.org\src\Concelier\__Libraries\StellaOps.Concelier.SourceIntel\StellaOps.Concelier.SourceIntel.csproj", "{EB093C48-CDAC-106B-1196-AE34809B34C0}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Configuration", "E:\dev\git.stella-ops.org\src\__Libraries\StellaOps.Configuration\StellaOps.Configuration.csproj", "{92C62F7B-8028-6EE1-B71B-F45F459B8E97}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Cryptography", "E:\dev\git.stella-ops.org\src\__Libraries\StellaOps.Cryptography\StellaOps.Cryptography.csproj", "{F664A948-E352-5808-E780-77A03F19E93E}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Cryptography.DependencyInjection", "E:\dev\git.stella-ops.org\src\__Libraries\StellaOps.Cryptography.DependencyInjection\StellaOps.Cryptography.DependencyInjection.csproj", "{FA83F778-5252-0B80-5555-E69F790322EA}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Cryptography.Kms", "E:\dev\git.stella-ops.org\src\__Libraries\StellaOps.Cryptography.Kms\StellaOps.Cryptography.Kms.csproj", "{F3A27846-6DE0-3448-222C-25A273E86B2E}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Cryptography.Plugin.BouncyCastle", "E:\dev\git.stella-ops.org\src\__Libraries\StellaOps.Cryptography.Plugin.BouncyCastle\StellaOps.Cryptography.Plugin.BouncyCastle.csproj", "{166F4DEC-9886-92D5-6496-085664E9F08F}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Cryptography.Plugin.CryptoPro", "E:\dev\git.stella-ops.org\src\__Libraries\StellaOps.Cryptography.Plugin.CryptoPro\StellaOps.Cryptography.Plugin.CryptoPro.csproj", "{C53E0895-879A-D9E6-0A43-24AD17A2F270}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Cryptography.Plugin.EIDAS", "E:\dev\git.stella-ops.org\src\__Libraries\StellaOps.Cryptography.Plugin.EIDAS\StellaOps.Cryptography.Plugin.EIDAS.csproj", "{1EE42F0F-3F9A-613C-D01F-8BCDB4C42C0E}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Cryptography.Plugin.OfflineVerification", "E:\dev\git.stella-ops.org\src\__Libraries\StellaOps.Cryptography.Plugin.OfflineVerification\StellaOps.Cryptography.Plugin.OfflineVerification.csproj", "{246FCC7C-1437-742D-BAE5-E77A24164F08}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Cryptography.Plugin.OpenSslGost", "E:\dev\git.stella-ops.org\src\__Libraries\StellaOps.Cryptography.Plugin.OpenSslGost\StellaOps.Cryptography.Plugin.OpenSslGost.csproj", "{0AED303F-69E6-238F-EF80-81985080EDB7}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Cryptography.Plugin.Pkcs11Gost", "E:\dev\git.stella-ops.org\src\__Libraries\StellaOps.Cryptography.Plugin.Pkcs11Gost\StellaOps.Cryptography.Plugin.Pkcs11Gost.csproj", "{2904D288-CE64-A565-2C46-C2E85A96A1EE}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Cryptography.Plugin.PqSoft", "E:\dev\git.stella-ops.org\src\__Libraries\StellaOps.Cryptography.Plugin.PqSoft\StellaOps.Cryptography.Plugin.PqSoft.csproj", "{A6667CC3-B77F-023E-3A67-05F99E9FF46A}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Cryptography.Plugin.SimRemote", "E:\dev\git.stella-ops.org\src\__Libraries\StellaOps.Cryptography.Plugin.SimRemote\StellaOps.Cryptography.Plugin.SimRemote.csproj", "{A26E2816-F787-F76B-1D6C-E086DD3E19CE}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Cryptography.Plugin.SmRemote", "E:\dev\git.stella-ops.org\src\__Libraries\StellaOps.Cryptography.Plugin.SmRemote\StellaOps.Cryptography.Plugin.SmRemote.csproj", "{B3DEC619-67AC-1B5A-4F3E-A1F24C3F6877}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Cryptography.Plugin.SmSoft", "E:\dev\git.stella-ops.org\src\__Libraries\StellaOps.Cryptography.Plugin.SmSoft\StellaOps.Cryptography.Plugin.SmSoft.csproj", "{90DB65B4-8F6E-FB8E-0281-505AD8BC6BA6}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Cryptography.Plugin.WineCsp", "E:\dev\git.stella-ops.org\src\__Libraries\StellaOps.Cryptography.Plugin.WineCsp\StellaOps.Cryptography.Plugin.WineCsp.csproj", "{059FBB86-DEE6-8207-3F23-2A1A3EC00DEA}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Cryptography.PluginLoader", "E:\dev\git.stella-ops.org\src\__Libraries\StellaOps.Cryptography.PluginLoader\StellaOps.Cryptography.PluginLoader.csproj", "{8BBA3159-C4CC-F685-A28C-7FE6CBD3D2A1}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.DeltaVerdict", "E:\dev\git.stella-ops.org\src\__Libraries\StellaOps.DeltaVerdict\StellaOps.DeltaVerdict.csproj", "{EA0974E3-CD2B-5792-EF1E-9B5B7CCBDF00}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.DependencyInjection", "E:\dev\git.stella-ops.org\src\__Libraries\StellaOps.DependencyInjection\StellaOps.DependencyInjection.csproj", "{632A1F0D-1BA5-C84B-B716-2BE638A92780}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Evidence.Bundle", "E:\dev\git.stella-ops.org\src\__Libraries\StellaOps.Evidence.Bundle\StellaOps.Evidence.Bundle.csproj", "{9DE7852B-7E2D-257E-B0F1-45D2687854ED}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Evidence.Core", "E:\dev\git.stella-ops.org\src\__Libraries\StellaOps.Evidence.Core\StellaOps.Evidence.Core.csproj", "{DC2AFC89-C3C8-4E9B-13A7-027EB6386EFA}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Excititor.Core", "E:\dev\git.stella-ops.org\src\Excititor\__Libraries\StellaOps.Excititor.Core\StellaOps.Excititor.Core.csproj", "{9151601C-8784-01A6-C2E7-A5C0FAAB0AEF}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Excititor.Persistence", "E:\dev\git.stella-ops.org\src\Excititor\__Libraries\StellaOps.Excititor.Persistence\StellaOps.Excititor.Persistence.csproj", "{4F1EE2D9-9392-6A1C-7224-6B01FAB934E3}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.ExportCenter.Client", "E:\dev\git.stella-ops.org\src\ExportCenter\StellaOps.ExportCenter\StellaOps.ExportCenter.Client\StellaOps.ExportCenter.Client.csproj", "{104A930A-6D8F-8C36-2CB5-0BC4F8FD74D2}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.ExportCenter.Core", "E:\dev\git.stella-ops.org\src\ExportCenter\StellaOps.ExportCenter\StellaOps.ExportCenter.Core\StellaOps.ExportCenter.Core.csproj", "{F7947A80-F07C-2FBF-77F8-DDFA57951A97}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Feedser.BinaryAnalysis", "E:\dev\git.stella-ops.org\src\Feedser\StellaOps.Feedser.BinaryAnalysis\StellaOps.Feedser.BinaryAnalysis.csproj", "{CB296A20-2732-77C1-7F23-27D5BAEDD0C7}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Feedser.Core", "E:\dev\git.stella-ops.org\src\Feedser\StellaOps.Feedser.Core\StellaOps.Feedser.Core.csproj", "{0DBEC9BA-FE1D-3898-B2C6-E4357DC23E0F}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Infrastructure.EfCore", "E:\dev\git.stella-ops.org\src\__Libraries\StellaOps.Infrastructure.EfCore\StellaOps.Infrastructure.EfCore.csproj", "{A63897D9-9531-989B-7309-E384BCFC2BB9}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Infrastructure.Postgres", "E:\dev\git.stella-ops.org\src\__Libraries\StellaOps.Infrastructure.Postgres\StellaOps.Infrastructure.Postgres.csproj", "{8C594D82-3463-3367-4F06-900AC707753D}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Ingestion.Telemetry", "E:\dev\git.stella-ops.org\src\__Libraries\StellaOps.Ingestion.Telemetry\StellaOps.Ingestion.Telemetry.csproj", "{9588FBF9-C37E-D16E-2E8F-CFA226EAC01D}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Messaging", "E:\dev\git.stella-ops.org\src\Router\__Libraries\StellaOps.Messaging\StellaOps.Messaging.csproj", "{97998C88-E6E1-D5E2-B632-537B58E00CBF}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Notify.Models", "E:\dev\git.stella-ops.org\src\Notify\__Libraries\StellaOps.Notify.Models\StellaOps.Notify.Models.csproj", "{20D1569C-2A47-38B8-075E-47225B674394}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Notify.Persistence", "E:\dev\git.stella-ops.org\src\Notify\__Libraries\StellaOps.Notify.Persistence\StellaOps.Notify.Persistence.csproj", "{2F7AA715-25AE-086A-7DF4-CAB5EF00E2B7}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Plugin", "E:\dev\git.stella-ops.org\src\__Libraries\StellaOps.Plugin\StellaOps.Plugin.csproj", "{38A9EE9B-6FC8-93BC-0D43-2A906E678D66}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Policy", "E:\dev\git.stella-ops.org\src\Policy\__Libraries\StellaOps.Policy\StellaOps.Policy.csproj", "{19868E2D-7163-2108-1094-F13887C4F070}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Policy.Exceptions", "E:\dev\git.stella-ops.org\src\Policy\__Libraries\StellaOps.Policy.Exceptions\StellaOps.Policy.Exceptions.csproj", "{7D3FC972-467A-4917-8339-9B6462C6A38A}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Policy.Persistence", "E:\dev\git.stella-ops.org\src\Policy\__Libraries\StellaOps.Policy.Persistence\StellaOps.Policy.Persistence.csproj", "{C154051B-DB4E-5270-AF5A-12A0FFE0E769}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Policy.RiskProfile", "E:\dev\git.stella-ops.org\src\Policy\StellaOps.Policy.RiskProfile\StellaOps.Policy.RiskProfile.csproj", "{CC319FC5-F4B1-C3DD-7310-4DAD343E0125}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Policy.Scoring", "E:\dev\git.stella-ops.org\src\Policy\StellaOps.Policy.Scoring\StellaOps.Policy.Scoring.csproj", "{CD6B144E-BCDD-D4FE-2749-703DAB054EBC}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.PolicyDsl", "E:\dev\git.stella-ops.org\src\Policy\StellaOps.PolicyDsl\StellaOps.PolicyDsl.csproj", "{B46D185B-A630-8F76-E61B-90084FBF65B0}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Provcache", "E:\dev\git.stella-ops.org\src\__Libraries\StellaOps.Provcache\StellaOps.Provcache.csproj", "{84F711C2-C210-28D2-F0D9-B13733FEE23D}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Provenance", "E:\dev\git.stella-ops.org\src\__Libraries\StellaOps.Provenance\StellaOps.Provenance.csproj", "{CBB14B90-27F9-8DD6-DFC4-3507DBD1FBC6}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Provenance.Attestation", "E:\dev\git.stella-ops.org\src\Provenance\StellaOps.Provenance.Attestation\StellaOps.Provenance.Attestation.csproj", "{A78EBC0F-C62C-8F56-95C0-330E376242A2}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Replay.Core", "E:\dev\git.stella-ops.org\src\__Libraries\StellaOps.Replay.Core\StellaOps.Replay.Core.csproj", "{6D26FB21-7E48-024B-E5D4-E3F0F31976BB}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Scanner.Analyzers.Lang", "E:\dev\git.stella-ops.org\src\Scanner\__Libraries\StellaOps.Scanner.Analyzers.Lang\StellaOps.Scanner.Analyzers.Lang.csproj", "{28D91816-206C-576E-1A83-FD98E08C2E3C}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Scanner.Analyzers.Lang.Bun", "E:\dev\git.stella-ops.org\src\Scanner\__Libraries\StellaOps.Scanner.Analyzers.Lang.Bun\StellaOps.Scanner.Analyzers.Lang.Bun.csproj", "{5EFEC79C-A9F1-96A4-692C-733566107170}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Scanner.Analyzers.Lang.Java", "E:\dev\git.stella-ops.org\src\Scanner\__Libraries\StellaOps.Scanner.Analyzers.Lang.Java\StellaOps.Scanner.Analyzers.Lang.Java.csproj", "{B7B5D764-C3A0-1743-0739-29966F993626}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Scanner.Analyzers.Lang.Node", "E:\dev\git.stella-ops.org\src\Scanner\__Libraries\StellaOps.Scanner.Analyzers.Lang.Node\StellaOps.Scanner.Analyzers.Lang.Node.csproj", "{C4EDBBAF-875C-4839-05A8-F6F12A5ED52D}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Scanner.Analyzers.Lang.Php", "E:\dev\git.stella-ops.org\src\Scanner\__Libraries\StellaOps.Scanner.Analyzers.Lang.Php\StellaOps.Scanner.Analyzers.Lang.Php.csproj", "{0EAC8F64-9588-1EF0-C33A-67590CF27590}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Scanner.Analyzers.Lang.Python", "E:\dev\git.stella-ops.org\src\Scanner\__Libraries\StellaOps.Scanner.Analyzers.Lang.Python\StellaOps.Scanner.Analyzers.Lang.Python.csproj", "{B1B31937-CCC8-D97A-F66D-1849734B780B}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Scanner.Analyzers.Lang.Ruby", "E:\dev\git.stella-ops.org\src\Scanner\__Libraries\StellaOps.Scanner.Analyzers.Lang.Ruby\StellaOps.Scanner.Analyzers.Lang.Ruby.csproj", "{A345E5AC-BDDB-A817-3C92-08C8865D1EF9}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Scanner.Core", "E:\dev\git.stella-ops.org\src\Scanner\__Libraries\StellaOps.Scanner.Core\StellaOps.Scanner.Core.csproj", "{58D8630F-C0F4-B772-8572-BCC98FF0F0D8}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Scanner.EntryTrace", "E:\dev\git.stella-ops.org\src\Scanner\__Libraries\StellaOps.Scanner.EntryTrace\StellaOps.Scanner.EntryTrace.csproj", "{D24E7862-3930-A4F6-1DFA-DA88C759546C}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Scanner.ProofSpine", "E:\dev\git.stella-ops.org\src\Scanner\__Libraries\StellaOps.Scanner.ProofSpine\StellaOps.Scanner.ProofSpine.csproj", "{7CB7FEA8-8A12-A5D6-0057-AA65DB328617}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Scanner.Surface.Env", "E:\dev\git.stella-ops.org\src\Scanner\__Libraries\StellaOps.Scanner.Surface.Env\StellaOps.Scanner.Surface.Env.csproj", "{52698305-D6F8-C13C-0882-48FC37726404}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Scanner.Surface.FS", "E:\dev\git.stella-ops.org\src\Scanner\__Libraries\StellaOps.Scanner.Surface.FS\StellaOps.Scanner.Surface.FS.csproj", "{5567139C-0365-B6A0-5DD0-978A09B9F176}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Scanner.Surface.Secrets", "E:\dev\git.stella-ops.org\src\Scanner\__Libraries\StellaOps.Scanner.Surface.Secrets\StellaOps.Scanner.Surface.Secrets.csproj", "{256D269B-35EA-F833-2F1D-8E0058908DEE}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Scanner.Surface.Validation", "E:\dev\git.stella-ops.org\src\Scanner\__Libraries\StellaOps.Scanner.Surface.Validation\StellaOps.Scanner.Surface.Validation.csproj", "{6E9C9582-67FA-2EB1-C6BA-AD4CD326E276}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Scheduler.Models", "E:\dev\git.stella-ops.org\src\Scheduler\__Libraries\StellaOps.Scheduler.Models\StellaOps.Scheduler.Models.csproj", "{1F372AB9-D8DD-D295-1D5E-CB5D454CBB24}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Scheduler.Persistence", "E:\dev\git.stella-ops.org\src\Scheduler\__Libraries\StellaOps.Scheduler.Persistence\StellaOps.Scheduler.Persistence.csproj", "{D96DA724-3A66-14E2-D6CC-F65CEEE71069}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Signer.Core", "E:\dev\git.stella-ops.org\src\Signer\StellaOps.Signer\StellaOps.Signer.Core\StellaOps.Signer.Core.csproj", "{0AF13355-173C-3128-5AFC-D32E540DA3EF}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Signer.Infrastructure", "E:\dev\git.stella-ops.org\src\Signer\StellaOps.Signer\StellaOps.Signer.Infrastructure\StellaOps.Signer.Infrastructure.csproj", "{06BC00C6-78D4-05AD-C8C8-FF64CD7968E0}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Symbols.Client", "E:\dev\git.stella-ops.org\src\Symbols\StellaOps.Symbols.Client\StellaOps.Symbols.Client.csproj", "{FFC170B2-A6F0-A1D7-02BD-16D813C8C8C0}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Symbols.Core", "E:\dev\git.stella-ops.org\src\Symbols\StellaOps.Symbols.Core\StellaOps.Symbols.Core.csproj", "{85B8B27B-51DD-025E-EEED-D44BC0D318B8}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.TestKit", "E:\dev\git.stella-ops.org\src\__Libraries\StellaOps.TestKit\StellaOps.TestKit.csproj", "{AF043113-CCE3-59C1-DF71-9804155F26A8}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Testing.Manifests", "E:\dev\git.stella-ops.org\src\__Tests\__Libraries\StellaOps.Testing.Manifests\StellaOps.Testing.Manifests.csproj", "{9222D186-CD9F-C783-AED5-A3B0E48623BD}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.TimelineIndexer.Core", "E:\dev\git.stella-ops.org\src\TimelineIndexer\StellaOps.TimelineIndexer\StellaOps.TimelineIndexer.Core\StellaOps.TimelineIndexer.Core.csproj", "{10588F6A-E13D-98DC-4EC9-917DCEE382EE}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Verdict", "E:\dev\git.stella-ops.org\src\__Libraries\StellaOps.Verdict\StellaOps.Verdict.csproj", "{E62C8F14-A7CF-47DF-8D60-77308D5D0647}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.VersionComparison", "E:\dev\git.stella-ops.org\src\__Libraries\StellaOps.VersionComparison\StellaOps.VersionComparison.csproj", "{1D761F8B-921C-53BF-DCF5-5ABD329EEB0C}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Release|Any CPU = Release|Any CPU - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {22B129C7-C609-3B90-AD56-64C746A1505E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {22B129C7-C609-3B90-AD56-64C746A1505E}.Debug|Any CPU.Build.0 = Debug|Any CPU - {22B129C7-C609-3B90-AD56-64C746A1505E}.Release|Any CPU.ActiveCfg = Release|Any CPU - {22B129C7-C609-3B90-AD56-64C746A1505E}.Release|Any CPU.Build.0 = Release|Any CPU - {AD31623A-BC43-52C2-D906-AC1D8784A541}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {AD31623A-BC43-52C2-D906-AC1D8784A541}.Debug|Any CPU.Build.0 = Debug|Any CPU - {AD31623A-BC43-52C2-D906-AC1D8784A541}.Release|Any CPU.ActiveCfg = Release|Any CPU - {AD31623A-BC43-52C2-D906-AC1D8784A541}.Release|Any CPU.Build.0 = Release|Any CPU - {776E2142-804F-03B9-C804-D061D64C6092}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {776E2142-804F-03B9-C804-D061D64C6092}.Debug|Any CPU.Build.0 = Debug|Any CPU - {776E2142-804F-03B9-C804-D061D64C6092}.Release|Any CPU.ActiveCfg = Release|Any CPU - {776E2142-804F-03B9-C804-D061D64C6092}.Release|Any CPU.Build.0 = Release|Any CPU - {E106BC8E-B20D-C1B5-130C-DAC28922112A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {E106BC8E-B20D-C1B5-130C-DAC28922112A}.Debug|Any CPU.Build.0 = Debug|Any CPU - {E106BC8E-B20D-C1B5-130C-DAC28922112A}.Release|Any CPU.ActiveCfg = Release|Any CPU - {E106BC8E-B20D-C1B5-130C-DAC28922112A}.Release|Any CPU.Build.0 = Release|Any CPU - {5B4DF41E-C8CC-2606-FA2D-967118BD3C59}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {5B4DF41E-C8CC-2606-FA2D-967118BD3C59}.Debug|Any CPU.Build.0 = Debug|Any CPU - {5B4DF41E-C8CC-2606-FA2D-967118BD3C59}.Release|Any CPU.ActiveCfg = Release|Any CPU - {5B4DF41E-C8CC-2606-FA2D-967118BD3C59}.Release|Any CPU.Build.0 = Release|Any CPU - {3D8C5A6C-462D-7487-5BD0-A3EF6B657EB6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {3D8C5A6C-462D-7487-5BD0-A3EF6B657EB6}.Debug|Any CPU.Build.0 = Debug|Any CPU - {3D8C5A6C-462D-7487-5BD0-A3EF6B657EB6}.Release|Any CPU.ActiveCfg = Release|Any CPU - {3D8C5A6C-462D-7487-5BD0-A3EF6B657EB6}.Release|Any CPU.Build.0 = Release|Any CPU - {2609BC1A-6765-29BE-78CC-C0F1D2814F10}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {2609BC1A-6765-29BE-78CC-C0F1D2814F10}.Debug|Any CPU.Build.0 = Debug|Any CPU - {2609BC1A-6765-29BE-78CC-C0F1D2814F10}.Release|Any CPU.ActiveCfg = Release|Any CPU - {2609BC1A-6765-29BE-78CC-C0F1D2814F10}.Release|Any CPU.Build.0 = Release|Any CPU - {C6822231-A4F4-9E69-6CE2-4FDB3E81C728}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {C6822231-A4F4-9E69-6CE2-4FDB3E81C728}.Debug|Any CPU.Build.0 = Debug|Any CPU - {C6822231-A4F4-9E69-6CE2-4FDB3E81C728}.Release|Any CPU.ActiveCfg = Release|Any CPU - {C6822231-A4F4-9E69-6CE2-4FDB3E81C728}.Release|Any CPU.Build.0 = Release|Any CPU - {28F2F8EE-CD31-0DEF-446C-D868B139F139}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {28F2F8EE-CD31-0DEF-446C-D868B139F139}.Debug|Any CPU.Build.0 = Debug|Any CPU - {28F2F8EE-CD31-0DEF-446C-D868B139F139}.Release|Any CPU.ActiveCfg = Release|Any CPU - {28F2F8EE-CD31-0DEF-446C-D868B139F139}.Release|Any CPU.Build.0 = Release|Any CPU - {55D9B653-FB76-FCE8-1A3C-67B1BEDEC214}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {55D9B653-FB76-FCE8-1A3C-67B1BEDEC214}.Debug|Any CPU.Build.0 = Debug|Any CPU - {55D9B653-FB76-FCE8-1A3C-67B1BEDEC214}.Release|Any CPU.ActiveCfg = Release|Any CPU - {55D9B653-FB76-FCE8-1A3C-67B1BEDEC214}.Release|Any CPU.Build.0 = Release|Any CPU - {DE5BF139-1E5C-D6EA-4FAA-661EF353A194}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {DE5BF139-1E5C-D6EA-4FAA-661EF353A194}.Debug|Any CPU.Build.0 = Debug|Any CPU - {DE5BF139-1E5C-D6EA-4FAA-661EF353A194}.Release|Any CPU.ActiveCfg = Release|Any CPU - {DE5BF139-1E5C-D6EA-4FAA-661EF353A194}.Release|Any CPU.Build.0 = Release|Any CPU - {335E62C0-9E69-A952-680B-753B1B17C6D0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {335E62C0-9E69-A952-680B-753B1B17C6D0}.Debug|Any CPU.Build.0 = Debug|Any CPU - {335E62C0-9E69-A952-680B-753B1B17C6D0}.Release|Any CPU.ActiveCfg = Release|Any CPU - {335E62C0-9E69-A952-680B-753B1B17C6D0}.Release|Any CPU.Build.0 = Release|Any CPU - {5A6CD890-8142-F920-3734-D67CA3E65F61}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {5A6CD890-8142-F920-3734-D67CA3E65F61}.Debug|Any CPU.Build.0 = Debug|Any CPU - {5A6CD890-8142-F920-3734-D67CA3E65F61}.Release|Any CPU.ActiveCfg = Release|Any CPU - {5A6CD890-8142-F920-3734-D67CA3E65F61}.Release|Any CPU.Build.0 = Release|Any CPU - {A260E14F-DBA4-862E-53CD-18D3B92ADA3D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {A260E14F-DBA4-862E-53CD-18D3B92ADA3D}.Debug|Any CPU.Build.0 = Debug|Any CPU - {A260E14F-DBA4-862E-53CD-18D3B92ADA3D}.Release|Any CPU.ActiveCfg = Release|Any CPU - {A260E14F-DBA4-862E-53CD-18D3B92ADA3D}.Release|Any CPU.Build.0 = Release|Any CPU - {97F94029-5419-6187-5A63-5C8FD9232FAE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {97F94029-5419-6187-5A63-5C8FD9232FAE}.Debug|Any CPU.Build.0 = Debug|Any CPU - {97F94029-5419-6187-5A63-5C8FD9232FAE}.Release|Any CPU.ActiveCfg = Release|Any CPU - {97F94029-5419-6187-5A63-5C8FD9232FAE}.Release|Any CPU.Build.0 = Release|Any CPU - {AF9E7F02-25AD-3540-18D7-F6A4F8BA5A60}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {AF9E7F02-25AD-3540-18D7-F6A4F8BA5A60}.Debug|Any CPU.Build.0 = Debug|Any CPU - {AF9E7F02-25AD-3540-18D7-F6A4F8BA5A60}.Release|Any CPU.ActiveCfg = Release|Any CPU - {AF9E7F02-25AD-3540-18D7-F6A4F8BA5A60}.Release|Any CPU.Build.0 = Release|Any CPU - {301015C5-1F56-2266-84AA-AB6D83F28893}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {301015C5-1F56-2266-84AA-AB6D83F28893}.Debug|Any CPU.Build.0 = Debug|Any CPU - {301015C5-1F56-2266-84AA-AB6D83F28893}.Release|Any CPU.ActiveCfg = Release|Any CPU - {301015C5-1F56-2266-84AA-AB6D83F28893}.Release|Any CPU.Build.0 = Release|Any CPU - {0C51F029-7C57-B767-AFFA-4800230A6B1F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {0C51F029-7C57-B767-AFFA-4800230A6B1F}.Debug|Any CPU.Build.0 = Debug|Any CPU - {0C51F029-7C57-B767-AFFA-4800230A6B1F}.Release|Any CPU.ActiveCfg = Release|Any CPU - {0C51F029-7C57-B767-AFFA-4800230A6B1F}.Release|Any CPU.Build.0 = Release|Any CPU - {1BAEE7A9-C442-D76D-8531-AE20501395C7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {1BAEE7A9-C442-D76D-8531-AE20501395C7}.Debug|Any CPU.Build.0 = Debug|Any CPU - {1BAEE7A9-C442-D76D-8531-AE20501395C7}.Release|Any CPU.ActiveCfg = Release|Any CPU - {1BAEE7A9-C442-D76D-8531-AE20501395C7}.Release|Any CPU.Build.0 = Release|Any CPU - {E7CCD23E-AFD3-B46F-48B0-908E5BF0825B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {E7CCD23E-AFD3-B46F-48B0-908E5BF0825B}.Debug|Any CPU.Build.0 = Debug|Any CPU - {E7CCD23E-AFD3-B46F-48B0-908E5BF0825B}.Release|Any CPU.ActiveCfg = Release|Any CPU - {E7CCD23E-AFD3-B46F-48B0-908E5BF0825B}.Release|Any CPU.Build.0 = Release|Any CPU - {8D3B990F-E832-139D-DDFD-1076A8E0834E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {8D3B990F-E832-139D-DDFD-1076A8E0834E}.Debug|Any CPU.Build.0 = Debug|Any CPU - {8D3B990F-E832-139D-DDFD-1076A8E0834E}.Release|Any CPU.ActiveCfg = Release|Any CPU - {8D3B990F-E832-139D-DDFD-1076A8E0834E}.Release|Any CPU.Build.0 = Release|Any CPU - {058E17AA-8F9F-426B-2364-65467F6891F7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {058E17AA-8F9F-426B-2364-65467F6891F7}.Debug|Any CPU.Build.0 = Debug|Any CPU - {058E17AA-8F9F-426B-2364-65467F6891F7}.Release|Any CPU.ActiveCfg = Release|Any CPU - {058E17AA-8F9F-426B-2364-65467F6891F7}.Release|Any CPU.Build.0 = Release|Any CPU - {33767BF5-0175-51A7-9B37-9312610359FC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {33767BF5-0175-51A7-9B37-9312610359FC}.Debug|Any CPU.Build.0 = Debug|Any CPU - {33767BF5-0175-51A7-9B37-9312610359FC}.Release|Any CPU.ActiveCfg = Release|Any CPU - {33767BF5-0175-51A7-9B37-9312610359FC}.Release|Any CPU.Build.0 = Release|Any CPU - {D1322A50-ABAB-EEFC-17B5-60EDCA13DF8C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {D1322A50-ABAB-EEFC-17B5-60EDCA13DF8C}.Debug|Any CPU.Build.0 = Debug|Any CPU - {D1322A50-ABAB-EEFC-17B5-60EDCA13DF8C}.Release|Any CPU.ActiveCfg = Release|Any CPU - {D1322A50-ABAB-EEFC-17B5-60EDCA13DF8C}.Release|Any CPU.Build.0 = Release|Any CPU - {AB6AE2B6-8D6B-2D9F-2A88-7C596C59F4FC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {AB6AE2B6-8D6B-2D9F-2A88-7C596C59F4FC}.Debug|Any CPU.Build.0 = Debug|Any CPU - {AB6AE2B6-8D6B-2D9F-2A88-7C596C59F4FC}.Release|Any CPU.ActiveCfg = Release|Any CPU - {AB6AE2B6-8D6B-2D9F-2A88-7C596C59F4FC}.Release|Any CPU.Build.0 = Release|Any CPU - {BA45605A-1CCE-6B0C-489D-C113915B243F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {BA45605A-1CCE-6B0C-489D-C113915B243F}.Debug|Any CPU.Build.0 = Debug|Any CPU - {BA45605A-1CCE-6B0C-489D-C113915B243F}.Release|Any CPU.ActiveCfg = Release|Any CPU - {BA45605A-1CCE-6B0C-489D-C113915B243F}.Release|Any CPU.Build.0 = Release|Any CPU - {9D31FC8A-2A69-B78A-D3E5-4F867B16D971}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {9D31FC8A-2A69-B78A-D3E5-4F867B16D971}.Debug|Any CPU.Build.0 = Debug|Any CPU - {9D31FC8A-2A69-B78A-D3E5-4F867B16D971}.Release|Any CPU.ActiveCfg = Release|Any CPU - {9D31FC8A-2A69-B78A-D3E5-4F867B16D971}.Release|Any CPU.Build.0 = Release|Any CPU - {92268008-FBB0-C7AD-ECC2-7B75BED9F5E1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {92268008-FBB0-C7AD-ECC2-7B75BED9F5E1}.Debug|Any CPU.Build.0 = Debug|Any CPU - {92268008-FBB0-C7AD-ECC2-7B75BED9F5E1}.Release|Any CPU.ActiveCfg = Release|Any CPU - {92268008-FBB0-C7AD-ECC2-7B75BED9F5E1}.Release|Any CPU.Build.0 = Release|Any CPU - {8DCCAF70-D364-4C8B-4E90-AF65091DE0C5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {8DCCAF70-D364-4C8B-4E90-AF65091DE0C5}.Debug|Any CPU.Build.0 = Debug|Any CPU - {8DCCAF70-D364-4C8B-4E90-AF65091DE0C5}.Release|Any CPU.ActiveCfg = Release|Any CPU - {8DCCAF70-D364-4C8B-4E90-AF65091DE0C5}.Release|Any CPU.Build.0 = Release|Any CPU - {7828C164-DD01-2809-CCB3-364486834F60}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {7828C164-DD01-2809-CCB3-364486834F60}.Debug|Any CPU.Build.0 = Debug|Any CPU - {7828C164-DD01-2809-CCB3-364486834F60}.Release|Any CPU.ActiveCfg = Release|Any CPU - {7828C164-DD01-2809-CCB3-364486834F60}.Release|Any CPU.Build.0 = Release|Any CPU - {DE95E7B2-0937-A980-441F-829E023BC43E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {DE95E7B2-0937-A980-441F-829E023BC43E}.Debug|Any CPU.Build.0 = Debug|Any CPU - {DE95E7B2-0937-A980-441F-829E023BC43E}.Release|Any CPU.ActiveCfg = Release|Any CPU - {DE95E7B2-0937-A980-441F-829E023BC43E}.Release|Any CPU.Build.0 = Release|Any CPU - {91D69463-23E2-E2C7-AA7E-A78B13CED620}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {91D69463-23E2-E2C7-AA7E-A78B13CED620}.Debug|Any CPU.Build.0 = Debug|Any CPU - {91D69463-23E2-E2C7-AA7E-A78B13CED620}.Release|Any CPU.ActiveCfg = Release|Any CPU - {91D69463-23E2-E2C7-AA7E-A78B13CED620}.Release|Any CPU.Build.0 = Release|Any CPU - {34EFF636-81A7-8DF6-7CC9-4DA784BAC7F3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {34EFF636-81A7-8DF6-7CC9-4DA784BAC7F3}.Debug|Any CPU.Build.0 = Debug|Any CPU - {34EFF636-81A7-8DF6-7CC9-4DA784BAC7F3}.Release|Any CPU.ActiveCfg = Release|Any CPU - {34EFF636-81A7-8DF6-7CC9-4DA784BAC7F3}.Release|Any CPU.Build.0 = Release|Any CPU - {5DCF16A8-97C6-2CB4-6A63-0370239039EB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {5DCF16A8-97C6-2CB4-6A63-0370239039EB}.Debug|Any CPU.Build.0 = Debug|Any CPU - {5DCF16A8-97C6-2CB4-6A63-0370239039EB}.Release|Any CPU.ActiveCfg = Release|Any CPU - {5DCF16A8-97C6-2CB4-6A63-0370239039EB}.Release|Any CPU.Build.0 = Release|Any CPU - {EB093C48-CDAC-106B-1196-AE34809B34C0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {EB093C48-CDAC-106B-1196-AE34809B34C0}.Debug|Any CPU.Build.0 = Debug|Any CPU - {EB093C48-CDAC-106B-1196-AE34809B34C0}.Release|Any CPU.ActiveCfg = Release|Any CPU - {EB093C48-CDAC-106B-1196-AE34809B34C0}.Release|Any CPU.Build.0 = Release|Any CPU - {92C62F7B-8028-6EE1-B71B-F45F459B8E97}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {92C62F7B-8028-6EE1-B71B-F45F459B8E97}.Debug|Any CPU.Build.0 = Debug|Any CPU - {92C62F7B-8028-6EE1-B71B-F45F459B8E97}.Release|Any CPU.ActiveCfg = Release|Any CPU - {92C62F7B-8028-6EE1-B71B-F45F459B8E97}.Release|Any CPU.Build.0 = Release|Any CPU - {F664A948-E352-5808-E780-77A03F19E93E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {F664A948-E352-5808-E780-77A03F19E93E}.Debug|Any CPU.Build.0 = Debug|Any CPU - {F664A948-E352-5808-E780-77A03F19E93E}.Release|Any CPU.ActiveCfg = Release|Any CPU - {F664A948-E352-5808-E780-77A03F19E93E}.Release|Any CPU.Build.0 = Release|Any CPU - {FA83F778-5252-0B80-5555-E69F790322EA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {FA83F778-5252-0B80-5555-E69F790322EA}.Debug|Any CPU.Build.0 = Debug|Any CPU - {FA83F778-5252-0B80-5555-E69F790322EA}.Release|Any CPU.ActiveCfg = Release|Any CPU - {FA83F778-5252-0B80-5555-E69F790322EA}.Release|Any CPU.Build.0 = Release|Any CPU - {F3A27846-6DE0-3448-222C-25A273E86B2E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {F3A27846-6DE0-3448-222C-25A273E86B2E}.Debug|Any CPU.Build.0 = Debug|Any CPU - {F3A27846-6DE0-3448-222C-25A273E86B2E}.Release|Any CPU.ActiveCfg = Release|Any CPU - {F3A27846-6DE0-3448-222C-25A273E86B2E}.Release|Any CPU.Build.0 = Release|Any CPU - {166F4DEC-9886-92D5-6496-085664E9F08F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {166F4DEC-9886-92D5-6496-085664E9F08F}.Debug|Any CPU.Build.0 = Debug|Any CPU - {166F4DEC-9886-92D5-6496-085664E9F08F}.Release|Any CPU.ActiveCfg = Release|Any CPU - {166F4DEC-9886-92D5-6496-085664E9F08F}.Release|Any CPU.Build.0 = Release|Any CPU - {C53E0895-879A-D9E6-0A43-24AD17A2F270}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {C53E0895-879A-D9E6-0A43-24AD17A2F270}.Debug|Any CPU.Build.0 = Debug|Any CPU - {C53E0895-879A-D9E6-0A43-24AD17A2F270}.Release|Any CPU.ActiveCfg = Release|Any CPU - {C53E0895-879A-D9E6-0A43-24AD17A2F270}.Release|Any CPU.Build.0 = Release|Any CPU - {1EE42F0F-3F9A-613C-D01F-8BCDB4C42C0E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {1EE42F0F-3F9A-613C-D01F-8BCDB4C42C0E}.Debug|Any CPU.Build.0 = Debug|Any CPU - {1EE42F0F-3F9A-613C-D01F-8BCDB4C42C0E}.Release|Any CPU.ActiveCfg = Release|Any CPU - {1EE42F0F-3F9A-613C-D01F-8BCDB4C42C0E}.Release|Any CPU.Build.0 = Release|Any CPU - {246FCC7C-1437-742D-BAE5-E77A24164F08}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {246FCC7C-1437-742D-BAE5-E77A24164F08}.Debug|Any CPU.Build.0 = Debug|Any CPU - {246FCC7C-1437-742D-BAE5-E77A24164F08}.Release|Any CPU.ActiveCfg = Release|Any CPU - {246FCC7C-1437-742D-BAE5-E77A24164F08}.Release|Any CPU.Build.0 = Release|Any CPU - {0AED303F-69E6-238F-EF80-81985080EDB7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {0AED303F-69E6-238F-EF80-81985080EDB7}.Debug|Any CPU.Build.0 = Debug|Any CPU - {0AED303F-69E6-238F-EF80-81985080EDB7}.Release|Any CPU.ActiveCfg = Release|Any CPU - {0AED303F-69E6-238F-EF80-81985080EDB7}.Release|Any CPU.Build.0 = Release|Any CPU - {2904D288-CE64-A565-2C46-C2E85A96A1EE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {2904D288-CE64-A565-2C46-C2E85A96A1EE}.Debug|Any CPU.Build.0 = Debug|Any CPU - {2904D288-CE64-A565-2C46-C2E85A96A1EE}.Release|Any CPU.ActiveCfg = Release|Any CPU - {2904D288-CE64-A565-2C46-C2E85A96A1EE}.Release|Any CPU.Build.0 = Release|Any CPU - {A6667CC3-B77F-023E-3A67-05F99E9FF46A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {A6667CC3-B77F-023E-3A67-05F99E9FF46A}.Debug|Any CPU.Build.0 = Debug|Any CPU - {A6667CC3-B77F-023E-3A67-05F99E9FF46A}.Release|Any CPU.ActiveCfg = Release|Any CPU - {A6667CC3-B77F-023E-3A67-05F99E9FF46A}.Release|Any CPU.Build.0 = Release|Any CPU - {A26E2816-F787-F76B-1D6C-E086DD3E19CE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {A26E2816-F787-F76B-1D6C-E086DD3E19CE}.Debug|Any CPU.Build.0 = Debug|Any CPU - {A26E2816-F787-F76B-1D6C-E086DD3E19CE}.Release|Any CPU.ActiveCfg = Release|Any CPU - {A26E2816-F787-F76B-1D6C-E086DD3E19CE}.Release|Any CPU.Build.0 = Release|Any CPU - {B3DEC619-67AC-1B5A-4F3E-A1F24C3F6877}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {B3DEC619-67AC-1B5A-4F3E-A1F24C3F6877}.Debug|Any CPU.Build.0 = Debug|Any CPU - {B3DEC619-67AC-1B5A-4F3E-A1F24C3F6877}.Release|Any CPU.ActiveCfg = Release|Any CPU - {B3DEC619-67AC-1B5A-4F3E-A1F24C3F6877}.Release|Any CPU.Build.0 = Release|Any CPU - {90DB65B4-8F6E-FB8E-0281-505AD8BC6BA6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {90DB65B4-8F6E-FB8E-0281-505AD8BC6BA6}.Debug|Any CPU.Build.0 = Debug|Any CPU - {90DB65B4-8F6E-FB8E-0281-505AD8BC6BA6}.Release|Any CPU.ActiveCfg = Release|Any CPU - {90DB65B4-8F6E-FB8E-0281-505AD8BC6BA6}.Release|Any CPU.Build.0 = Release|Any CPU - {059FBB86-DEE6-8207-3F23-2A1A3EC00DEA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {059FBB86-DEE6-8207-3F23-2A1A3EC00DEA}.Debug|Any CPU.Build.0 = Debug|Any CPU - {059FBB86-DEE6-8207-3F23-2A1A3EC00DEA}.Release|Any CPU.ActiveCfg = Release|Any CPU - {059FBB86-DEE6-8207-3F23-2A1A3EC00DEA}.Release|Any CPU.Build.0 = Release|Any CPU - {8BBA3159-C4CC-F685-A28C-7FE6CBD3D2A1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {8BBA3159-C4CC-F685-A28C-7FE6CBD3D2A1}.Debug|Any CPU.Build.0 = Debug|Any CPU - {8BBA3159-C4CC-F685-A28C-7FE6CBD3D2A1}.Release|Any CPU.ActiveCfg = Release|Any CPU - {8BBA3159-C4CC-F685-A28C-7FE6CBD3D2A1}.Release|Any CPU.Build.0 = Release|Any CPU - {EA0974E3-CD2B-5792-EF1E-9B5B7CCBDF00}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {EA0974E3-CD2B-5792-EF1E-9B5B7CCBDF00}.Debug|Any CPU.Build.0 = Debug|Any CPU - {EA0974E3-CD2B-5792-EF1E-9B5B7CCBDF00}.Release|Any CPU.ActiveCfg = Release|Any CPU - {EA0974E3-CD2B-5792-EF1E-9B5B7CCBDF00}.Release|Any CPU.Build.0 = Release|Any CPU - {632A1F0D-1BA5-C84B-B716-2BE638A92780}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {632A1F0D-1BA5-C84B-B716-2BE638A92780}.Debug|Any CPU.Build.0 = Debug|Any CPU - {632A1F0D-1BA5-C84B-B716-2BE638A92780}.Release|Any CPU.ActiveCfg = Release|Any CPU - {632A1F0D-1BA5-C84B-B716-2BE638A92780}.Release|Any CPU.Build.0 = Release|Any CPU - {9DE7852B-7E2D-257E-B0F1-45D2687854ED}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {9DE7852B-7E2D-257E-B0F1-45D2687854ED}.Debug|Any CPU.Build.0 = Debug|Any CPU - {9DE7852B-7E2D-257E-B0F1-45D2687854ED}.Release|Any CPU.ActiveCfg = Release|Any CPU - {9DE7852B-7E2D-257E-B0F1-45D2687854ED}.Release|Any CPU.Build.0 = Release|Any CPU - {DC2AFC89-C3C8-4E9B-13A7-027EB6386EFA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {DC2AFC89-C3C8-4E9B-13A7-027EB6386EFA}.Debug|Any CPU.Build.0 = Debug|Any CPU - {DC2AFC89-C3C8-4E9B-13A7-027EB6386EFA}.Release|Any CPU.ActiveCfg = Release|Any CPU - {DC2AFC89-C3C8-4E9B-13A7-027EB6386EFA}.Release|Any CPU.Build.0 = Release|Any CPU - {9151601C-8784-01A6-C2E7-A5C0FAAB0AEF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {9151601C-8784-01A6-C2E7-A5C0FAAB0AEF}.Debug|Any CPU.Build.0 = Debug|Any CPU - {9151601C-8784-01A6-C2E7-A5C0FAAB0AEF}.Release|Any CPU.ActiveCfg = Release|Any CPU - {9151601C-8784-01A6-C2E7-A5C0FAAB0AEF}.Release|Any CPU.Build.0 = Release|Any CPU - {4F1EE2D9-9392-6A1C-7224-6B01FAB934E3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {4F1EE2D9-9392-6A1C-7224-6B01FAB934E3}.Debug|Any CPU.Build.0 = Debug|Any CPU - {4F1EE2D9-9392-6A1C-7224-6B01FAB934E3}.Release|Any CPU.ActiveCfg = Release|Any CPU - {4F1EE2D9-9392-6A1C-7224-6B01FAB934E3}.Release|Any CPU.Build.0 = Release|Any CPU - {104A930A-6D8F-8C36-2CB5-0BC4F8FD74D2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {104A930A-6D8F-8C36-2CB5-0BC4F8FD74D2}.Debug|Any CPU.Build.0 = Debug|Any CPU - {104A930A-6D8F-8C36-2CB5-0BC4F8FD74D2}.Release|Any CPU.ActiveCfg = Release|Any CPU - {104A930A-6D8F-8C36-2CB5-0BC4F8FD74D2}.Release|Any CPU.Build.0 = Release|Any CPU - {F7947A80-F07C-2FBF-77F8-DDFA57951A97}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {F7947A80-F07C-2FBF-77F8-DDFA57951A97}.Debug|Any CPU.Build.0 = Debug|Any CPU - {F7947A80-F07C-2FBF-77F8-DDFA57951A97}.Release|Any CPU.ActiveCfg = Release|Any CPU - {F7947A80-F07C-2FBF-77F8-DDFA57951A97}.Release|Any CPU.Build.0 = Release|Any CPU - {CB296A20-2732-77C1-7F23-27D5BAEDD0C7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {CB296A20-2732-77C1-7F23-27D5BAEDD0C7}.Debug|Any CPU.Build.0 = Debug|Any CPU - {CB296A20-2732-77C1-7F23-27D5BAEDD0C7}.Release|Any CPU.ActiveCfg = Release|Any CPU - {CB296A20-2732-77C1-7F23-27D5BAEDD0C7}.Release|Any CPU.Build.0 = Release|Any CPU - {0DBEC9BA-FE1D-3898-B2C6-E4357DC23E0F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {0DBEC9BA-FE1D-3898-B2C6-E4357DC23E0F}.Debug|Any CPU.Build.0 = Debug|Any CPU - {0DBEC9BA-FE1D-3898-B2C6-E4357DC23E0F}.Release|Any CPU.ActiveCfg = Release|Any CPU - {0DBEC9BA-FE1D-3898-B2C6-E4357DC23E0F}.Release|Any CPU.Build.0 = Release|Any CPU - {A63897D9-9531-989B-7309-E384BCFC2BB9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {A63897D9-9531-989B-7309-E384BCFC2BB9}.Debug|Any CPU.Build.0 = Debug|Any CPU - {A63897D9-9531-989B-7309-E384BCFC2BB9}.Release|Any CPU.ActiveCfg = Release|Any CPU - {A63897D9-9531-989B-7309-E384BCFC2BB9}.Release|Any CPU.Build.0 = Release|Any CPU - {8C594D82-3463-3367-4F06-900AC707753D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {8C594D82-3463-3367-4F06-900AC707753D}.Debug|Any CPU.Build.0 = Debug|Any CPU - {8C594D82-3463-3367-4F06-900AC707753D}.Release|Any CPU.ActiveCfg = Release|Any CPU - {8C594D82-3463-3367-4F06-900AC707753D}.Release|Any CPU.Build.0 = Release|Any CPU - {9588FBF9-C37E-D16E-2E8F-CFA226EAC01D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {9588FBF9-C37E-D16E-2E8F-CFA226EAC01D}.Debug|Any CPU.Build.0 = Debug|Any CPU - {9588FBF9-C37E-D16E-2E8F-CFA226EAC01D}.Release|Any CPU.ActiveCfg = Release|Any CPU - {9588FBF9-C37E-D16E-2E8F-CFA226EAC01D}.Release|Any CPU.Build.0 = Release|Any CPU - {97998C88-E6E1-D5E2-B632-537B58E00CBF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {97998C88-E6E1-D5E2-B632-537B58E00CBF}.Debug|Any CPU.Build.0 = Debug|Any CPU - {97998C88-E6E1-D5E2-B632-537B58E00CBF}.Release|Any CPU.ActiveCfg = Release|Any CPU - {97998C88-E6E1-D5E2-B632-537B58E00CBF}.Release|Any CPU.Build.0 = Release|Any CPU - {20D1569C-2A47-38B8-075E-47225B674394}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {20D1569C-2A47-38B8-075E-47225B674394}.Debug|Any CPU.Build.0 = Debug|Any CPU - {20D1569C-2A47-38B8-075E-47225B674394}.Release|Any CPU.ActiveCfg = Release|Any CPU - {20D1569C-2A47-38B8-075E-47225B674394}.Release|Any CPU.Build.0 = Release|Any CPU - {2F7AA715-25AE-086A-7DF4-CAB5EF00E2B7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {2F7AA715-25AE-086A-7DF4-CAB5EF00E2B7}.Debug|Any CPU.Build.0 = Debug|Any CPU - {2F7AA715-25AE-086A-7DF4-CAB5EF00E2B7}.Release|Any CPU.ActiveCfg = Release|Any CPU - {2F7AA715-25AE-086A-7DF4-CAB5EF00E2B7}.Release|Any CPU.Build.0 = Release|Any CPU - {38A9EE9B-6FC8-93BC-0D43-2A906E678D66}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {38A9EE9B-6FC8-93BC-0D43-2A906E678D66}.Debug|Any CPU.Build.0 = Debug|Any CPU - {38A9EE9B-6FC8-93BC-0D43-2A906E678D66}.Release|Any CPU.ActiveCfg = Release|Any CPU - {38A9EE9B-6FC8-93BC-0D43-2A906E678D66}.Release|Any CPU.Build.0 = Release|Any CPU - {19868E2D-7163-2108-1094-F13887C4F070}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {19868E2D-7163-2108-1094-F13887C4F070}.Debug|Any CPU.Build.0 = Debug|Any CPU - {19868E2D-7163-2108-1094-F13887C4F070}.Release|Any CPU.ActiveCfg = Release|Any CPU - {19868E2D-7163-2108-1094-F13887C4F070}.Release|Any CPU.Build.0 = Release|Any CPU - {7D3FC972-467A-4917-8339-9B6462C6A38A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {7D3FC972-467A-4917-8339-9B6462C6A38A}.Debug|Any CPU.Build.0 = Debug|Any CPU - {7D3FC972-467A-4917-8339-9B6462C6A38A}.Release|Any CPU.ActiveCfg = Release|Any CPU - {7D3FC972-467A-4917-8339-9B6462C6A38A}.Release|Any CPU.Build.0 = Release|Any CPU - {C154051B-DB4E-5270-AF5A-12A0FFE0E769}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {C154051B-DB4E-5270-AF5A-12A0FFE0E769}.Debug|Any CPU.Build.0 = Debug|Any CPU - {C154051B-DB4E-5270-AF5A-12A0FFE0E769}.Release|Any CPU.ActiveCfg = Release|Any CPU - {C154051B-DB4E-5270-AF5A-12A0FFE0E769}.Release|Any CPU.Build.0 = Release|Any CPU - {CC319FC5-F4B1-C3DD-7310-4DAD343E0125}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {CC319FC5-F4B1-C3DD-7310-4DAD343E0125}.Debug|Any CPU.Build.0 = Debug|Any CPU - {CC319FC5-F4B1-C3DD-7310-4DAD343E0125}.Release|Any CPU.ActiveCfg = Release|Any CPU - {CC319FC5-F4B1-C3DD-7310-4DAD343E0125}.Release|Any CPU.Build.0 = Release|Any CPU - {CD6B144E-BCDD-D4FE-2749-703DAB054EBC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {CD6B144E-BCDD-D4FE-2749-703DAB054EBC}.Debug|Any CPU.Build.0 = Debug|Any CPU - {CD6B144E-BCDD-D4FE-2749-703DAB054EBC}.Release|Any CPU.ActiveCfg = Release|Any CPU - {CD6B144E-BCDD-D4FE-2749-703DAB054EBC}.Release|Any CPU.Build.0 = Release|Any CPU - {B46D185B-A630-8F76-E61B-90084FBF65B0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {B46D185B-A630-8F76-E61B-90084FBF65B0}.Debug|Any CPU.Build.0 = Debug|Any CPU - {B46D185B-A630-8F76-E61B-90084FBF65B0}.Release|Any CPU.ActiveCfg = Release|Any CPU - {B46D185B-A630-8F76-E61B-90084FBF65B0}.Release|Any CPU.Build.0 = Release|Any CPU - {84F711C2-C210-28D2-F0D9-B13733FEE23D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {84F711C2-C210-28D2-F0D9-B13733FEE23D}.Debug|Any CPU.Build.0 = Debug|Any CPU - {84F711C2-C210-28D2-F0D9-B13733FEE23D}.Release|Any CPU.ActiveCfg = Release|Any CPU - {84F711C2-C210-28D2-F0D9-B13733FEE23D}.Release|Any CPU.Build.0 = Release|Any CPU - {CBB14B90-27F9-8DD6-DFC4-3507DBD1FBC6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {CBB14B90-27F9-8DD6-DFC4-3507DBD1FBC6}.Debug|Any CPU.Build.0 = Debug|Any CPU - {CBB14B90-27F9-8DD6-DFC4-3507DBD1FBC6}.Release|Any CPU.ActiveCfg = Release|Any CPU - {CBB14B90-27F9-8DD6-DFC4-3507DBD1FBC6}.Release|Any CPU.Build.0 = Release|Any CPU - {A78EBC0F-C62C-8F56-95C0-330E376242A2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {A78EBC0F-C62C-8F56-95C0-330E376242A2}.Debug|Any CPU.Build.0 = Debug|Any CPU - {A78EBC0F-C62C-8F56-95C0-330E376242A2}.Release|Any CPU.ActiveCfg = Release|Any CPU - {A78EBC0F-C62C-8F56-95C0-330E376242A2}.Release|Any CPU.Build.0 = Release|Any CPU - {6D26FB21-7E48-024B-E5D4-E3F0F31976BB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {6D26FB21-7E48-024B-E5D4-E3F0F31976BB}.Debug|Any CPU.Build.0 = Debug|Any CPU - {6D26FB21-7E48-024B-E5D4-E3F0F31976BB}.Release|Any CPU.ActiveCfg = Release|Any CPU - {6D26FB21-7E48-024B-E5D4-E3F0F31976BB}.Release|Any CPU.Build.0 = Release|Any CPU - {28D91816-206C-576E-1A83-FD98E08C2E3C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {28D91816-206C-576E-1A83-FD98E08C2E3C}.Debug|Any CPU.Build.0 = Debug|Any CPU - {28D91816-206C-576E-1A83-FD98E08C2E3C}.Release|Any CPU.ActiveCfg = Release|Any CPU - {28D91816-206C-576E-1A83-FD98E08C2E3C}.Release|Any CPU.Build.0 = Release|Any CPU - {5EFEC79C-A9F1-96A4-692C-733566107170}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {5EFEC79C-A9F1-96A4-692C-733566107170}.Debug|Any CPU.Build.0 = Debug|Any CPU - {5EFEC79C-A9F1-96A4-692C-733566107170}.Release|Any CPU.ActiveCfg = Release|Any CPU - {5EFEC79C-A9F1-96A4-692C-733566107170}.Release|Any CPU.Build.0 = Release|Any CPU - {B7B5D764-C3A0-1743-0739-29966F993626}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {B7B5D764-C3A0-1743-0739-29966F993626}.Debug|Any CPU.Build.0 = Debug|Any CPU - {B7B5D764-C3A0-1743-0739-29966F993626}.Release|Any CPU.ActiveCfg = Release|Any CPU - {B7B5D764-C3A0-1743-0739-29966F993626}.Release|Any CPU.Build.0 = Release|Any CPU - {C4EDBBAF-875C-4839-05A8-F6F12A5ED52D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {C4EDBBAF-875C-4839-05A8-F6F12A5ED52D}.Debug|Any CPU.Build.0 = Debug|Any CPU - {C4EDBBAF-875C-4839-05A8-F6F12A5ED52D}.Release|Any CPU.ActiveCfg = Release|Any CPU - {C4EDBBAF-875C-4839-05A8-F6F12A5ED52D}.Release|Any CPU.Build.0 = Release|Any CPU - {0EAC8F64-9588-1EF0-C33A-67590CF27590}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {0EAC8F64-9588-1EF0-C33A-67590CF27590}.Debug|Any CPU.Build.0 = Debug|Any CPU - {0EAC8F64-9588-1EF0-C33A-67590CF27590}.Release|Any CPU.ActiveCfg = Release|Any CPU - {0EAC8F64-9588-1EF0-C33A-67590CF27590}.Release|Any CPU.Build.0 = Release|Any CPU - {B1B31937-CCC8-D97A-F66D-1849734B780B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {B1B31937-CCC8-D97A-F66D-1849734B780B}.Debug|Any CPU.Build.0 = Debug|Any CPU - {B1B31937-CCC8-D97A-F66D-1849734B780B}.Release|Any CPU.ActiveCfg = Release|Any CPU - {B1B31937-CCC8-D97A-F66D-1849734B780B}.Release|Any CPU.Build.0 = Release|Any CPU - {A345E5AC-BDDB-A817-3C92-08C8865D1EF9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {A345E5AC-BDDB-A817-3C92-08C8865D1EF9}.Debug|Any CPU.Build.0 = Debug|Any CPU - {A345E5AC-BDDB-A817-3C92-08C8865D1EF9}.Release|Any CPU.ActiveCfg = Release|Any CPU - {A345E5AC-BDDB-A817-3C92-08C8865D1EF9}.Release|Any CPU.Build.0 = Release|Any CPU - {58D8630F-C0F4-B772-8572-BCC98FF0F0D8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {58D8630F-C0F4-B772-8572-BCC98FF0F0D8}.Debug|Any CPU.Build.0 = Debug|Any CPU - {58D8630F-C0F4-B772-8572-BCC98FF0F0D8}.Release|Any CPU.ActiveCfg = Release|Any CPU - {58D8630F-C0F4-B772-8572-BCC98FF0F0D8}.Release|Any CPU.Build.0 = Release|Any CPU - {D24E7862-3930-A4F6-1DFA-DA88C759546C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {D24E7862-3930-A4F6-1DFA-DA88C759546C}.Debug|Any CPU.Build.0 = Debug|Any CPU - {D24E7862-3930-A4F6-1DFA-DA88C759546C}.Release|Any CPU.ActiveCfg = Release|Any CPU - {D24E7862-3930-A4F6-1DFA-DA88C759546C}.Release|Any CPU.Build.0 = Release|Any CPU - {7CB7FEA8-8A12-A5D6-0057-AA65DB328617}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {7CB7FEA8-8A12-A5D6-0057-AA65DB328617}.Debug|Any CPU.Build.0 = Debug|Any CPU - {7CB7FEA8-8A12-A5D6-0057-AA65DB328617}.Release|Any CPU.ActiveCfg = Release|Any CPU - {7CB7FEA8-8A12-A5D6-0057-AA65DB328617}.Release|Any CPU.Build.0 = Release|Any CPU - {52698305-D6F8-C13C-0882-48FC37726404}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {52698305-D6F8-C13C-0882-48FC37726404}.Debug|Any CPU.Build.0 = Debug|Any CPU - {52698305-D6F8-C13C-0882-48FC37726404}.Release|Any CPU.ActiveCfg = Release|Any CPU - {52698305-D6F8-C13C-0882-48FC37726404}.Release|Any CPU.Build.0 = Release|Any CPU - {5567139C-0365-B6A0-5DD0-978A09B9F176}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {5567139C-0365-B6A0-5DD0-978A09B9F176}.Debug|Any CPU.Build.0 = Debug|Any CPU - {5567139C-0365-B6A0-5DD0-978A09B9F176}.Release|Any CPU.ActiveCfg = Release|Any CPU - {5567139C-0365-B6A0-5DD0-978A09B9F176}.Release|Any CPU.Build.0 = Release|Any CPU - {256D269B-35EA-F833-2F1D-8E0058908DEE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {256D269B-35EA-F833-2F1D-8E0058908DEE}.Debug|Any CPU.Build.0 = Debug|Any CPU - {256D269B-35EA-F833-2F1D-8E0058908DEE}.Release|Any CPU.ActiveCfg = Release|Any CPU - {256D269B-35EA-F833-2F1D-8E0058908DEE}.Release|Any CPU.Build.0 = Release|Any CPU - {6E9C9582-67FA-2EB1-C6BA-AD4CD326E276}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {6E9C9582-67FA-2EB1-C6BA-AD4CD326E276}.Debug|Any CPU.Build.0 = Debug|Any CPU - {6E9C9582-67FA-2EB1-C6BA-AD4CD326E276}.Release|Any CPU.ActiveCfg = Release|Any CPU - {6E9C9582-67FA-2EB1-C6BA-AD4CD326E276}.Release|Any CPU.Build.0 = Release|Any CPU - {1F372AB9-D8DD-D295-1D5E-CB5D454CBB24}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {1F372AB9-D8DD-D295-1D5E-CB5D454CBB24}.Debug|Any CPU.Build.0 = Debug|Any CPU - {1F372AB9-D8DD-D295-1D5E-CB5D454CBB24}.Release|Any CPU.ActiveCfg = Release|Any CPU - {1F372AB9-D8DD-D295-1D5E-CB5D454CBB24}.Release|Any CPU.Build.0 = Release|Any CPU - {D96DA724-3A66-14E2-D6CC-F65CEEE71069}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {D96DA724-3A66-14E2-D6CC-F65CEEE71069}.Debug|Any CPU.Build.0 = Debug|Any CPU - {D96DA724-3A66-14E2-D6CC-F65CEEE71069}.Release|Any CPU.ActiveCfg = Release|Any CPU - {D96DA724-3A66-14E2-D6CC-F65CEEE71069}.Release|Any CPU.Build.0 = Release|Any CPU - {0AF13355-173C-3128-5AFC-D32E540DA3EF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {0AF13355-173C-3128-5AFC-D32E540DA3EF}.Debug|Any CPU.Build.0 = Debug|Any CPU - {0AF13355-173C-3128-5AFC-D32E540DA3EF}.Release|Any CPU.ActiveCfg = Release|Any CPU - {0AF13355-173C-3128-5AFC-D32E540DA3EF}.Release|Any CPU.Build.0 = Release|Any CPU - {06BC00C6-78D4-05AD-C8C8-FF64CD7968E0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {06BC00C6-78D4-05AD-C8C8-FF64CD7968E0}.Debug|Any CPU.Build.0 = Debug|Any CPU - {06BC00C6-78D4-05AD-C8C8-FF64CD7968E0}.Release|Any CPU.ActiveCfg = Release|Any CPU - {06BC00C6-78D4-05AD-C8C8-FF64CD7968E0}.Release|Any CPU.Build.0 = Release|Any CPU - {FFC170B2-A6F0-A1D7-02BD-16D813C8C8C0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {FFC170B2-A6F0-A1D7-02BD-16D813C8C8C0}.Debug|Any CPU.Build.0 = Debug|Any CPU - {FFC170B2-A6F0-A1D7-02BD-16D813C8C8C0}.Release|Any CPU.ActiveCfg = Release|Any CPU - {FFC170B2-A6F0-A1D7-02BD-16D813C8C8C0}.Release|Any CPU.Build.0 = Release|Any CPU - {85B8B27B-51DD-025E-EEED-D44BC0D318B8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {85B8B27B-51DD-025E-EEED-D44BC0D318B8}.Debug|Any CPU.Build.0 = Debug|Any CPU - {85B8B27B-51DD-025E-EEED-D44BC0D318B8}.Release|Any CPU.ActiveCfg = Release|Any CPU - {85B8B27B-51DD-025E-EEED-D44BC0D318B8}.Release|Any CPU.Build.0 = Release|Any CPU - {AF043113-CCE3-59C1-DF71-9804155F26A8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {AF043113-CCE3-59C1-DF71-9804155F26A8}.Debug|Any CPU.Build.0 = Debug|Any CPU - {AF043113-CCE3-59C1-DF71-9804155F26A8}.Release|Any CPU.ActiveCfg = Release|Any CPU - {AF043113-CCE3-59C1-DF71-9804155F26A8}.Release|Any CPU.Build.0 = Release|Any CPU - {9222D186-CD9F-C783-AED5-A3B0E48623BD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {9222D186-CD9F-C783-AED5-A3B0E48623BD}.Debug|Any CPU.Build.0 = Debug|Any CPU - {9222D186-CD9F-C783-AED5-A3B0E48623BD}.Release|Any CPU.ActiveCfg = Release|Any CPU - {9222D186-CD9F-C783-AED5-A3B0E48623BD}.Release|Any CPU.Build.0 = Release|Any CPU - {10588F6A-E13D-98DC-4EC9-917DCEE382EE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {10588F6A-E13D-98DC-4EC9-917DCEE382EE}.Debug|Any CPU.Build.0 = Debug|Any CPU - {10588F6A-E13D-98DC-4EC9-917DCEE382EE}.Release|Any CPU.ActiveCfg = Release|Any CPU - {10588F6A-E13D-98DC-4EC9-917DCEE382EE}.Release|Any CPU.Build.0 = Release|Any CPU - {E62C8F14-A7CF-47DF-8D60-77308D5D0647}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {E62C8F14-A7CF-47DF-8D60-77308D5D0647}.Debug|Any CPU.Build.0 = Debug|Any CPU - {E62C8F14-A7CF-47DF-8D60-77308D5D0647}.Release|Any CPU.ActiveCfg = Release|Any CPU - {E62C8F14-A7CF-47DF-8D60-77308D5D0647}.Release|Any CPU.Build.0 = Release|Any CPU - {1D761F8B-921C-53BF-DCF5-5ABD329EEB0C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {1D761F8B-921C-53BF-DCF5-5ABD329EEB0C}.Debug|Any CPU.Build.0 = Debug|Any CPU - {1D761F8B-921C-53BF-DCF5-5ABD329EEB0C}.Release|Any CPU.ActiveCfg = Release|Any CPU - {1D761F8B-921C-53BF-DCF5-5ABD329EEB0C}.Release|Any CPU.Build.0 = Release|Any CPU - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(NestedProjects) = preSolution - {F310596E-88BB-9E54-885E-21C61971917E} = {5B52EF8A-3661-DCFF-797D-BC4D6AC60BDA} - {EA6E5683-3A20-2E52-1CE6-AE0D6D36AC4D} = {F310596E-88BB-9E54-885E-21C61971917E} - {D9492ED1-A812-924B-65E4-F518592B49BB} = {F310596E-88BB-9E54-885E-21C61971917E} - {3823DE1E-2ACE-C956-99E1-00DB786D9E1D} = {D9492ED1-A812-924B-65E4-F518592B49BB} - {03DFF14F-7321-1784-D4C7-4E99D4120F48} = {5B52EF8A-3661-DCFF-797D-BC4D6AC60BDA} - {BDD326D6-7616-84F0-B914-74743BFBA520} = {03DFF14F-7321-1784-D4C7-4E99D4120F48} - {EC506DBE-AB6D-492E-786E-8B176021BF2E} = {BDD326D6-7616-84F0-B914-74743BFBA520} - {5AC09D9A-F2A5-9CFA-B3C5-8D25F257651C} = {5B52EF8A-3661-DCFF-797D-BC4D6AC60BDA} - {0B71A5C2-A1C9-BB93-6042-23D1CEE5AD68} = {5AC09D9A-F2A5-9CFA-B3C5-8D25F257651C} - {33B1AE27-692A-1778-48C1-CCEC2B9BC78F} = {5AC09D9A-F2A5-9CFA-B3C5-8D25F257651C} - {018E0E11-1CCE-A2BE-641D-21EE14D2E90D} = {5AC09D9A-F2A5-9CFA-B3C5-8D25F257651C} - {5F27FB4E-CF09-3A6B-F5B4-BF5A709FA609} = {33B1AE27-692A-1778-48C1-CCEC2B9BC78F} - {AB67BDB9-D701-3AC9-9CDF-ECCDCCD8DB6D} = {5AC09D9A-F2A5-9CFA-B3C5-8D25F257651C} - {3F605548-87E2-8A1D-306D-0CE6960B8242} = {AB67BDB9-D701-3AC9-9CDF-ECCDCCD8DB6D} - {45F7FA87-7451-6970-7F6E-F8BAE45E081B} = {AB67BDB9-D701-3AC9-9CDF-ECCDCCD8DB6D} - {C1DCEFBD-12A5-EAAE-632E-8EEB9BE491B6} = {5B52EF8A-3661-DCFF-797D-BC4D6AC60BDA} - {A6928CBA-4D4D-AB2B-CA19-FEE6E73ECE70} = {C1DCEFBD-12A5-EAAE-632E-8EEB9BE491B6} - {F2E6CB0E-DF77-1FAA-582B-62B040DF3848} = {A6928CBA-4D4D-AB2B-CA19-FEE6E73ECE70} - {C494ECBE-DEA5-3576-D2AF-200FF12BC144} = {A6928CBA-4D4D-AB2B-CA19-FEE6E73ECE70} - {64689413-46D7-8499-68A6-B6367ACBC597} = {A6928CBA-4D4D-AB2B-CA19-FEE6E73ECE70} - {5827F4DE-0AA7-FC85-641D-09E3D890DB27} = {C1DCEFBD-12A5-EAAE-632E-8EEB9BE491B6} - {9BD75659-58CB-06D1-E198-C39007E82C6A} = {5827F4DE-0AA7-FC85-641D-09E3D890DB27} - {7BF13935-F1DD-D23B-8347-DB1550C69D69} = {5827F4DE-0AA7-FC85-641D-09E3D890DB27} - {157C3671-CA0B-69FA-A7C9-74A1FDA97B99} = {5B52EF8A-3661-DCFF-797D-BC4D6AC60BDA} - {F39E09D6-BF93-B64A-CFE7-2BA92815C0FE} = {157C3671-CA0B-69FA-A7C9-74A1FDA97B99} - {39EFDA5B-F5EE-8212-D5BA-90E1B82013E7} = {F39E09D6-BF93-B64A-CFE7-2BA92815C0FE} - {6844B539-C2A3-9D4F-139D-9D533BCABADA} = {F39E09D6-BF93-B64A-CFE7-2BA92815C0FE} - {4263AA71-0335-3F44-9A9B-423C3A3D05E6} = {F39E09D6-BF93-B64A-CFE7-2BA92815C0FE} - {F1B1DB47-D2D7-59CB-679B-23E4928E8328} = {F39E09D6-BF93-B64A-CFE7-2BA92815C0FE} - {BC35DE94-4F04-3436-27A3-F11647FEDD5C} = {F39E09D6-BF93-B64A-CFE7-2BA92815C0FE} - {864C8B80-771A-0C15-30A5-558F99006E0D} = {F39E09D6-BF93-B64A-CFE7-2BA92815C0FE} - {603E7A23-1D6B-D3A9-B0E6-3E332B13ED5C} = {F39E09D6-BF93-B64A-CFE7-2BA92815C0FE} - {D2F7E58B-47D4-5205-D917-144CA1CFF4F1} = {F39E09D6-BF93-B64A-CFE7-2BA92815C0FE} - {1DCF4EBB-DBC4-752C-13D4-D1EECE4E8907} = {F39E09D6-BF93-B64A-CFE7-2BA92815C0FE} - {1B37A859-E733-60CB-4806-1A24B6F10E05} = {F39E09D6-BF93-B64A-CFE7-2BA92815C0FE} - {F2B58F4E-6F28-A25F-5BFB-CDEBAD6B9A3E} = {F39E09D6-BF93-B64A-CFE7-2BA92815C0FE} - {7D49FA52-6EA1-EAC8-4C5A-AC07188D6C57} = {5B52EF8A-3661-DCFF-797D-BC4D6AC60BDA} - {C9CF27FC-12DB-954F-863C-576BA8E309A5} = {7D49FA52-6EA1-EAC8-4C5A-AC07188D6C57} - {6DCAF6F3-717F-27A9-D96C-F2BFA5550347} = {C9CF27FC-12DB-954F-863C-576BA8E309A5} - {83791804-2407-CC2B-34AD-ED8FFAAF3257} = {C9CF27FC-12DB-954F-863C-576BA8E309A5} - {8E933B6D-39AB-871C-33D6-E57984AA38BA} = {5B52EF8A-3661-DCFF-797D-BC4D6AC60BDA} - {84C61393-D449-22D3-FA3B-75F7256384E9} = {8E933B6D-39AB-871C-33D6-E57984AA38BA} - {48007FB6-A895-4ED1-E1AE-E0806BCFFF96} = {84C61393-D449-22D3-FA3B-75F7256384E9} - {09DD25DA-BBB0-5D9D-A372-751855D00AF0} = {84C61393-D449-22D3-FA3B-75F7256384E9} - {C4A90603-BE42-0044-CAB4-3EB910AD51A5} = {5B52EF8A-3661-DCFF-797D-BC4D6AC60BDA} - {054761F9-16D3-B2F8-6F4D-EFC2248805CD} = {C4A90603-BE42-0044-CAB4-3EB910AD51A5} - {B54CE64C-4167-1DD1-B7D6-2FD7A5AEF715} = {C4A90603-BE42-0044-CAB4-3EB910AD51A5} - {D2162FEA-AFA4-2A88-6444-2F6D845260BB} = {5B52EF8A-3661-DCFF-797D-BC4D6AC60BDA} - {63EAEA3B-ADC9-631D-774E-7AA04490EDDD} = {D2162FEA-AFA4-2A88-6444-2F6D845260BB} - {B0F64757-F7A7-1A11-8DEC-BAC72EB5EC29} = {63EAEA3B-ADC9-631D-774E-7AA04490EDDD} - {C5F86BAD-155A-591C-9610-55D40F59C775} = {63EAEA3B-ADC9-631D-774E-7AA04490EDDD} - {8E6B774C-CC4E-CE7C-AD4B-8AF7C92889A6} = {5B52EF8A-3661-DCFF-797D-BC4D6AC60BDA} - {BC12ED55-6015-7C8B-8384-B39CE93C76D6} = {8E6B774C-CC4E-CE7C-AD4B-8AF7C92889A6} - {7DE09F4B-E86D-CEA4-EC36-364CC9CCD2A6} = {8E6B774C-CC4E-CE7C-AD4B-8AF7C92889A6} - {BA20548F-5ADA-BE63-1AE7-BA12CB4E82B3} = {8E6B774C-CC4E-CE7C-AD4B-8AF7C92889A6} - {FF70543D-AFF9-1D38-4950-4F8EE18D60BB} = {8E6B774C-CC4E-CE7C-AD4B-8AF7C92889A6} - {831265B0-8896-9C95-3488-E12FD9F6DC53} = {FF70543D-AFF9-1D38-4950-4F8EE18D60BB} - {97579A99-E7BE-9189-9B9A-CA0EBB5E9C97} = {FF70543D-AFF9-1D38-4950-4F8EE18D60BB} - {F3131BAC-FF6E-FBF1-1A59-74B89427DFE6} = {FF70543D-AFF9-1D38-4950-4F8EE18D60BB} - {316BBD0A-04D2-85C9-52EA-7993CC6C8930} = {5B52EF8A-3661-DCFF-797D-BC4D6AC60BDA} - {9D6AB85A-85EA-D85A-5566-A121D34016E6} = {316BBD0A-04D2-85C9-52EA-7993CC6C8930} - {FC018E5B-1E2F-DE19-1E97-0C845058C469} = {5B52EF8A-3661-DCFF-797D-BC4D6AC60BDA} - {1BE5B76C-B486-560B-6CB2-44C6537249AA} = {FC018E5B-1E2F-DE19-1E97-0C845058C469} - {F4F1CBE2-1CDD-CAA4-41F0-266DB4677C05} = {1BE5B76C-B486-560B-6CB2-44C6537249AA} - {5896C4B3-31D1-1EDD-11D0-C46DB178DC12} = {5B52EF8A-3661-DCFF-797D-BC4D6AC60BDA} - {D4D193A8-47D7-0B1A-1327-F9C580E7AD07} = {5896C4B3-31D1-1EDD-11D0-C46DB178DC12} - {69C91AE6-4555-7B2C-AD32-F7F11B9C605A} = {D4D193A8-47D7-0B1A-1327-F9C580E7AD07} - {E8061AC3-8163-26F9-4FC8-C0E31D9C1EE1} = {D4D193A8-47D7-0B1A-1327-F9C580E7AD07} - {AE168BCD-C771-ECB3-6830-12D1D3B1871B} = {D4D193A8-47D7-0B1A-1327-F9C580E7AD07} - {345E1BA3-820E-DF7C-85FA-A9ABDD8B4057} = {D4D193A8-47D7-0B1A-1327-F9C580E7AD07} - {AEA0B5AB-830E-DB83-623F-3CE249DB4A1C} = {D4D193A8-47D7-0B1A-1327-F9C580E7AD07} - {DB6D3C1B-DBD3-4D87-64E5-87146B89E6EA} = {D4D193A8-47D7-0B1A-1327-F9C580E7AD07} - {0FF1692A-5BF7-62DC-C61C-FD2F44252ED2} = {D4D193A8-47D7-0B1A-1327-F9C580E7AD07} - {C9BCCEDF-7B8A-BCD8-A6B4-75EB25689FE8} = {D4D193A8-47D7-0B1A-1327-F9C580E7AD07} - {C0E85164-7AA3-6931-5770-037E3051A499} = {D4D193A8-47D7-0B1A-1327-F9C580E7AD07} - {9F30DC58-7747-31D8-2403-D7D0F5454C87} = {D4D193A8-47D7-0B1A-1327-F9C580E7AD07} - {336213F7-1241-D268-8EA5-1C73F0040714} = {D4D193A8-47D7-0B1A-1327-F9C580E7AD07} - {5693F73D-6707-6F86-65D6-654023205615} = {D4D193A8-47D7-0B1A-1327-F9C580E7AD07} - {593308D7-2453-DC66-4151-E983E4B3F422} = {D4D193A8-47D7-0B1A-1327-F9C580E7AD07} - {7D55A179-3CDB-8D44-C448-F502BF7ECB3D} = {D4D193A8-47D7-0B1A-1327-F9C580E7AD07} - {B24B448A-28D8-778E-DCC1-FCF4A0916DF5} = {5B52EF8A-3661-DCFF-797D-BC4D6AC60BDA} - {BF1AF1AB-97A8-BD70-63F2-E028DE8EE90F} = {B24B448A-28D8-778E-DCC1-FCF4A0916DF5} - {3DB6D7AE-8187-5324-1208-D6090D5324C6} = {BF1AF1AB-97A8-BD70-63F2-E028DE8EE90F} - {F945436F-31AA-CA1E-6C57-CCA4E8F854B4} = {BF1AF1AB-97A8-BD70-63F2-E028DE8EE90F} - {3247EE0D-B3E9-9C11-B0AE-FE719410390B} = {5B52EF8A-3661-DCFF-797D-BC4D6AC60BDA} - {CD7C09DA-FEC8-2CC5-D00C-E525638DFF4A} = {3247EE0D-B3E9-9C11-B0AE-FE719410390B} - {79B10804-91E9-972E-1913-EE0F0B11663E} = {CD7C09DA-FEC8-2CC5-D00C-E525638DFF4A} - {7C2831B0-C6BE-6A5A-D8AF-0FB8CE7CC181} = {CD7C09DA-FEC8-2CC5-D00C-E525638DFF4A} - {B67B057E-97D2-C6C5-0D7C-D41CA935778A} = {5B52EF8A-3661-DCFF-797D-BC4D6AC60BDA} - {0749F755-0A1A-7265-20BC-F2DE9EAE4DC3} = {B67B057E-97D2-C6C5-0D7C-D41CA935778A} - {EFA3BD2C-84D2-5AA8-C5B6-DD41A302A229} = {B67B057E-97D2-C6C5-0D7C-D41CA935778A} - {0C91EE5B-C434-750F-C923-6D7F9993BF94} = {5B52EF8A-3661-DCFF-797D-BC4D6AC60BDA} - {2EB6434B-85BC-51D4-4BA4-DD291B656FA7} = {0C91EE5B-C434-750F-C923-6D7F9993BF94} - {420AE456-2C11-B598-ECCF-8A00F8BAA467} = {2EB6434B-85BC-51D4-4BA4-DD291B656FA7} - {1345DD29-BB3A-FB5F-4B3D-E29F6045A27A} = {5B52EF8A-3661-DCFF-797D-BC4D6AC60BDA} - {232347E1-9BB1-0E46-AA39-C22E3B91BC39} = {1345DD29-BB3A-FB5F-4B3D-E29F6045A27A} - {9C2DD234-FA33-FDB6-86F0-EF9B75A13450} = {1345DD29-BB3A-FB5F-4B3D-E29F6045A27A} - {79E122F4-2325-3E92-438E-5825A307B594} = {1345DD29-BB3A-FB5F-4B3D-E29F6045A27A} - {584C3E3B-3CC8-504F-C662-C23A1DF3D002} = {1345DD29-BB3A-FB5F-4B3D-E29F6045A27A} - {538E2D98-5325-3F54-BE74-EFE5FC1ECBD8} = {1345DD29-BB3A-FB5F-4B3D-E29F6045A27A} - {66557252-B5C4-664B-D807-07018C627474} = {1345DD29-BB3A-FB5F-4B3D-E29F6045A27A} - {7203223D-FF02-7BEB-2798-D1639ACC01C4} = {1345DD29-BB3A-FB5F-4B3D-E29F6045A27A} - {5AC9EE40-1881-5F8A-46A2-2C303950D3C8} = {1345DD29-BB3A-FB5F-4B3D-E29F6045A27A} - {927E3CD3-4C20-4DE5-A395-D0977152A8D3} = {1345DD29-BB3A-FB5F-4B3D-E29F6045A27A} - {3C69853C-90E3-D889-1960-3B9229882590} = {1345DD29-BB3A-FB5F-4B3D-E29F6045A27A} - {695330E8-D292-889E-1D7F-1250A378492A} = {1345DD29-BB3A-FB5F-4B3D-E29F6045A27A} - {9FB0DDD7-7A77-8DA4-F9E2-A94E60ED8FC7} = {1345DD29-BB3A-FB5F-4B3D-E29F6045A27A} - {643E4D4C-BC96-A37F-E0EC-488127F0B127} = {1345DD29-BB3A-FB5F-4B3D-E29F6045A27A} - {6F2CA7F5-3E7C-C61B-94E6-E7DD1227B5B1} = {1345DD29-BB3A-FB5F-4B3D-E29F6045A27A} - {F04B7DBB-77A5-C978-B2DE-8C189A32AA72} = {1345DD29-BB3A-FB5F-4B3D-E29F6045A27A} - {7C72F22A-20FF-DF5B-9191-6DFD0D497DB2} = {1345DD29-BB3A-FB5F-4B3D-E29F6045A27A} - {C896CC0A-F5E6-9AA4-C582-E691441F8D32} = {1345DD29-BB3A-FB5F-4B3D-E29F6045A27A} - {0AA3A418-AB45-CCA4-46D4-EEBFE011FECA} = {1345DD29-BB3A-FB5F-4B3D-E29F6045A27A} - {225D9926-4AE8-E539-70AD-8698E688F271} = {1345DD29-BB3A-FB5F-4B3D-E29F6045A27A} - {D6E8E69C-F721-BBCB-8C39-9716D53D72AD} = {1345DD29-BB3A-FB5F-4B3D-E29F6045A27A} - {9529EE99-D6A5-B570-EB1F-15BD2D57DFE2} = {1345DD29-BB3A-FB5F-4B3D-E29F6045A27A} - {589A43FD-8213-E9E3-6CFF-9CBA72D53E98} = {1345DD29-BB3A-FB5F-4B3D-E29F6045A27A} - {2BACF7E3-1278-FE99-8343-8221E6FBA9DE} = {1345DD29-BB3A-FB5F-4B3D-E29F6045A27A} - {75E47125-E4D7-8482-F1A4-726564970864} = {1345DD29-BB3A-FB5F-4B3D-E29F6045A27A} - {FCD529E0-DD17-6587-B29C-12D425C0AD0C} = {1345DD29-BB3A-FB5F-4B3D-E29F6045A27A} - {61B23570-4F2D-B060-BE1F-37995682E494} = {1345DD29-BB3A-FB5F-4B3D-E29F6045A27A} - {1182764D-2143-EEF0-9270-3DCE392F5D06} = {1345DD29-BB3A-FB5F-4B3D-E29F6045A27A} - {772B02B5-6280-E1D4-3E2E-248D0455C2FB} = {1345DD29-BB3A-FB5F-4B3D-E29F6045A27A} - {48F90289-938C-CCA7-B60F-D2143E7C9A69} = {1345DD29-BB3A-FB5F-4B3D-E29F6045A27A} - {E69FA1A0-6D1B-A6E4-2DC0-8F4C5F21BF04} = {1345DD29-BB3A-FB5F-4B3D-E29F6045A27A} - {083067CF-CE89-EF39-9BD3-4741919E26F3} = {1345DD29-BB3A-FB5F-4B3D-E29F6045A27A} - {8380A20C-A5B8-EE91-1A58-270323688CB9} = {1345DD29-BB3A-FB5F-4B3D-E29F6045A27A} - {8F128EAE-E97E-82A0-A748-A13F1A85AC8F} = {1345DD29-BB3A-FB5F-4B3D-E29F6045A27A} - {A7542386-71EB-4F34-E1CE-27D399325955} = {1345DD29-BB3A-FB5F-4B3D-E29F6045A27A} - {90659617-4DF7-809A-4E5B-29BB5A98E8E1} = {5B52EF8A-3661-DCFF-797D-BC4D6AC60BDA} - {AB8B269C-5A2A-A4B8-0488-B5F81E55B4D9} = {90659617-4DF7-809A-4E5B-29BB5A98E8E1} - {EDBA6A07-B0FD-81C5-B3C5-1F7020F8065F} = {AB8B269C-5A2A-A4B8-0488-B5F81E55B4D9} - {122C01BB-BAD0-E507-AD3F-ABA8F00A80DC} = {A5C98087-E847-D2C4-2143-20869479839D} - {5788C133-8A9B-0810-2AF4-EA77504A7379} = {A5C98087-E847-D2C4-2143-20869479839D} - {86CBB26D-D368-4DC4-2F5E-E47E5078BF37} = {A5C98087-E847-D2C4-2143-20869479839D} - {7C3E7AD5-8E96-4BD0-5AF5-1FCB0F0D175C} = {A5C98087-E847-D2C4-2143-20869479839D} - {3B68EBC3-2752-608B-8F6D-BC7A28A3DAB7} = {A5C98087-E847-D2C4-2143-20869479839D} - {DD40725E-6473-AB10-786C-C3B68881A622} = {BB76B5A5-14BA-E317-828D-110B711D71F5} - {22B129C7-C609-3B90-AD56-64C746A1505E} = {EA6E5683-3A20-2E52-1CE6-AE0D6D36AC4D} - {AD31623A-BC43-52C2-D906-AC1D8784A541} = {3823DE1E-2ACE-C956-99E1-00DB786D9E1D} - {776E2142-804F-03B9-C804-D061D64C6092} = {EC506DBE-AB6D-492E-786E-8B176021BF2E} - {E106BC8E-B20D-C1B5-130C-DAC28922112A} = {0B71A5C2-A1C9-BB93-6042-23D1CEE5AD68} - {5B4DF41E-C8CC-2606-FA2D-967118BD3C59} = {5F27FB4E-CF09-3A6B-F5B4-BF5A709FA609} - {3D8C5A6C-462D-7487-5BD0-A3EF6B657EB6} = {018E0E11-1CCE-A2BE-641D-21EE14D2E90D} - {2609BC1A-6765-29BE-78CC-C0F1D2814F10} = {3F605548-87E2-8A1D-306D-0CE6960B8242} - {C6822231-A4F4-9E69-6CE2-4FDB3E81C728} = {45F7FA87-7451-6970-7F6E-F8BAE45E081B} - {28F2F8EE-CD31-0DEF-446C-D868B139F139} = {232347E1-9BB1-0E46-AA39-C22E3B91BC39} - {55D9B653-FB76-FCE8-1A3C-67B1BEDEC214} = {F2E6CB0E-DF77-1FAA-582B-62B040DF3848} - {DE5BF139-1E5C-D6EA-4FAA-661EF353A194} = {C494ECBE-DEA5-3576-D2AF-200FF12BC144} - {335E62C0-9E69-A952-680B-753B1B17C6D0} = {9C2DD234-FA33-FDB6-86F0-EF9B75A13450} - {5A6CD890-8142-F920-3734-D67CA3E65F61} = {9BD75659-58CB-06D1-E198-C39007E82C6A} - {A260E14F-DBA4-862E-53CD-18D3B92ADA3D} = {7BF13935-F1DD-D23B-8347-DB1550C69D69} - {97F94029-5419-6187-5A63-5C8FD9232FAE} = {64689413-46D7-8499-68A6-B6367ACBC597} - {AF9E7F02-25AD-3540-18D7-F6A4F8BA5A60} = {79E122F4-2325-3E92-438E-5825A307B594} - {301015C5-1F56-2266-84AA-AB6D83F28893} = {584C3E3B-3CC8-504F-C662-C23A1DF3D002} - {0C51F029-7C57-B767-AFFA-4800230A6B1F} = {000B0CE4-1FA5-04BB-64A0-CF75B545CE86} - {1BAEE7A9-C442-D76D-8531-AE20501395C7} = {122C01BB-BAD0-E507-AD3F-ABA8F00A80DC} - {E7CCD23E-AFD3-B46F-48B0-908E5BF0825B} = {5788C133-8A9B-0810-2AF4-EA77504A7379} - {8D3B990F-E832-139D-DDFD-1076A8E0834E} = {86CBB26D-D368-4DC4-2F5E-E47E5078BF37} - {058E17AA-8F9F-426B-2364-65467F6891F7} = {7C3E7AD5-8E96-4BD0-5AF5-1FCB0F0D175C} - {33767BF5-0175-51A7-9B37-9312610359FC} = {3B68EBC3-2752-608B-8F6D-BC7A28A3DAB7} - {D1322A50-ABAB-EEFC-17B5-60EDCA13DF8C} = {DD40725E-6473-AB10-786C-C3B68881A622} - {AB6AE2B6-8D6B-2D9F-2A88-7C596C59F4FC} = {39EFDA5B-F5EE-8212-D5BA-90E1B82013E7} - {BA45605A-1CCE-6B0C-489D-C113915B243F} = {6844B539-C2A3-9D4F-139D-9D533BCABADA} - {9D31FC8A-2A69-B78A-D3E5-4F867B16D971} = {4263AA71-0335-3F44-9A9B-423C3A3D05E6} - {92268008-FBB0-C7AD-ECC2-7B75BED9F5E1} = {F1B1DB47-D2D7-59CB-679B-23E4928E8328} - {8DCCAF70-D364-4C8B-4E90-AF65091DE0C5} = {BC35DE94-4F04-3436-27A3-F11647FEDD5C} - {7828C164-DD01-2809-CCB3-364486834F60} = {864C8B80-771A-0C15-30A5-558F99006E0D} - {DE95E7B2-0937-A980-441F-829E023BC43E} = {603E7A23-1D6B-D3A9-B0E6-3E332B13ED5C} - {91D69463-23E2-E2C7-AA7E-A78B13CED620} = {D2F7E58B-47D4-5205-D917-144CA1CFF4F1} - {34EFF636-81A7-8DF6-7CC9-4DA784BAC7F3} = {1DCF4EBB-DBC4-752C-13D4-D1EECE4E8907} - {5DCF16A8-97C6-2CB4-6A63-0370239039EB} = {1B37A859-E733-60CB-4806-1A24B6F10E05} - {EB093C48-CDAC-106B-1196-AE34809B34C0} = {F2B58F4E-6F28-A25F-5BFB-CDEBAD6B9A3E} - {92C62F7B-8028-6EE1-B71B-F45F459B8E97} = {538E2D98-5325-3F54-BE74-EFE5FC1ECBD8} - {F664A948-E352-5808-E780-77A03F19E93E} = {66557252-B5C4-664B-D807-07018C627474} - {FA83F778-5252-0B80-5555-E69F790322EA} = {7203223D-FF02-7BEB-2798-D1639ACC01C4} - {F3A27846-6DE0-3448-222C-25A273E86B2E} = {5AC9EE40-1881-5F8A-46A2-2C303950D3C8} - {166F4DEC-9886-92D5-6496-085664E9F08F} = {927E3CD3-4C20-4DE5-A395-D0977152A8D3} - {C53E0895-879A-D9E6-0A43-24AD17A2F270} = {3C69853C-90E3-D889-1960-3B9229882590} - {1EE42F0F-3F9A-613C-D01F-8BCDB4C42C0E} = {695330E8-D292-889E-1D7F-1250A378492A} - {246FCC7C-1437-742D-BAE5-E77A24164F08} = {9FB0DDD7-7A77-8DA4-F9E2-A94E60ED8FC7} - {0AED303F-69E6-238F-EF80-81985080EDB7} = {643E4D4C-BC96-A37F-E0EC-488127F0B127} - {2904D288-CE64-A565-2C46-C2E85A96A1EE} = {6F2CA7F5-3E7C-C61B-94E6-E7DD1227B5B1} - {A6667CC3-B77F-023E-3A67-05F99E9FF46A} = {F04B7DBB-77A5-C978-B2DE-8C189A32AA72} - {A26E2816-F787-F76B-1D6C-E086DD3E19CE} = {7C72F22A-20FF-DF5B-9191-6DFD0D497DB2} - {B3DEC619-67AC-1B5A-4F3E-A1F24C3F6877} = {C896CC0A-F5E6-9AA4-C582-E691441F8D32} - {90DB65B4-8F6E-FB8E-0281-505AD8BC6BA6} = {0AA3A418-AB45-CCA4-46D4-EEBFE011FECA} - {059FBB86-DEE6-8207-3F23-2A1A3EC00DEA} = {225D9926-4AE8-E539-70AD-8698E688F271} - {8BBA3159-C4CC-F685-A28C-7FE6CBD3D2A1} = {D6E8E69C-F721-BBCB-8C39-9716D53D72AD} - {EA0974E3-CD2B-5792-EF1E-9B5B7CCBDF00} = {9529EE99-D6A5-B570-EB1F-15BD2D57DFE2} - {632A1F0D-1BA5-C84B-B716-2BE638A92780} = {589A43FD-8213-E9E3-6CFF-9CBA72D53E98} - {9DE7852B-7E2D-257E-B0F1-45D2687854ED} = {2BACF7E3-1278-FE99-8343-8221E6FBA9DE} - {DC2AFC89-C3C8-4E9B-13A7-027EB6386EFA} = {75E47125-E4D7-8482-F1A4-726564970864} - {9151601C-8784-01A6-C2E7-A5C0FAAB0AEF} = {6DCAF6F3-717F-27A9-D96C-F2BFA5550347} - {4F1EE2D9-9392-6A1C-7224-6B01FAB934E3} = {83791804-2407-CC2B-34AD-ED8FFAAF3257} - {104A930A-6D8F-8C36-2CB5-0BC4F8FD74D2} = {48007FB6-A895-4ED1-E1AE-E0806BCFFF96} - {F7947A80-F07C-2FBF-77F8-DDFA57951A97} = {09DD25DA-BBB0-5D9D-A372-751855D00AF0} - {CB296A20-2732-77C1-7F23-27D5BAEDD0C7} = {054761F9-16D3-B2F8-6F4D-EFC2248805CD} - {0DBEC9BA-FE1D-3898-B2C6-E4357DC23E0F} = {B54CE64C-4167-1DD1-B7D6-2FD7A5AEF715} - {A63897D9-9531-989B-7309-E384BCFC2BB9} = {FCD529E0-DD17-6587-B29C-12D425C0AD0C} - {8C594D82-3463-3367-4F06-900AC707753D} = {61B23570-4F2D-B060-BE1F-37995682E494} - {9588FBF9-C37E-D16E-2E8F-CFA226EAC01D} = {1182764D-2143-EEF0-9270-3DCE392F5D06} - {97998C88-E6E1-D5E2-B632-537B58E00CBF} = {F4F1CBE2-1CDD-CAA4-41F0-266DB4677C05} - {20D1569C-2A47-38B8-075E-47225B674394} = {B0F64757-F7A7-1A11-8DEC-BAC72EB5EC29} - {2F7AA715-25AE-086A-7DF4-CAB5EF00E2B7} = {C5F86BAD-155A-591C-9610-55D40F59C775} - {38A9EE9B-6FC8-93BC-0D43-2A906E678D66} = {772B02B5-6280-E1D4-3E2E-248D0455C2FB} - {19868E2D-7163-2108-1094-F13887C4F070} = {831265B0-8896-9C95-3488-E12FD9F6DC53} - {7D3FC972-467A-4917-8339-9B6462C6A38A} = {97579A99-E7BE-9189-9B9A-CA0EBB5E9C97} - {C154051B-DB4E-5270-AF5A-12A0FFE0E769} = {F3131BAC-FF6E-FBF1-1A59-74B89427DFE6} - {CC319FC5-F4B1-C3DD-7310-4DAD343E0125} = {BC12ED55-6015-7C8B-8384-B39CE93C76D6} - {CD6B144E-BCDD-D4FE-2749-703DAB054EBC} = {7DE09F4B-E86D-CEA4-EC36-364CC9CCD2A6} - {B46D185B-A630-8F76-E61B-90084FBF65B0} = {BA20548F-5ADA-BE63-1AE7-BA12CB4E82B3} - {84F711C2-C210-28D2-F0D9-B13733FEE23D} = {48F90289-938C-CCA7-B60F-D2143E7C9A69} - {CBB14B90-27F9-8DD6-DFC4-3507DBD1FBC6} = {E69FA1A0-6D1B-A6E4-2DC0-8F4C5F21BF04} - {A78EBC0F-C62C-8F56-95C0-330E376242A2} = {9D6AB85A-85EA-D85A-5566-A121D34016E6} - {6D26FB21-7E48-024B-E5D4-E3F0F31976BB} = {083067CF-CE89-EF39-9BD3-4741919E26F3} - {28D91816-206C-576E-1A83-FD98E08C2E3C} = {69C91AE6-4555-7B2C-AD32-F7F11B9C605A} - {5EFEC79C-A9F1-96A4-692C-733566107170} = {E8061AC3-8163-26F9-4FC8-C0E31D9C1EE1} - {B7B5D764-C3A0-1743-0739-29966F993626} = {AE168BCD-C771-ECB3-6830-12D1D3B1871B} - {C4EDBBAF-875C-4839-05A8-F6F12A5ED52D} = {345E1BA3-820E-DF7C-85FA-A9ABDD8B4057} - {0EAC8F64-9588-1EF0-C33A-67590CF27590} = {AEA0B5AB-830E-DB83-623F-3CE249DB4A1C} - {B1B31937-CCC8-D97A-F66D-1849734B780B} = {DB6D3C1B-DBD3-4D87-64E5-87146B89E6EA} - {A345E5AC-BDDB-A817-3C92-08C8865D1EF9} = {0FF1692A-5BF7-62DC-C61C-FD2F44252ED2} - {58D8630F-C0F4-B772-8572-BCC98FF0F0D8} = {C9BCCEDF-7B8A-BCD8-A6B4-75EB25689FE8} - {D24E7862-3930-A4F6-1DFA-DA88C759546C} = {C0E85164-7AA3-6931-5770-037E3051A499} - {7CB7FEA8-8A12-A5D6-0057-AA65DB328617} = {9F30DC58-7747-31D8-2403-D7D0F5454C87} - {52698305-D6F8-C13C-0882-48FC37726404} = {336213F7-1241-D268-8EA5-1C73F0040714} - {5567139C-0365-B6A0-5DD0-978A09B9F176} = {5693F73D-6707-6F86-65D6-654023205615} - {256D269B-35EA-F833-2F1D-8E0058908DEE} = {593308D7-2453-DC66-4151-E983E4B3F422} - {6E9C9582-67FA-2EB1-C6BA-AD4CD326E276} = {7D55A179-3CDB-8D44-C448-F502BF7ECB3D} - {1F372AB9-D8DD-D295-1D5E-CB5D454CBB24} = {3DB6D7AE-8187-5324-1208-D6090D5324C6} - {D96DA724-3A66-14E2-D6CC-F65CEEE71069} = {F945436F-31AA-CA1E-6C57-CCA4E8F854B4} - {0AF13355-173C-3128-5AFC-D32E540DA3EF} = {79B10804-91E9-972E-1913-EE0F0B11663E} - {06BC00C6-78D4-05AD-C8C8-FF64CD7968E0} = {7C2831B0-C6BE-6A5A-D8AF-0FB8CE7CC181} - {FFC170B2-A6F0-A1D7-02BD-16D813C8C8C0} = {0749F755-0A1A-7265-20BC-F2DE9EAE4DC3} - {85B8B27B-51DD-025E-EEED-D44BC0D318B8} = {EFA3BD2C-84D2-5AA8-C5B6-DD41A302A229} - {AF043113-CCE3-59C1-DF71-9804155F26A8} = {8380A20C-A5B8-EE91-1A58-270323688CB9} - {9222D186-CD9F-C783-AED5-A3B0E48623BD} = {EDBA6A07-B0FD-81C5-B3C5-1F7020F8065F} - {10588F6A-E13D-98DC-4EC9-917DCEE382EE} = {420AE456-2C11-B598-ECCF-8A00F8BAA467} - {E62C8F14-A7CF-47DF-8D60-77308D5D0647} = {8F128EAE-E97E-82A0-A748-A13F1A85AC8F} - {1D761F8B-921C-53BF-DCF5-5ABD329EEB0C} = {A7542386-71EB-4F34-E1CE-27D399325955} - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {258695E4-E399-5944-2BC9-675391C4BB15} - EndGlobalSection -EndGlobal +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.0.31903.59 +MinimumVisualStudioVersion = 10.0.40219.1 + +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Cli", "StellaOps.Cli", "{000B0CE4-1FA5-04BB-64A0-CF75B545CE86}" + +EndProject + +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "__External", "__External", "{5B52EF8A-3661-DCFF-797D-BC4D6AC60BDA}" + +EndProject + +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "AirGap", "AirGap", "{F310596E-88BB-9E54-885E-21C61971917E}" + +EndProject + +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.AirGap.Importer", "StellaOps.AirGap.Importer", "{EA6E5683-3A20-2E52-1CE6-AE0D6D36AC4D}" + +EndProject + +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.AirGap.Policy", "StellaOps.AirGap.Policy", "{D9492ED1-A812-924B-65E4-F518592B49BB}" + +EndProject + +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.AirGap.Policy", "StellaOps.AirGap.Policy", "{3823DE1E-2ACE-C956-99E1-00DB786D9E1D}" + +EndProject + +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Aoc", "Aoc", "{03DFF14F-7321-1784-D4C7-4E99D4120F48}" + +EndProject + +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "__Libraries", "__Libraries", "{BDD326D6-7616-84F0-B914-74743BFBA520}" + +EndProject + +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Aoc", "StellaOps.Aoc", "{EC506DBE-AB6D-492E-786E-8B176021BF2E}" + +EndProject + +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Attestor", "Attestor", "{5AC09D9A-F2A5-9CFA-B3C5-8D25F257651C}" + +EndProject + +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Attestation", "StellaOps.Attestation", "{0B71A5C2-A1C9-BB93-6042-23D1CEE5AD68}" + +EndProject + +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Attestor", "StellaOps.Attestor", "{33B1AE27-692A-1778-48C1-CCEC2B9BC78F}" + +EndProject + +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Attestor.Envelope", "StellaOps.Attestor.Envelope", "{018E0E11-1CCE-A2BE-641D-21EE14D2E90D}" + +EndProject + +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Attestor.Core", "StellaOps.Attestor.Core", "{5F27FB4E-CF09-3A6B-F5B4-BF5A709FA609}" + +EndProject + +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "__Libraries", "__Libraries", "{AB67BDB9-D701-3AC9-9CDF-ECCDCCD8DB6D}" + +EndProject + +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Attestor.GraphRoot", "StellaOps.Attestor.GraphRoot", "{3F605548-87E2-8A1D-306D-0CE6960B8242}" + +EndProject + +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Attestor.ProofChain", "StellaOps.Attestor.ProofChain", "{45F7FA87-7451-6970-7F6E-F8BAE45E081B}" + +EndProject + +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Authority", "Authority", "{C1DCEFBD-12A5-EAAE-632E-8EEB9BE491B6}" + +EndProject + +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Authority", "StellaOps.Authority", "{A6928CBA-4D4D-AB2B-CA19-FEE6E73ECE70}" + +EndProject + +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Auth.Abstractions", "StellaOps.Auth.Abstractions", "{F2E6CB0E-DF77-1FAA-582B-62B040DF3848}" + +EndProject + +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Auth.Client", "StellaOps.Auth.Client", "{C494ECBE-DEA5-3576-D2AF-200FF12BC144}" + +EndProject + +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Authority.Plugins.Abstractions", "StellaOps.Authority.Plugins.Abstractions", "{64689413-46D7-8499-68A6-B6367ACBC597}" + +EndProject + +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "__Libraries", "__Libraries", "{5827F4DE-0AA7-FC85-641D-09E3D890DB27}" + +EndProject + +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Authority.Core", "StellaOps.Authority.Core", "{9BD75659-58CB-06D1-E198-C39007E82C6A}" + +EndProject + +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Authority.Persistence", "StellaOps.Authority.Persistence", "{7BF13935-F1DD-D23B-8347-DB1550C69D69}" + +EndProject + +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Concelier", "Concelier", "{157C3671-CA0B-69FA-A7C9-74A1FDA97B99}" + +EndProject + +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "__Libraries", "__Libraries", "{F39E09D6-BF93-B64A-CFE7-2BA92815C0FE}" + +EndProject + +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Concelier.Cache.Valkey", "StellaOps.Concelier.Cache.Valkey", "{39EFDA5B-F5EE-8212-D5BA-90E1B82013E7}" + +EndProject + +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Concelier.Core", "StellaOps.Concelier.Core", "{6844B539-C2A3-9D4F-139D-9D533BCABADA}" + +EndProject + +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Concelier.Interest", "StellaOps.Concelier.Interest", "{4263AA71-0335-3F44-9A9B-423C3A3D05E6}" + +EndProject + +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Concelier.Merge", "StellaOps.Concelier.Merge", "{F1B1DB47-D2D7-59CB-679B-23E4928E8328}" + +EndProject + +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Concelier.Models", "StellaOps.Concelier.Models", "{BC35DE94-4F04-3436-27A3-F11647FEDD5C}" + +EndProject + +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Concelier.Normalization", "StellaOps.Concelier.Normalization", "{864C8B80-771A-0C15-30A5-558F99006E0D}" + +EndProject + +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Concelier.Persistence", "StellaOps.Concelier.Persistence", "{603E7A23-1D6B-D3A9-B0E6-3E332B13ED5C}" + +EndProject + +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Concelier.ProofService", "StellaOps.Concelier.ProofService", "{D2F7E58B-47D4-5205-D917-144CA1CFF4F1}" + +EndProject + +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Concelier.RawModels", "StellaOps.Concelier.RawModels", "{1DCF4EBB-DBC4-752C-13D4-D1EECE4E8907}" + +EndProject + +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Concelier.SbomIntegration", "StellaOps.Concelier.SbomIntegration", "{1B37A859-E733-60CB-4806-1A24B6F10E05}" + +EndProject + +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Concelier.SourceIntel", "StellaOps.Concelier.SourceIntel", "{F2B58F4E-6F28-A25F-5BFB-CDEBAD6B9A3E}" + +EndProject + +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Excititor", "Excititor", "{7D49FA52-6EA1-EAC8-4C5A-AC07188D6C57}" + +EndProject + +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "__Libraries", "__Libraries", "{C9CF27FC-12DB-954F-863C-576BA8E309A5}" + +EndProject + +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Excititor.Core", "StellaOps.Excititor.Core", "{6DCAF6F3-717F-27A9-D96C-F2BFA5550347}" + +EndProject + +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Excititor.Persistence", "StellaOps.Excititor.Persistence", "{83791804-2407-CC2B-34AD-ED8FFAAF3257}" + +EndProject + +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ExportCenter", "ExportCenter", "{8E933B6D-39AB-871C-33D6-E57984AA38BA}" + +EndProject + +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.ExportCenter", "StellaOps.ExportCenter", "{84C61393-D449-22D3-FA3B-75F7256384E9}" + +EndProject + +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.ExportCenter.Client", "StellaOps.ExportCenter.Client", "{48007FB6-A895-4ED1-E1AE-E0806BCFFF96}" + +EndProject + +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.ExportCenter.Core", "StellaOps.ExportCenter.Core", "{09DD25DA-BBB0-5D9D-A372-751855D00AF0}" + +EndProject + +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Feedser", "Feedser", "{C4A90603-BE42-0044-CAB4-3EB910AD51A5}" + +EndProject + +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Feedser.BinaryAnalysis", "StellaOps.Feedser.BinaryAnalysis", "{054761F9-16D3-B2F8-6F4D-EFC2248805CD}" + +EndProject + +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Feedser.Core", "StellaOps.Feedser.Core", "{B54CE64C-4167-1DD1-B7D6-2FD7A5AEF715}" + +EndProject + +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Notify", "Notify", "{D2162FEA-AFA4-2A88-6444-2F6D845260BB}" + +EndProject + +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "__Libraries", "__Libraries", "{63EAEA3B-ADC9-631D-774E-7AA04490EDDD}" + +EndProject + +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Notify.Models", "StellaOps.Notify.Models", "{B0F64757-F7A7-1A11-8DEC-BAC72EB5EC29}" + +EndProject + +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Notify.Persistence", "StellaOps.Notify.Persistence", "{C5F86BAD-155A-591C-9610-55D40F59C775}" + +EndProject + +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Policy", "Policy", "{8E6B774C-CC4E-CE7C-AD4B-8AF7C92889A6}" + +EndProject + +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Policy.RiskProfile", "StellaOps.Policy.RiskProfile", "{BC12ED55-6015-7C8B-8384-B39CE93C76D6}" + +EndProject + +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Policy.Scoring", "StellaOps.Policy.Scoring", "{7DE09F4B-E86D-CEA4-EC36-364CC9CCD2A6}" + +EndProject + +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.PolicyDsl", "StellaOps.PolicyDsl", "{BA20548F-5ADA-BE63-1AE7-BA12CB4E82B3}" + +EndProject + +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "__Libraries", "__Libraries", "{FF70543D-AFF9-1D38-4950-4F8EE18D60BB}" + +EndProject + +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Policy", "StellaOps.Policy", "{831265B0-8896-9C95-3488-E12FD9F6DC53}" + +EndProject + +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Policy.Exceptions", "StellaOps.Policy.Exceptions", "{97579A99-E7BE-9189-9B9A-CA0EBB5E9C97}" + +EndProject + +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Policy.Persistence", "StellaOps.Policy.Persistence", "{F3131BAC-FF6E-FBF1-1A59-74B89427DFE6}" + +EndProject + +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Provenance", "Provenance", "{316BBD0A-04D2-85C9-52EA-7993CC6C8930}" + +EndProject + +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Provenance.Attestation", "StellaOps.Provenance.Attestation", "{9D6AB85A-85EA-D85A-5566-A121D34016E6}" + +EndProject + +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Router", "Router", "{FC018E5B-1E2F-DE19-1E97-0C845058C469}" + +EndProject + +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "__Libraries", "__Libraries", "{1BE5B76C-B486-560B-6CB2-44C6537249AA}" + +EndProject + +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Messaging", "StellaOps.Messaging", "{F4F1CBE2-1CDD-CAA4-41F0-266DB4677C05}" + +EndProject + +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Scanner", "Scanner", "{5896C4B3-31D1-1EDD-11D0-C46DB178DC12}" + +EndProject + +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "__Libraries", "__Libraries", "{D4D193A8-47D7-0B1A-1327-F9C580E7AD07}" + +EndProject + +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Scanner.Analyzers.Lang", "StellaOps.Scanner.Analyzers.Lang", "{69C91AE6-4555-7B2C-AD32-F7F11B9C605A}" + +EndProject + +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Scanner.Analyzers.Lang.Bun", "StellaOps.Scanner.Analyzers.Lang.Bun", "{E8061AC3-8163-26F9-4FC8-C0E31D9C1EE1}" + +EndProject + +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Scanner.Analyzers.Lang.Java", "StellaOps.Scanner.Analyzers.Lang.Java", "{AE168BCD-C771-ECB3-6830-12D1D3B1871B}" + +EndProject + +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Scanner.Analyzers.Lang.Node", "StellaOps.Scanner.Analyzers.Lang.Node", "{345E1BA3-820E-DF7C-85FA-A9ABDD8B4057}" + +EndProject + +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Scanner.Analyzers.Lang.Php", "StellaOps.Scanner.Analyzers.Lang.Php", "{AEA0B5AB-830E-DB83-623F-3CE249DB4A1C}" + +EndProject + +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Scanner.Analyzers.Lang.Python", "StellaOps.Scanner.Analyzers.Lang.Python", "{DB6D3C1B-DBD3-4D87-64E5-87146B89E6EA}" + +EndProject + +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Scanner.Analyzers.Lang.Ruby", "StellaOps.Scanner.Analyzers.Lang.Ruby", "{0FF1692A-5BF7-62DC-C61C-FD2F44252ED2}" + +EndProject + +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Scanner.Core", "StellaOps.Scanner.Core", "{C9BCCEDF-7B8A-BCD8-A6B4-75EB25689FE8}" + +EndProject + +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Scanner.EntryTrace", "StellaOps.Scanner.EntryTrace", "{C0E85164-7AA3-6931-5770-037E3051A499}" + +EndProject + +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Scanner.ProofSpine", "StellaOps.Scanner.ProofSpine", "{9F30DC58-7747-31D8-2403-D7D0F5454C87}" + +EndProject + +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Scanner.Surface.Env", "StellaOps.Scanner.Surface.Env", "{336213F7-1241-D268-8EA5-1C73F0040714}" + +EndProject + +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Scanner.Surface.FS", "StellaOps.Scanner.Surface.FS", "{5693F73D-6707-6F86-65D6-654023205615}" + +EndProject + +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Scanner.Surface.Secrets", "StellaOps.Scanner.Surface.Secrets", "{593308D7-2453-DC66-4151-E983E4B3F422}" + +EndProject + +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Scanner.Surface.Validation", "StellaOps.Scanner.Surface.Validation", "{7D55A179-3CDB-8D44-C448-F502BF7ECB3D}" + +EndProject + +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Scheduler", "Scheduler", "{B24B448A-28D8-778E-DCC1-FCF4A0916DF5}" + +EndProject + +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "__Libraries", "__Libraries", "{BF1AF1AB-97A8-BD70-63F2-E028DE8EE90F}" + +EndProject + +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Scheduler.Models", "StellaOps.Scheduler.Models", "{3DB6D7AE-8187-5324-1208-D6090D5324C6}" + +EndProject + +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Scheduler.Persistence", "StellaOps.Scheduler.Persistence", "{F945436F-31AA-CA1E-6C57-CCA4E8F854B4}" + +EndProject + +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Signer", "Signer", "{3247EE0D-B3E9-9C11-B0AE-FE719410390B}" + +EndProject + +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Signer", "StellaOps.Signer", "{CD7C09DA-FEC8-2CC5-D00C-E525638DFF4A}" + +EndProject + +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Signer.Core", "StellaOps.Signer.Core", "{79B10804-91E9-972E-1913-EE0F0B11663E}" + +EndProject + +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Signer.Infrastructure", "StellaOps.Signer.Infrastructure", "{7C2831B0-C6BE-6A5A-D8AF-0FB8CE7CC181}" + +EndProject + +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Symbols", "Symbols", "{B67B057E-97D2-C6C5-0D7C-D41CA935778A}" + +EndProject + +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Symbols.Client", "StellaOps.Symbols.Client", "{0749F755-0A1A-7265-20BC-F2DE9EAE4DC3}" + +EndProject + +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Symbols.Core", "StellaOps.Symbols.Core", "{EFA3BD2C-84D2-5AA8-C5B6-DD41A302A229}" + +EndProject + +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "TimelineIndexer", "TimelineIndexer", "{0C91EE5B-C434-750F-C923-6D7F9993BF94}" + +EndProject + +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.TimelineIndexer", "StellaOps.TimelineIndexer", "{2EB6434B-85BC-51D4-4BA4-DD291B656FA7}" + +EndProject + +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.TimelineIndexer.Core", "StellaOps.TimelineIndexer.Core", "{420AE456-2C11-B598-ECCF-8A00F8BAA467}" + +EndProject + +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "__Libraries", "__Libraries", "{1345DD29-BB3A-FB5F-4B3D-E29F6045A27A}" + +EndProject + +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.AuditPack", "StellaOps.AuditPack", "{232347E1-9BB1-0E46-AA39-C22E3B91BC39}" + +EndProject + +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Auth.Security", "StellaOps.Auth.Security", "{9C2DD234-FA33-FDB6-86F0-EF9B75A13450}" + +EndProject + +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Canonical.Json", "StellaOps.Canonical.Json", "{79E122F4-2325-3E92-438E-5825A307B594}" + +EndProject + +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Canonicalization", "StellaOps.Canonicalization", "{584C3E3B-3CC8-504F-C662-C23A1DF3D002}" + +EndProject + +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Configuration", "StellaOps.Configuration", "{538E2D98-5325-3F54-BE74-EFE5FC1ECBD8}" + +EndProject + +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Cryptography", "StellaOps.Cryptography", "{66557252-B5C4-664B-D807-07018C627474}" + +EndProject + +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Cryptography.DependencyInjection", "StellaOps.Cryptography.DependencyInjection", "{7203223D-FF02-7BEB-2798-D1639ACC01C4}" + +EndProject + +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Cryptography.Kms", "StellaOps.Cryptography.Kms", "{5AC9EE40-1881-5F8A-46A2-2C303950D3C8}" + +EndProject + +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Cryptography.Plugin.BouncyCastle", "StellaOps.Cryptography.Plugin.BouncyCastle", "{927E3CD3-4C20-4DE5-A395-D0977152A8D3}" + +EndProject + +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Cryptography.Plugin.CryptoPro", "StellaOps.Cryptography.Plugin.CryptoPro", "{3C69853C-90E3-D889-1960-3B9229882590}" + +EndProject + +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Cryptography.Plugin.EIDAS", "StellaOps.Cryptography.Plugin.EIDAS", "{695330E8-D292-889E-1D7F-1250A378492A}" + +EndProject + +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Cryptography.Plugin.OfflineVerification", "StellaOps.Cryptography.Plugin.OfflineVerification", "{9FB0DDD7-7A77-8DA4-F9E2-A94E60ED8FC7}" + +EndProject + +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Cryptography.Plugin.OpenSslGost", "StellaOps.Cryptography.Plugin.OpenSslGost", "{643E4D4C-BC96-A37F-E0EC-488127F0B127}" + +EndProject + +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Cryptography.Plugin.Pkcs11Gost", "StellaOps.Cryptography.Plugin.Pkcs11Gost", "{6F2CA7F5-3E7C-C61B-94E6-E7DD1227B5B1}" + +EndProject + +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Cryptography.Plugin.PqSoft", "StellaOps.Cryptography.Plugin.PqSoft", "{F04B7DBB-77A5-C978-B2DE-8C189A32AA72}" + +EndProject + +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Cryptography.Plugin.SimRemote", "StellaOps.Cryptography.Plugin.SimRemote", "{7C72F22A-20FF-DF5B-9191-6DFD0D497DB2}" + +EndProject + +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Cryptography.Plugin.SmRemote", "StellaOps.Cryptography.Plugin.SmRemote", "{C896CC0A-F5E6-9AA4-C582-E691441F8D32}" + +EndProject + +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Cryptography.Plugin.SmSoft", "StellaOps.Cryptography.Plugin.SmSoft", "{0AA3A418-AB45-CCA4-46D4-EEBFE011FECA}" + +EndProject + +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Cryptography.Plugin.WineCsp", "StellaOps.Cryptography.Plugin.WineCsp", "{225D9926-4AE8-E539-70AD-8698E688F271}" + +EndProject + +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Cryptography.PluginLoader", "StellaOps.Cryptography.PluginLoader", "{D6E8E69C-F721-BBCB-8C39-9716D53D72AD}" + +EndProject + +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.DeltaVerdict", "StellaOps.DeltaVerdict", "{9529EE99-D6A5-B570-EB1F-15BD2D57DFE2}" + +EndProject + +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.DependencyInjection", "StellaOps.DependencyInjection", "{589A43FD-8213-E9E3-6CFF-9CBA72D53E98}" + +EndProject + +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Evidence.Bundle", "StellaOps.Evidence.Bundle", "{2BACF7E3-1278-FE99-8343-8221E6FBA9DE}" + +EndProject + +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Evidence.Core", "StellaOps.Evidence.Core", "{75E47125-E4D7-8482-F1A4-726564970864}" + +EndProject + +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Infrastructure.EfCore", "StellaOps.Infrastructure.EfCore", "{FCD529E0-DD17-6587-B29C-12D425C0AD0C}" + +EndProject + +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Infrastructure.Postgres", "StellaOps.Infrastructure.Postgres", "{61B23570-4F2D-B060-BE1F-37995682E494}" + +EndProject + +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Ingestion.Telemetry", "StellaOps.Ingestion.Telemetry", "{1182764D-2143-EEF0-9270-3DCE392F5D06}" + +EndProject + +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Plugin", "StellaOps.Plugin", "{772B02B5-6280-E1D4-3E2E-248D0455C2FB}" + +EndProject + +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Provcache", "StellaOps.Provcache", "{48F90289-938C-CCA7-B60F-D2143E7C9A69}" + +EndProject + +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Provenance", "StellaOps.Provenance", "{E69FA1A0-6D1B-A6E4-2DC0-8F4C5F21BF04}" + +EndProject + +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Replay.Core", "StellaOps.Replay.Core", "{083067CF-CE89-EF39-9BD3-4741919E26F3}" + +EndProject + +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.TestKit", "StellaOps.TestKit", "{8380A20C-A5B8-EE91-1A58-270323688CB9}" + +EndProject + +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Verdict", "StellaOps.Verdict", "{8F128EAE-E97E-82A0-A748-A13F1A85AC8F}" + +EndProject + +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.VersionComparison", "StellaOps.VersionComparison", "{A7542386-71EB-4F34-E1CE-27D399325955}" + +EndProject + +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "__Tests", "__Tests", "{90659617-4DF7-809A-4E5B-29BB5A98E8E1}" + +EndProject + +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "__Libraries", "__Libraries", "{AB8B269C-5A2A-A4B8-0488-B5F81E55B4D9}" + +EndProject + +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Testing.Manifests", "StellaOps.Testing.Manifests", "{EDBA6A07-B0FD-81C5-B3C5-1F7020F8065F}" + +EndProject + +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "__Libraries", "__Libraries", "{A5C98087-E847-D2C4-2143-20869479839D}" + +EndProject + +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Cli.Plugins.Aoc", "StellaOps.Cli.Plugins.Aoc", "{122C01BB-BAD0-E507-AD3F-ABA8F00A80DC}" + +EndProject + +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Cli.Plugins.NonCore", "StellaOps.Cli.Plugins.NonCore", "{5788C133-8A9B-0810-2AF4-EA77504A7379}" + +EndProject + +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Cli.Plugins.Symbols", "StellaOps.Cli.Plugins.Symbols", "{86CBB26D-D368-4DC4-2F5E-E47E5078BF37}" + +EndProject + +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Cli.Plugins.Verdict", "StellaOps.Cli.Plugins.Verdict", "{7C3E7AD5-8E96-4BD0-5AF5-1FCB0F0D175C}" + +EndProject + +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Cli.Plugins.Vex", "StellaOps.Cli.Plugins.Vex", "{3B68EBC3-2752-608B-8F6D-BC7A28A3DAB7}" + +EndProject + +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "__Tests", "__Tests", "{BB76B5A5-14BA-E317-828D-110B711D71F5}" + +EndProject + +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Cli.Tests", "StellaOps.Cli.Tests", "{DD40725E-6473-AB10-786C-C3B68881A622}" + +EndProject + +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.AirGap.Importer", "E:\dev\git.stella-ops.org\src\AirGap\StellaOps.AirGap.Importer\StellaOps.AirGap.Importer.csproj", "{22B129C7-C609-3B90-AD56-64C746A1505E}" + +EndProject + +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.AirGap.Policy", "E:\dev\git.stella-ops.org\src\AirGap\StellaOps.AirGap.Policy\StellaOps.AirGap.Policy\StellaOps.AirGap.Policy.csproj", "{AD31623A-BC43-52C2-D906-AC1D8784A541}" + +EndProject + +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Aoc", "E:\dev\git.stella-ops.org\src\Aoc\__Libraries\StellaOps.Aoc\StellaOps.Aoc.csproj", "{776E2142-804F-03B9-C804-D061D64C6092}" + +EndProject + +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Attestation", "E:\dev\git.stella-ops.org\src\Attestor\StellaOps.Attestation\StellaOps.Attestation.csproj", "{E106BC8E-B20D-C1B5-130C-DAC28922112A}" + +EndProject + +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Attestor.Core", "E:\dev\git.stella-ops.org\src\Attestor\StellaOps.Attestor\StellaOps.Attestor.Core\StellaOps.Attestor.Core.csproj", "{5B4DF41E-C8CC-2606-FA2D-967118BD3C59}" + +EndProject + +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Attestor.Envelope", "E:\dev\git.stella-ops.org\src\Attestor\StellaOps.Attestor.Envelope\StellaOps.Attestor.Envelope.csproj", "{3D8C5A6C-462D-7487-5BD0-A3EF6B657EB6}" + +EndProject + +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Attestor.GraphRoot", "E:\dev\git.stella-ops.org\src\Attestor\__Libraries\StellaOps.Attestor.GraphRoot\StellaOps.Attestor.GraphRoot.csproj", "{2609BC1A-6765-29BE-78CC-C0F1D2814F10}" + +EndProject + +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Attestor.ProofChain", "E:\dev\git.stella-ops.org\src\Attestor\__Libraries\StellaOps.Attestor.ProofChain\StellaOps.Attestor.ProofChain.csproj", "{C6822231-A4F4-9E69-6CE2-4FDB3E81C728}" + +EndProject + +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.AuditPack", "E:\dev\git.stella-ops.org\src\__Libraries\StellaOps.AuditPack\StellaOps.AuditPack.csproj", "{28F2F8EE-CD31-0DEF-446C-D868B139F139}" + +EndProject + +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Auth.Abstractions", "E:\dev\git.stella-ops.org\src\Authority\StellaOps.Authority\StellaOps.Auth.Abstractions\StellaOps.Auth.Abstractions.csproj", "{55D9B653-FB76-FCE8-1A3C-67B1BEDEC214}" + +EndProject + +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Auth.Client", "E:\dev\git.stella-ops.org\src\Authority\StellaOps.Authority\StellaOps.Auth.Client\StellaOps.Auth.Client.csproj", "{DE5BF139-1E5C-D6EA-4FAA-661EF353A194}" + +EndProject + +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Auth.Security", "E:\dev\git.stella-ops.org\src\__Libraries\StellaOps.Auth.Security\StellaOps.Auth.Security.csproj", "{335E62C0-9E69-A952-680B-753B1B17C6D0}" + +EndProject + +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Authority.Core", "E:\dev\git.stella-ops.org\src\Authority\__Libraries\StellaOps.Authority.Core\StellaOps.Authority.Core.csproj", "{5A6CD890-8142-F920-3734-D67CA3E65F61}" + +EndProject + +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Authority.Persistence", "E:\dev\git.stella-ops.org\src\Authority\__Libraries\StellaOps.Authority.Persistence\StellaOps.Authority.Persistence.csproj", "{A260E14F-DBA4-862E-53CD-18D3B92ADA3D}" + +EndProject + +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Authority.Plugins.Abstractions", "E:\dev\git.stella-ops.org\src\Authority\StellaOps.Authority\StellaOps.Authority.Plugins.Abstractions\StellaOps.Authority.Plugins.Abstractions.csproj", "{97F94029-5419-6187-5A63-5C8FD9232FAE}" + +EndProject + +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Canonical.Json", "E:\dev\git.stella-ops.org\src\__Libraries\StellaOps.Canonical.Json\StellaOps.Canonical.Json.csproj", "{AF9E7F02-25AD-3540-18D7-F6A4F8BA5A60}" + +EndProject + +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Canonicalization", "E:\dev\git.stella-ops.org\src\__Libraries\StellaOps.Canonicalization\StellaOps.Canonicalization.csproj", "{301015C5-1F56-2266-84AA-AB6D83F28893}" + +EndProject + +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Cli", "StellaOps.Cli\StellaOps.Cli.csproj", "{0C51F029-7C57-B767-AFFA-4800230A6B1F}" + +EndProject + +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Cli.Plugins.Aoc", "__Libraries\StellaOps.Cli.Plugins.Aoc\StellaOps.Cli.Plugins.Aoc.csproj", "{1BAEE7A9-C442-D76D-8531-AE20501395C7}" + +EndProject + +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Cli.Plugins.NonCore", "__Libraries\StellaOps.Cli.Plugins.NonCore\StellaOps.Cli.Plugins.NonCore.csproj", "{E7CCD23E-AFD3-B46F-48B0-908E5BF0825B}" + +EndProject + +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Cli.Plugins.Symbols", "__Libraries\StellaOps.Cli.Plugins.Symbols\StellaOps.Cli.Plugins.Symbols.csproj", "{8D3B990F-E832-139D-DDFD-1076A8E0834E}" + +EndProject + +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Cli.Plugins.Verdict", "__Libraries\StellaOps.Cli.Plugins.Verdict\StellaOps.Cli.Plugins.Verdict.csproj", "{058E17AA-8F9F-426B-2364-65467F6891F7}" + +EndProject + +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Cli.Plugins.Vex", "__Libraries\StellaOps.Cli.Plugins.Vex\StellaOps.Cli.Plugins.Vex.csproj", "{33767BF5-0175-51A7-9B37-9312610359FC}" + +EndProject + +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Cli.Tests", "__Tests\StellaOps.Cli.Tests\StellaOps.Cli.Tests.csproj", "{D1322A50-ABAB-EEFC-17B5-60EDCA13DF8C}" + +EndProject + +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Concelier.Cache.Valkey", "E:\dev\git.stella-ops.org\src\Concelier\__Libraries\StellaOps.Concelier.Cache.Valkey\StellaOps.Concelier.Cache.Valkey.csproj", "{AB6AE2B6-8D6B-2D9F-2A88-7C596C59F4FC}" + +EndProject + +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Concelier.Core", "E:\dev\git.stella-ops.org\src\Concelier\__Libraries\StellaOps.Concelier.Core\StellaOps.Concelier.Core.csproj", "{BA45605A-1CCE-6B0C-489D-C113915B243F}" + +EndProject + +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Concelier.Interest", "E:\dev\git.stella-ops.org\src\Concelier\__Libraries\StellaOps.Concelier.Interest\StellaOps.Concelier.Interest.csproj", "{9D31FC8A-2A69-B78A-D3E5-4F867B16D971}" + +EndProject + +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Concelier.Merge", "E:\dev\git.stella-ops.org\src\Concelier\__Libraries\StellaOps.Concelier.Merge\StellaOps.Concelier.Merge.csproj", "{92268008-FBB0-C7AD-ECC2-7B75BED9F5E1}" + +EndProject + +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Concelier.Models", "E:\dev\git.stella-ops.org\src\Concelier\__Libraries\StellaOps.Concelier.Models\StellaOps.Concelier.Models.csproj", "{8DCCAF70-D364-4C8B-4E90-AF65091DE0C5}" + +EndProject + +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Concelier.Normalization", "E:\dev\git.stella-ops.org\src\Concelier\__Libraries\StellaOps.Concelier.Normalization\StellaOps.Concelier.Normalization.csproj", "{7828C164-DD01-2809-CCB3-364486834F60}" + +EndProject + +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Concelier.Persistence", "E:\dev\git.stella-ops.org\src\Concelier\__Libraries\StellaOps.Concelier.Persistence\StellaOps.Concelier.Persistence.csproj", "{DE95E7B2-0937-A980-441F-829E023BC43E}" + +EndProject + +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Concelier.ProofService", "E:\dev\git.stella-ops.org\src\Concelier\__Libraries\StellaOps.Concelier.ProofService\StellaOps.Concelier.ProofService.csproj", "{91D69463-23E2-E2C7-AA7E-A78B13CED620}" + +EndProject + +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Concelier.RawModels", "E:\dev\git.stella-ops.org\src\Concelier\__Libraries\StellaOps.Concelier.RawModels\StellaOps.Concelier.RawModels.csproj", "{34EFF636-81A7-8DF6-7CC9-4DA784BAC7F3}" + +EndProject + +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Concelier.SbomIntegration", "E:\dev\git.stella-ops.org\src\Concelier\__Libraries\StellaOps.Concelier.SbomIntegration\StellaOps.Concelier.SbomIntegration.csproj", "{5DCF16A8-97C6-2CB4-6A63-0370239039EB}" + +EndProject + +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Concelier.SourceIntel", "E:\dev\git.stella-ops.org\src\Concelier\__Libraries\StellaOps.Concelier.SourceIntel\StellaOps.Concelier.SourceIntel.csproj", "{EB093C48-CDAC-106B-1196-AE34809B34C0}" + +EndProject + +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Configuration", "E:\dev\git.stella-ops.org\src\__Libraries\StellaOps.Configuration\StellaOps.Configuration.csproj", "{92C62F7B-8028-6EE1-B71B-F45F459B8E97}" + +EndProject + +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Cryptography", "E:\dev\git.stella-ops.org\src\__Libraries\StellaOps.Cryptography\StellaOps.Cryptography.csproj", "{F664A948-E352-5808-E780-77A03F19E93E}" + +EndProject + +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Cryptography.DependencyInjection", "E:\dev\git.stella-ops.org\src\__Libraries\StellaOps.Cryptography.DependencyInjection\StellaOps.Cryptography.DependencyInjection.csproj", "{FA83F778-5252-0B80-5555-E69F790322EA}" + +EndProject + +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Cryptography.Kms", "E:\dev\git.stella-ops.org\src\__Libraries\StellaOps.Cryptography.Kms\StellaOps.Cryptography.Kms.csproj", "{F3A27846-6DE0-3448-222C-25A273E86B2E}" + +EndProject + +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Cryptography.Plugin.BouncyCastle", "E:\dev\git.stella-ops.org\src\__Libraries\StellaOps.Cryptography.Plugin.BouncyCastle\StellaOps.Cryptography.Plugin.BouncyCastle.csproj", "{166F4DEC-9886-92D5-6496-085664E9F08F}" + +EndProject + +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Cryptography.Plugin.CryptoPro", "E:\dev\git.stella-ops.org\src\__Libraries\StellaOps.Cryptography.Plugin.CryptoPro\StellaOps.Cryptography.Plugin.CryptoPro.csproj", "{C53E0895-879A-D9E6-0A43-24AD17A2F270}" + +EndProject + +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Cryptography.Plugin.EIDAS", "E:\dev\git.stella-ops.org\src\__Libraries\StellaOps.Cryptography.Plugin.EIDAS\StellaOps.Cryptography.Plugin.EIDAS.csproj", "{1EE42F0F-3F9A-613C-D01F-8BCDB4C42C0E}" + +EndProject + +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Cryptography.Plugin.OfflineVerification", "E:\dev\git.stella-ops.org\src\__Libraries\StellaOps.Cryptography.Plugin.OfflineVerification\StellaOps.Cryptography.Plugin.OfflineVerification.csproj", "{246FCC7C-1437-742D-BAE5-E77A24164F08}" + +EndProject + +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Cryptography.Plugin.OpenSslGost", "E:\dev\git.stella-ops.org\src\__Libraries\StellaOps.Cryptography.Plugin.OpenSslGost\StellaOps.Cryptography.Plugin.OpenSslGost.csproj", "{0AED303F-69E6-238F-EF80-81985080EDB7}" + +EndProject + +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Cryptography.Plugin.Pkcs11Gost", "E:\dev\git.stella-ops.org\src\__Libraries\StellaOps.Cryptography.Plugin.Pkcs11Gost\StellaOps.Cryptography.Plugin.Pkcs11Gost.csproj", "{2904D288-CE64-A565-2C46-C2E85A96A1EE}" + +EndProject + +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Cryptography.Plugin.PqSoft", "E:\dev\git.stella-ops.org\src\__Libraries\StellaOps.Cryptography.Plugin.PqSoft\StellaOps.Cryptography.Plugin.PqSoft.csproj", "{A6667CC3-B77F-023E-3A67-05F99E9FF46A}" + +EndProject + +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Cryptography.Plugin.SimRemote", "E:\dev\git.stella-ops.org\src\__Libraries\StellaOps.Cryptography.Plugin.SimRemote\StellaOps.Cryptography.Plugin.SimRemote.csproj", "{A26E2816-F787-F76B-1D6C-E086DD3E19CE}" + +EndProject + +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Cryptography.Plugin.SmRemote", "E:\dev\git.stella-ops.org\src\__Libraries\StellaOps.Cryptography.Plugin.SmRemote\StellaOps.Cryptography.Plugin.SmRemote.csproj", "{B3DEC619-67AC-1B5A-4F3E-A1F24C3F6877}" + +EndProject + +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Cryptography.Plugin.SmSoft", "E:\dev\git.stella-ops.org\src\__Libraries\StellaOps.Cryptography.Plugin.SmSoft\StellaOps.Cryptography.Plugin.SmSoft.csproj", "{90DB65B4-8F6E-FB8E-0281-505AD8BC6BA6}" + +EndProject + +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Cryptography.Plugin.WineCsp", "E:\dev\git.stella-ops.org\src\__Libraries\StellaOps.Cryptography.Plugin.WineCsp\StellaOps.Cryptography.Plugin.WineCsp.csproj", "{059FBB86-DEE6-8207-3F23-2A1A3EC00DEA}" + +EndProject + +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Cryptography.PluginLoader", "E:\dev\git.stella-ops.org\src\__Libraries\StellaOps.Cryptography.PluginLoader\StellaOps.Cryptography.PluginLoader.csproj", "{8BBA3159-C4CC-F685-A28C-7FE6CBD3D2A1}" + +EndProject + +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.DeltaVerdict", "E:\dev\git.stella-ops.org\src\__Libraries\StellaOps.DeltaVerdict\StellaOps.DeltaVerdict.csproj", "{EA0974E3-CD2B-5792-EF1E-9B5B7CCBDF00}" + +EndProject + +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.DependencyInjection", "E:\dev\git.stella-ops.org\src\__Libraries\StellaOps.DependencyInjection\StellaOps.DependencyInjection.csproj", "{632A1F0D-1BA5-C84B-B716-2BE638A92780}" + +EndProject + +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Evidence.Bundle", "E:\dev\git.stella-ops.org\src\__Libraries\StellaOps.Evidence.Bundle\StellaOps.Evidence.Bundle.csproj", "{9DE7852B-7E2D-257E-B0F1-45D2687854ED}" + +EndProject + +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Evidence.Core", "E:\dev\git.stella-ops.org\src\__Libraries\StellaOps.Evidence.Core\StellaOps.Evidence.Core.csproj", "{DC2AFC89-C3C8-4E9B-13A7-027EB6386EFA}" + +EndProject + +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Excititor.Core", "E:\dev\git.stella-ops.org\src\Excititor\__Libraries\StellaOps.Excititor.Core\StellaOps.Excititor.Core.csproj", "{9151601C-8784-01A6-C2E7-A5C0FAAB0AEF}" + +EndProject + +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Excititor.Persistence", "E:\dev\git.stella-ops.org\src\Excititor\__Libraries\StellaOps.Excititor.Persistence\StellaOps.Excititor.Persistence.csproj", "{4F1EE2D9-9392-6A1C-7224-6B01FAB934E3}" + +EndProject + +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.ExportCenter.Client", "E:\dev\git.stella-ops.org\src\ExportCenter\StellaOps.ExportCenter\StellaOps.ExportCenter.Client\StellaOps.ExportCenter.Client.csproj", "{104A930A-6D8F-8C36-2CB5-0BC4F8FD74D2}" + +EndProject + +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.ExportCenter.Core", "E:\dev\git.stella-ops.org\src\ExportCenter\StellaOps.ExportCenter\StellaOps.ExportCenter.Core\StellaOps.ExportCenter.Core.csproj", "{F7947A80-F07C-2FBF-77F8-DDFA57951A97}" + +EndProject + +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Feedser.BinaryAnalysis", "E:\dev\git.stella-ops.org\src\Feedser\StellaOps.Feedser.BinaryAnalysis\StellaOps.Feedser.BinaryAnalysis.csproj", "{CB296A20-2732-77C1-7F23-27D5BAEDD0C7}" + +EndProject + +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Feedser.Core", "E:\dev\git.stella-ops.org\src\Feedser\StellaOps.Feedser.Core\StellaOps.Feedser.Core.csproj", "{0DBEC9BA-FE1D-3898-B2C6-E4357DC23E0F}" + +EndProject + +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Infrastructure.EfCore", "E:\dev\git.stella-ops.org\src\__Libraries\StellaOps.Infrastructure.EfCore\StellaOps.Infrastructure.EfCore.csproj", "{A63897D9-9531-989B-7309-E384BCFC2BB9}" + +EndProject + +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Infrastructure.Postgres", "E:\dev\git.stella-ops.org\src\__Libraries\StellaOps.Infrastructure.Postgres\StellaOps.Infrastructure.Postgres.csproj", "{8C594D82-3463-3367-4F06-900AC707753D}" + +EndProject + +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Ingestion.Telemetry", "E:\dev\git.stella-ops.org\src\__Libraries\StellaOps.Ingestion.Telemetry\StellaOps.Ingestion.Telemetry.csproj", "{9588FBF9-C37E-D16E-2E8F-CFA226EAC01D}" + +EndProject + +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Messaging", "E:\dev\git.stella-ops.org\src\Router\__Libraries\StellaOps.Messaging\StellaOps.Messaging.csproj", "{97998C88-E6E1-D5E2-B632-537B58E00CBF}" + +EndProject + +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Notify.Models", "E:\dev\git.stella-ops.org\src\Notify\__Libraries\StellaOps.Notify.Models\StellaOps.Notify.Models.csproj", "{20D1569C-2A47-38B8-075E-47225B674394}" + +EndProject + +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Notify.Persistence", "E:\dev\git.stella-ops.org\src\Notify\__Libraries\StellaOps.Notify.Persistence\StellaOps.Notify.Persistence.csproj", "{2F7AA715-25AE-086A-7DF4-CAB5EF00E2B7}" + +EndProject + +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Plugin", "E:\dev\git.stella-ops.org\src\__Libraries\StellaOps.Plugin\StellaOps.Plugin.csproj", "{38A9EE9B-6FC8-93BC-0D43-2A906E678D66}" + +EndProject + +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Policy", "E:\dev\git.stella-ops.org\src\Policy\__Libraries\StellaOps.Policy\StellaOps.Policy.csproj", "{19868E2D-7163-2108-1094-F13887C4F070}" + +EndProject + +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Policy.Exceptions", "E:\dev\git.stella-ops.org\src\Policy\__Libraries\StellaOps.Policy.Exceptions\StellaOps.Policy.Exceptions.csproj", "{7D3FC972-467A-4917-8339-9B6462C6A38A}" + +EndProject + +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Policy.Persistence", "E:\dev\git.stella-ops.org\src\Policy\__Libraries\StellaOps.Policy.Persistence\StellaOps.Policy.Persistence.csproj", "{C154051B-DB4E-5270-AF5A-12A0FFE0E769}" + +EndProject + +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Policy.RiskProfile", "E:\dev\git.stella-ops.org\src\Policy\StellaOps.Policy.RiskProfile\StellaOps.Policy.RiskProfile.csproj", "{CC319FC5-F4B1-C3DD-7310-4DAD343E0125}" + +EndProject + +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Policy.Scoring", "E:\dev\git.stella-ops.org\src\Policy\StellaOps.Policy.Scoring\StellaOps.Policy.Scoring.csproj", "{CD6B144E-BCDD-D4FE-2749-703DAB054EBC}" + +EndProject + +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.PolicyDsl", "E:\dev\git.stella-ops.org\src\Policy\StellaOps.PolicyDsl\StellaOps.PolicyDsl.csproj", "{B46D185B-A630-8F76-E61B-90084FBF65B0}" + +EndProject + +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Provcache", "E:\dev\git.stella-ops.org\src\__Libraries\StellaOps.Provcache\StellaOps.Provcache.csproj", "{84F711C2-C210-28D2-F0D9-B13733FEE23D}" + +EndProject + +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Provenance", "E:\dev\git.stella-ops.org\src\__Libraries\StellaOps.Provenance\StellaOps.Provenance.csproj", "{CBB14B90-27F9-8DD6-DFC4-3507DBD1FBC6}" + +EndProject + +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Provenance.Attestation", "E:\dev\git.stella-ops.org\src\Provenance\StellaOps.Provenance.Attestation\StellaOps.Provenance.Attestation.csproj", "{A78EBC0F-C62C-8F56-95C0-330E376242A2}" + +EndProject + +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Replay.Core", "E:\dev\git.stella-ops.org\src\__Libraries\StellaOps.Replay.Core\StellaOps.Replay.Core.csproj", "{6D26FB21-7E48-024B-E5D4-E3F0F31976BB}" + +EndProject + +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Scanner.Analyzers.Lang", "E:\dev\git.stella-ops.org\src\Scanner\__Libraries\StellaOps.Scanner.Analyzers.Lang\StellaOps.Scanner.Analyzers.Lang.csproj", "{28D91816-206C-576E-1A83-FD98E08C2E3C}" + +EndProject + +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Scanner.Analyzers.Lang.Bun", "E:\dev\git.stella-ops.org\src\Scanner\__Libraries\StellaOps.Scanner.Analyzers.Lang.Bun\StellaOps.Scanner.Analyzers.Lang.Bun.csproj", "{5EFEC79C-A9F1-96A4-692C-733566107170}" + +EndProject + +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Scanner.Analyzers.Lang.Java", "E:\dev\git.stella-ops.org\src\Scanner\__Libraries\StellaOps.Scanner.Analyzers.Lang.Java\StellaOps.Scanner.Analyzers.Lang.Java.csproj", "{B7B5D764-C3A0-1743-0739-29966F993626}" + +EndProject + +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Scanner.Analyzers.Lang.Node", "E:\dev\git.stella-ops.org\src\Scanner\__Libraries\StellaOps.Scanner.Analyzers.Lang.Node\StellaOps.Scanner.Analyzers.Lang.Node.csproj", "{C4EDBBAF-875C-4839-05A8-F6F12A5ED52D}" + +EndProject + +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Scanner.Analyzers.Lang.Php", "E:\dev\git.stella-ops.org\src\Scanner\__Libraries\StellaOps.Scanner.Analyzers.Lang.Php\StellaOps.Scanner.Analyzers.Lang.Php.csproj", "{0EAC8F64-9588-1EF0-C33A-67590CF27590}" + +EndProject + +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Scanner.Analyzers.Lang.Python", "E:\dev\git.stella-ops.org\src\Scanner\__Libraries\StellaOps.Scanner.Analyzers.Lang.Python\StellaOps.Scanner.Analyzers.Lang.Python.csproj", "{B1B31937-CCC8-D97A-F66D-1849734B780B}" + +EndProject + +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Scanner.Analyzers.Lang.Ruby", "E:\dev\git.stella-ops.org\src\Scanner\__Libraries\StellaOps.Scanner.Analyzers.Lang.Ruby\StellaOps.Scanner.Analyzers.Lang.Ruby.csproj", "{A345E5AC-BDDB-A817-3C92-08C8865D1EF9}" + +EndProject + +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Scanner.Core", "E:\dev\git.stella-ops.org\src\Scanner\__Libraries\StellaOps.Scanner.Core\StellaOps.Scanner.Core.csproj", "{58D8630F-C0F4-B772-8572-BCC98FF0F0D8}" + +EndProject + +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Scanner.EntryTrace", "E:\dev\git.stella-ops.org\src\Scanner\__Libraries\StellaOps.Scanner.EntryTrace\StellaOps.Scanner.EntryTrace.csproj", "{D24E7862-3930-A4F6-1DFA-DA88C759546C}" + +EndProject + +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Scanner.ProofSpine", "E:\dev\git.stella-ops.org\src\Scanner\__Libraries\StellaOps.Scanner.ProofSpine\StellaOps.Scanner.ProofSpine.csproj", "{7CB7FEA8-8A12-A5D6-0057-AA65DB328617}" + +EndProject + +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Scanner.Surface.Env", "E:\dev\git.stella-ops.org\src\Scanner\__Libraries\StellaOps.Scanner.Surface.Env\StellaOps.Scanner.Surface.Env.csproj", "{52698305-D6F8-C13C-0882-48FC37726404}" + +EndProject + +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Scanner.Surface.FS", "E:\dev\git.stella-ops.org\src\Scanner\__Libraries\StellaOps.Scanner.Surface.FS\StellaOps.Scanner.Surface.FS.csproj", "{5567139C-0365-B6A0-5DD0-978A09B9F176}" + +EndProject + +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Scanner.Surface.Secrets", "E:\dev\git.stella-ops.org\src\Scanner\__Libraries\StellaOps.Scanner.Surface.Secrets\StellaOps.Scanner.Surface.Secrets.csproj", "{256D269B-35EA-F833-2F1D-8E0058908DEE}" + +EndProject + +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Scanner.Surface.Validation", "E:\dev\git.stella-ops.org\src\Scanner\__Libraries\StellaOps.Scanner.Surface.Validation\StellaOps.Scanner.Surface.Validation.csproj", "{6E9C9582-67FA-2EB1-C6BA-AD4CD326E276}" + +EndProject + +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Scheduler.Models", "E:\dev\git.stella-ops.org\src\Scheduler\__Libraries\StellaOps.Scheduler.Models\StellaOps.Scheduler.Models.csproj", "{1F372AB9-D8DD-D295-1D5E-CB5D454CBB24}" + +EndProject + +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Scheduler.Persistence", "E:\dev\git.stella-ops.org\src\Scheduler\__Libraries\StellaOps.Scheduler.Persistence\StellaOps.Scheduler.Persistence.csproj", "{D96DA724-3A66-14E2-D6CC-F65CEEE71069}" + +EndProject + +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Signer.Core", "E:\dev\git.stella-ops.org\src\Signer\StellaOps.Signer\StellaOps.Signer.Core\StellaOps.Signer.Core.csproj", "{0AF13355-173C-3128-5AFC-D32E540DA3EF}" + +EndProject + +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Signer.Infrastructure", "E:\dev\git.stella-ops.org\src\Signer\StellaOps.Signer\StellaOps.Signer.Infrastructure\StellaOps.Signer.Infrastructure.csproj", "{06BC00C6-78D4-05AD-C8C8-FF64CD7968E0}" + +EndProject + +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Symbols.Client", "E:\dev\git.stella-ops.org\src\Symbols\StellaOps.Symbols.Client\StellaOps.Symbols.Client.csproj", "{FFC170B2-A6F0-A1D7-02BD-16D813C8C8C0}" + +EndProject + +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Symbols.Core", "E:\dev\git.stella-ops.org\src\Symbols\StellaOps.Symbols.Core\StellaOps.Symbols.Core.csproj", "{85B8B27B-51DD-025E-EEED-D44BC0D318B8}" + +EndProject + +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.TestKit", "E:\dev\git.stella-ops.org\src\__Libraries\StellaOps.TestKit\StellaOps.TestKit.csproj", "{AF043113-CCE3-59C1-DF71-9804155F26A8}" + +EndProject + +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Testing.Manifests", "E:\dev\git.stella-ops.org\src\__Tests\__Libraries\StellaOps.Testing.Manifests\StellaOps.Testing.Manifests.csproj", "{9222D186-CD9F-C783-AED5-A3B0E48623BD}" + +EndProject + +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.TimelineIndexer.Core", "E:\dev\git.stella-ops.org\src\TimelineIndexer\StellaOps.TimelineIndexer\StellaOps.TimelineIndexer.Core\StellaOps.TimelineIndexer.Core.csproj", "{10588F6A-E13D-98DC-4EC9-917DCEE382EE}" + +EndProject + +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Verdict", "E:\dev\git.stella-ops.org\src\__Libraries\StellaOps.Verdict\StellaOps.Verdict.csproj", "{E62C8F14-A7CF-47DF-8D60-77308D5D0647}" + +EndProject + +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.VersionComparison", "E:\dev\git.stella-ops.org\src\__Libraries\StellaOps.VersionComparison\StellaOps.VersionComparison.csproj", "{1D761F8B-921C-53BF-DCF5-5ABD329EEB0C}" + +EndProject + +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Policy.Tools", "..\__Libraries\StellaOps.Policy.Tools\StellaOps.Policy.Tools.csproj", "{D484A534-4FE3-4A39-B855-44427C29AEBE}" +EndProject +Global + + GlobalSection(SolutionConfigurationPlatforms) = preSolution + + Debug|Any CPU = Debug|Any CPU + + Release|Any CPU = Release|Any CPU + + EndGlobalSection + + GlobalSection(ProjectConfigurationPlatforms) = postSolution + + {22B129C7-C609-3B90-AD56-64C746A1505E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + + {22B129C7-C609-3B90-AD56-64C746A1505E}.Debug|Any CPU.Build.0 = Debug|Any CPU + + {22B129C7-C609-3B90-AD56-64C746A1505E}.Release|Any CPU.ActiveCfg = Release|Any CPU + + {22B129C7-C609-3B90-AD56-64C746A1505E}.Release|Any CPU.Build.0 = Release|Any CPU + + {AD31623A-BC43-52C2-D906-AC1D8784A541}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + + {AD31623A-BC43-52C2-D906-AC1D8784A541}.Debug|Any CPU.Build.0 = Debug|Any CPU + + {AD31623A-BC43-52C2-D906-AC1D8784A541}.Release|Any CPU.ActiveCfg = Release|Any CPU + + {AD31623A-BC43-52C2-D906-AC1D8784A541}.Release|Any CPU.Build.0 = Release|Any CPU + + {776E2142-804F-03B9-C804-D061D64C6092}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + + {776E2142-804F-03B9-C804-D061D64C6092}.Debug|Any CPU.Build.0 = Debug|Any CPU + + {776E2142-804F-03B9-C804-D061D64C6092}.Release|Any CPU.ActiveCfg = Release|Any CPU + + {776E2142-804F-03B9-C804-D061D64C6092}.Release|Any CPU.Build.0 = Release|Any CPU + + {E106BC8E-B20D-C1B5-130C-DAC28922112A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + + {E106BC8E-B20D-C1B5-130C-DAC28922112A}.Debug|Any CPU.Build.0 = Debug|Any CPU + + {E106BC8E-B20D-C1B5-130C-DAC28922112A}.Release|Any CPU.ActiveCfg = Release|Any CPU + + {E106BC8E-B20D-C1B5-130C-DAC28922112A}.Release|Any CPU.Build.0 = Release|Any CPU + + {5B4DF41E-C8CC-2606-FA2D-967118BD3C59}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + + {5B4DF41E-C8CC-2606-FA2D-967118BD3C59}.Debug|Any CPU.Build.0 = Debug|Any CPU + + {5B4DF41E-C8CC-2606-FA2D-967118BD3C59}.Release|Any CPU.ActiveCfg = Release|Any CPU + + {5B4DF41E-C8CC-2606-FA2D-967118BD3C59}.Release|Any CPU.Build.0 = Release|Any CPU + + {3D8C5A6C-462D-7487-5BD0-A3EF6B657EB6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + + {3D8C5A6C-462D-7487-5BD0-A3EF6B657EB6}.Debug|Any CPU.Build.0 = Debug|Any CPU + + {3D8C5A6C-462D-7487-5BD0-A3EF6B657EB6}.Release|Any CPU.ActiveCfg = Release|Any CPU + + {3D8C5A6C-462D-7487-5BD0-A3EF6B657EB6}.Release|Any CPU.Build.0 = Release|Any CPU + + {2609BC1A-6765-29BE-78CC-C0F1D2814F10}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + + {2609BC1A-6765-29BE-78CC-C0F1D2814F10}.Debug|Any CPU.Build.0 = Debug|Any CPU + + {2609BC1A-6765-29BE-78CC-C0F1D2814F10}.Release|Any CPU.ActiveCfg = Release|Any CPU + + {2609BC1A-6765-29BE-78CC-C0F1D2814F10}.Release|Any CPU.Build.0 = Release|Any CPU + + {C6822231-A4F4-9E69-6CE2-4FDB3E81C728}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + + {C6822231-A4F4-9E69-6CE2-4FDB3E81C728}.Debug|Any CPU.Build.0 = Debug|Any CPU + + {C6822231-A4F4-9E69-6CE2-4FDB3E81C728}.Release|Any CPU.ActiveCfg = Release|Any CPU + + {C6822231-A4F4-9E69-6CE2-4FDB3E81C728}.Release|Any CPU.Build.0 = Release|Any CPU + + {28F2F8EE-CD31-0DEF-446C-D868B139F139}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + + {28F2F8EE-CD31-0DEF-446C-D868B139F139}.Debug|Any CPU.Build.0 = Debug|Any CPU + + {28F2F8EE-CD31-0DEF-446C-D868B139F139}.Release|Any CPU.ActiveCfg = Release|Any CPU + + {28F2F8EE-CD31-0DEF-446C-D868B139F139}.Release|Any CPU.Build.0 = Release|Any CPU + + {55D9B653-FB76-FCE8-1A3C-67B1BEDEC214}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + + {55D9B653-FB76-FCE8-1A3C-67B1BEDEC214}.Debug|Any CPU.Build.0 = Debug|Any CPU + + {55D9B653-FB76-FCE8-1A3C-67B1BEDEC214}.Release|Any CPU.ActiveCfg = Release|Any CPU + + {55D9B653-FB76-FCE8-1A3C-67B1BEDEC214}.Release|Any CPU.Build.0 = Release|Any CPU + + {DE5BF139-1E5C-D6EA-4FAA-661EF353A194}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + + {DE5BF139-1E5C-D6EA-4FAA-661EF353A194}.Debug|Any CPU.Build.0 = Debug|Any CPU + + {DE5BF139-1E5C-D6EA-4FAA-661EF353A194}.Release|Any CPU.ActiveCfg = Release|Any CPU + + {DE5BF139-1E5C-D6EA-4FAA-661EF353A194}.Release|Any CPU.Build.0 = Release|Any CPU + + {335E62C0-9E69-A952-680B-753B1B17C6D0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + + {335E62C0-9E69-A952-680B-753B1B17C6D0}.Debug|Any CPU.Build.0 = Debug|Any CPU + + {335E62C0-9E69-A952-680B-753B1B17C6D0}.Release|Any CPU.ActiveCfg = Release|Any CPU + + {335E62C0-9E69-A952-680B-753B1B17C6D0}.Release|Any CPU.Build.0 = Release|Any CPU + + {5A6CD890-8142-F920-3734-D67CA3E65F61}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + + {5A6CD890-8142-F920-3734-D67CA3E65F61}.Debug|Any CPU.Build.0 = Debug|Any CPU + + {5A6CD890-8142-F920-3734-D67CA3E65F61}.Release|Any CPU.ActiveCfg = Release|Any CPU + + {5A6CD890-8142-F920-3734-D67CA3E65F61}.Release|Any CPU.Build.0 = Release|Any CPU + + {A260E14F-DBA4-862E-53CD-18D3B92ADA3D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + + {A260E14F-DBA4-862E-53CD-18D3B92ADA3D}.Debug|Any CPU.Build.0 = Debug|Any CPU + + {A260E14F-DBA4-862E-53CD-18D3B92ADA3D}.Release|Any CPU.ActiveCfg = Release|Any CPU + + {A260E14F-DBA4-862E-53CD-18D3B92ADA3D}.Release|Any CPU.Build.0 = Release|Any CPU + + {97F94029-5419-6187-5A63-5C8FD9232FAE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + + {97F94029-5419-6187-5A63-5C8FD9232FAE}.Debug|Any CPU.Build.0 = Debug|Any CPU + + {97F94029-5419-6187-5A63-5C8FD9232FAE}.Release|Any CPU.ActiveCfg = Release|Any CPU + + {97F94029-5419-6187-5A63-5C8FD9232FAE}.Release|Any CPU.Build.0 = Release|Any CPU + + {AF9E7F02-25AD-3540-18D7-F6A4F8BA5A60}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + + {AF9E7F02-25AD-3540-18D7-F6A4F8BA5A60}.Debug|Any CPU.Build.0 = Debug|Any CPU + + {AF9E7F02-25AD-3540-18D7-F6A4F8BA5A60}.Release|Any CPU.ActiveCfg = Release|Any CPU + + {AF9E7F02-25AD-3540-18D7-F6A4F8BA5A60}.Release|Any CPU.Build.0 = Release|Any CPU + + {301015C5-1F56-2266-84AA-AB6D83F28893}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + + {301015C5-1F56-2266-84AA-AB6D83F28893}.Debug|Any CPU.Build.0 = Debug|Any CPU + + {301015C5-1F56-2266-84AA-AB6D83F28893}.Release|Any CPU.ActiveCfg = Release|Any CPU + + {301015C5-1F56-2266-84AA-AB6D83F28893}.Release|Any CPU.Build.0 = Release|Any CPU + + {0C51F029-7C57-B767-AFFA-4800230A6B1F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + + {0C51F029-7C57-B767-AFFA-4800230A6B1F}.Debug|Any CPU.Build.0 = Debug|Any CPU + + {0C51F029-7C57-B767-AFFA-4800230A6B1F}.Release|Any CPU.ActiveCfg = Release|Any CPU + + {0C51F029-7C57-B767-AFFA-4800230A6B1F}.Release|Any CPU.Build.0 = Release|Any CPU + + {1BAEE7A9-C442-D76D-8531-AE20501395C7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + + {1BAEE7A9-C442-D76D-8531-AE20501395C7}.Debug|Any CPU.Build.0 = Debug|Any CPU + + {1BAEE7A9-C442-D76D-8531-AE20501395C7}.Release|Any CPU.ActiveCfg = Release|Any CPU + + {1BAEE7A9-C442-D76D-8531-AE20501395C7}.Release|Any CPU.Build.0 = Release|Any CPU + + {E7CCD23E-AFD3-B46F-48B0-908E5BF0825B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + + {E7CCD23E-AFD3-B46F-48B0-908E5BF0825B}.Debug|Any CPU.Build.0 = Debug|Any CPU + + {E7CCD23E-AFD3-B46F-48B0-908E5BF0825B}.Release|Any CPU.ActiveCfg = Release|Any CPU + + {E7CCD23E-AFD3-B46F-48B0-908E5BF0825B}.Release|Any CPU.Build.0 = Release|Any CPU + + {8D3B990F-E832-139D-DDFD-1076A8E0834E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + + {8D3B990F-E832-139D-DDFD-1076A8E0834E}.Debug|Any CPU.Build.0 = Debug|Any CPU + + {8D3B990F-E832-139D-DDFD-1076A8E0834E}.Release|Any CPU.ActiveCfg = Release|Any CPU + + {8D3B990F-E832-139D-DDFD-1076A8E0834E}.Release|Any CPU.Build.0 = Release|Any CPU + + {058E17AA-8F9F-426B-2364-65467F6891F7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + + {058E17AA-8F9F-426B-2364-65467F6891F7}.Debug|Any CPU.Build.0 = Debug|Any CPU + + {058E17AA-8F9F-426B-2364-65467F6891F7}.Release|Any CPU.ActiveCfg = Release|Any CPU + + {058E17AA-8F9F-426B-2364-65467F6891F7}.Release|Any CPU.Build.0 = Release|Any CPU + + {33767BF5-0175-51A7-9B37-9312610359FC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + + {33767BF5-0175-51A7-9B37-9312610359FC}.Debug|Any CPU.Build.0 = Debug|Any CPU + + {33767BF5-0175-51A7-9B37-9312610359FC}.Release|Any CPU.ActiveCfg = Release|Any CPU + + {33767BF5-0175-51A7-9B37-9312610359FC}.Release|Any CPU.Build.0 = Release|Any CPU + + {D1322A50-ABAB-EEFC-17B5-60EDCA13DF8C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + + {D1322A50-ABAB-EEFC-17B5-60EDCA13DF8C}.Debug|Any CPU.Build.0 = Debug|Any CPU + + {D1322A50-ABAB-EEFC-17B5-60EDCA13DF8C}.Release|Any CPU.ActiveCfg = Release|Any CPU + + {D1322A50-ABAB-EEFC-17B5-60EDCA13DF8C}.Release|Any CPU.Build.0 = Release|Any CPU + + {AB6AE2B6-8D6B-2D9F-2A88-7C596C59F4FC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + + {AB6AE2B6-8D6B-2D9F-2A88-7C596C59F4FC}.Debug|Any CPU.Build.0 = Debug|Any CPU + + {AB6AE2B6-8D6B-2D9F-2A88-7C596C59F4FC}.Release|Any CPU.ActiveCfg = Release|Any CPU + + {AB6AE2B6-8D6B-2D9F-2A88-7C596C59F4FC}.Release|Any CPU.Build.0 = Release|Any CPU + + {BA45605A-1CCE-6B0C-489D-C113915B243F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + + {BA45605A-1CCE-6B0C-489D-C113915B243F}.Debug|Any CPU.Build.0 = Debug|Any CPU + + {BA45605A-1CCE-6B0C-489D-C113915B243F}.Release|Any CPU.ActiveCfg = Release|Any CPU + + {BA45605A-1CCE-6B0C-489D-C113915B243F}.Release|Any CPU.Build.0 = Release|Any CPU + + {9D31FC8A-2A69-B78A-D3E5-4F867B16D971}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + + {9D31FC8A-2A69-B78A-D3E5-4F867B16D971}.Debug|Any CPU.Build.0 = Debug|Any CPU + + {9D31FC8A-2A69-B78A-D3E5-4F867B16D971}.Release|Any CPU.ActiveCfg = Release|Any CPU + + {9D31FC8A-2A69-B78A-D3E5-4F867B16D971}.Release|Any CPU.Build.0 = Release|Any CPU + + {92268008-FBB0-C7AD-ECC2-7B75BED9F5E1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + + {92268008-FBB0-C7AD-ECC2-7B75BED9F5E1}.Debug|Any CPU.Build.0 = Debug|Any CPU + + {92268008-FBB0-C7AD-ECC2-7B75BED9F5E1}.Release|Any CPU.ActiveCfg = Release|Any CPU + + {92268008-FBB0-C7AD-ECC2-7B75BED9F5E1}.Release|Any CPU.Build.0 = Release|Any CPU + + {8DCCAF70-D364-4C8B-4E90-AF65091DE0C5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + + {8DCCAF70-D364-4C8B-4E90-AF65091DE0C5}.Debug|Any CPU.Build.0 = Debug|Any CPU + + {8DCCAF70-D364-4C8B-4E90-AF65091DE0C5}.Release|Any CPU.ActiveCfg = Release|Any CPU + + {8DCCAF70-D364-4C8B-4E90-AF65091DE0C5}.Release|Any CPU.Build.0 = Release|Any CPU + + {7828C164-DD01-2809-CCB3-364486834F60}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + + {7828C164-DD01-2809-CCB3-364486834F60}.Debug|Any CPU.Build.0 = Debug|Any CPU + + {7828C164-DD01-2809-CCB3-364486834F60}.Release|Any CPU.ActiveCfg = Release|Any CPU + + {7828C164-DD01-2809-CCB3-364486834F60}.Release|Any CPU.Build.0 = Release|Any CPU + + {DE95E7B2-0937-A980-441F-829E023BC43E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + + {DE95E7B2-0937-A980-441F-829E023BC43E}.Debug|Any CPU.Build.0 = Debug|Any CPU + + {DE95E7B2-0937-A980-441F-829E023BC43E}.Release|Any CPU.ActiveCfg = Release|Any CPU + + {DE95E7B2-0937-A980-441F-829E023BC43E}.Release|Any CPU.Build.0 = Release|Any CPU + + {91D69463-23E2-E2C7-AA7E-A78B13CED620}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + + {91D69463-23E2-E2C7-AA7E-A78B13CED620}.Debug|Any CPU.Build.0 = Debug|Any CPU + + {91D69463-23E2-E2C7-AA7E-A78B13CED620}.Release|Any CPU.ActiveCfg = Release|Any CPU + + {91D69463-23E2-E2C7-AA7E-A78B13CED620}.Release|Any CPU.Build.0 = Release|Any CPU + + {34EFF636-81A7-8DF6-7CC9-4DA784BAC7F3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + + {34EFF636-81A7-8DF6-7CC9-4DA784BAC7F3}.Debug|Any CPU.Build.0 = Debug|Any CPU + + {34EFF636-81A7-8DF6-7CC9-4DA784BAC7F3}.Release|Any CPU.ActiveCfg = Release|Any CPU + + {34EFF636-81A7-8DF6-7CC9-4DA784BAC7F3}.Release|Any CPU.Build.0 = Release|Any CPU + + {5DCF16A8-97C6-2CB4-6A63-0370239039EB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + + {5DCF16A8-97C6-2CB4-6A63-0370239039EB}.Debug|Any CPU.Build.0 = Debug|Any CPU + + {5DCF16A8-97C6-2CB4-6A63-0370239039EB}.Release|Any CPU.ActiveCfg = Release|Any CPU + + {5DCF16A8-97C6-2CB4-6A63-0370239039EB}.Release|Any CPU.Build.0 = Release|Any CPU + + {EB093C48-CDAC-106B-1196-AE34809B34C0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + + {EB093C48-CDAC-106B-1196-AE34809B34C0}.Debug|Any CPU.Build.0 = Debug|Any CPU + + {EB093C48-CDAC-106B-1196-AE34809B34C0}.Release|Any CPU.ActiveCfg = Release|Any CPU + + {EB093C48-CDAC-106B-1196-AE34809B34C0}.Release|Any CPU.Build.0 = Release|Any CPU + + {92C62F7B-8028-6EE1-B71B-F45F459B8E97}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + + {92C62F7B-8028-6EE1-B71B-F45F459B8E97}.Debug|Any CPU.Build.0 = Debug|Any CPU + + {92C62F7B-8028-6EE1-B71B-F45F459B8E97}.Release|Any CPU.ActiveCfg = Release|Any CPU + + {92C62F7B-8028-6EE1-B71B-F45F459B8E97}.Release|Any CPU.Build.0 = Release|Any CPU + + {F664A948-E352-5808-E780-77A03F19E93E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + + {F664A948-E352-5808-E780-77A03F19E93E}.Debug|Any CPU.Build.0 = Debug|Any CPU + + {F664A948-E352-5808-E780-77A03F19E93E}.Release|Any CPU.ActiveCfg = Release|Any CPU + + {F664A948-E352-5808-E780-77A03F19E93E}.Release|Any CPU.Build.0 = Release|Any CPU + + {FA83F778-5252-0B80-5555-E69F790322EA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + + {FA83F778-5252-0B80-5555-E69F790322EA}.Debug|Any CPU.Build.0 = Debug|Any CPU + + {FA83F778-5252-0B80-5555-E69F790322EA}.Release|Any CPU.ActiveCfg = Release|Any CPU + + {FA83F778-5252-0B80-5555-E69F790322EA}.Release|Any CPU.Build.0 = Release|Any CPU + + {F3A27846-6DE0-3448-222C-25A273E86B2E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + + {F3A27846-6DE0-3448-222C-25A273E86B2E}.Debug|Any CPU.Build.0 = Debug|Any CPU + + {F3A27846-6DE0-3448-222C-25A273E86B2E}.Release|Any CPU.ActiveCfg = Release|Any CPU + + {F3A27846-6DE0-3448-222C-25A273E86B2E}.Release|Any CPU.Build.0 = Release|Any CPU + + {166F4DEC-9886-92D5-6496-085664E9F08F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + + {166F4DEC-9886-92D5-6496-085664E9F08F}.Debug|Any CPU.Build.0 = Debug|Any CPU + + {166F4DEC-9886-92D5-6496-085664E9F08F}.Release|Any CPU.ActiveCfg = Release|Any CPU + + {166F4DEC-9886-92D5-6496-085664E9F08F}.Release|Any CPU.Build.0 = Release|Any CPU + + {C53E0895-879A-D9E6-0A43-24AD17A2F270}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + + {C53E0895-879A-D9E6-0A43-24AD17A2F270}.Debug|Any CPU.Build.0 = Debug|Any CPU + + {C53E0895-879A-D9E6-0A43-24AD17A2F270}.Release|Any CPU.ActiveCfg = Release|Any CPU + + {C53E0895-879A-D9E6-0A43-24AD17A2F270}.Release|Any CPU.Build.0 = Release|Any CPU + + {1EE42F0F-3F9A-613C-D01F-8BCDB4C42C0E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + + {1EE42F0F-3F9A-613C-D01F-8BCDB4C42C0E}.Debug|Any CPU.Build.0 = Debug|Any CPU + + {1EE42F0F-3F9A-613C-D01F-8BCDB4C42C0E}.Release|Any CPU.ActiveCfg = Release|Any CPU + + {1EE42F0F-3F9A-613C-D01F-8BCDB4C42C0E}.Release|Any CPU.Build.0 = Release|Any CPU + + {246FCC7C-1437-742D-BAE5-E77A24164F08}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + + {246FCC7C-1437-742D-BAE5-E77A24164F08}.Debug|Any CPU.Build.0 = Debug|Any CPU + + {246FCC7C-1437-742D-BAE5-E77A24164F08}.Release|Any CPU.ActiveCfg = Release|Any CPU + + {246FCC7C-1437-742D-BAE5-E77A24164F08}.Release|Any CPU.Build.0 = Release|Any CPU + + {0AED303F-69E6-238F-EF80-81985080EDB7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + + {0AED303F-69E6-238F-EF80-81985080EDB7}.Debug|Any CPU.Build.0 = Debug|Any CPU + + {0AED303F-69E6-238F-EF80-81985080EDB7}.Release|Any CPU.ActiveCfg = Release|Any CPU + + {0AED303F-69E6-238F-EF80-81985080EDB7}.Release|Any CPU.Build.0 = Release|Any CPU + + {2904D288-CE64-A565-2C46-C2E85A96A1EE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + + {2904D288-CE64-A565-2C46-C2E85A96A1EE}.Debug|Any CPU.Build.0 = Debug|Any CPU + + {2904D288-CE64-A565-2C46-C2E85A96A1EE}.Release|Any CPU.ActiveCfg = Release|Any CPU + + {2904D288-CE64-A565-2C46-C2E85A96A1EE}.Release|Any CPU.Build.0 = Release|Any CPU + + {A6667CC3-B77F-023E-3A67-05F99E9FF46A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + + {A6667CC3-B77F-023E-3A67-05F99E9FF46A}.Debug|Any CPU.Build.0 = Debug|Any CPU + + {A6667CC3-B77F-023E-3A67-05F99E9FF46A}.Release|Any CPU.ActiveCfg = Release|Any CPU + + {A6667CC3-B77F-023E-3A67-05F99E9FF46A}.Release|Any CPU.Build.0 = Release|Any CPU + + {A26E2816-F787-F76B-1D6C-E086DD3E19CE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + + {A26E2816-F787-F76B-1D6C-E086DD3E19CE}.Debug|Any CPU.Build.0 = Debug|Any CPU + + {A26E2816-F787-F76B-1D6C-E086DD3E19CE}.Release|Any CPU.ActiveCfg = Release|Any CPU + + {A26E2816-F787-F76B-1D6C-E086DD3E19CE}.Release|Any CPU.Build.0 = Release|Any CPU + + {B3DEC619-67AC-1B5A-4F3E-A1F24C3F6877}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + + {B3DEC619-67AC-1B5A-4F3E-A1F24C3F6877}.Debug|Any CPU.Build.0 = Debug|Any CPU + + {B3DEC619-67AC-1B5A-4F3E-A1F24C3F6877}.Release|Any CPU.ActiveCfg = Release|Any CPU + + {B3DEC619-67AC-1B5A-4F3E-A1F24C3F6877}.Release|Any CPU.Build.0 = Release|Any CPU + + {90DB65B4-8F6E-FB8E-0281-505AD8BC6BA6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + + {90DB65B4-8F6E-FB8E-0281-505AD8BC6BA6}.Debug|Any CPU.Build.0 = Debug|Any CPU + + {90DB65B4-8F6E-FB8E-0281-505AD8BC6BA6}.Release|Any CPU.ActiveCfg = Release|Any CPU + + {90DB65B4-8F6E-FB8E-0281-505AD8BC6BA6}.Release|Any CPU.Build.0 = Release|Any CPU + + {059FBB86-DEE6-8207-3F23-2A1A3EC00DEA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + + {059FBB86-DEE6-8207-3F23-2A1A3EC00DEA}.Debug|Any CPU.Build.0 = Debug|Any CPU + + {059FBB86-DEE6-8207-3F23-2A1A3EC00DEA}.Release|Any CPU.ActiveCfg = Release|Any CPU + + {059FBB86-DEE6-8207-3F23-2A1A3EC00DEA}.Release|Any CPU.Build.0 = Release|Any CPU + + {8BBA3159-C4CC-F685-A28C-7FE6CBD3D2A1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + + {8BBA3159-C4CC-F685-A28C-7FE6CBD3D2A1}.Debug|Any CPU.Build.0 = Debug|Any CPU + + {8BBA3159-C4CC-F685-A28C-7FE6CBD3D2A1}.Release|Any CPU.ActiveCfg = Release|Any CPU + + {8BBA3159-C4CC-F685-A28C-7FE6CBD3D2A1}.Release|Any CPU.Build.0 = Release|Any CPU + + {EA0974E3-CD2B-5792-EF1E-9B5B7CCBDF00}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + + {EA0974E3-CD2B-5792-EF1E-9B5B7CCBDF00}.Debug|Any CPU.Build.0 = Debug|Any CPU + + {EA0974E3-CD2B-5792-EF1E-9B5B7CCBDF00}.Release|Any CPU.ActiveCfg = Release|Any CPU + + {EA0974E3-CD2B-5792-EF1E-9B5B7CCBDF00}.Release|Any CPU.Build.0 = Release|Any CPU + + {632A1F0D-1BA5-C84B-B716-2BE638A92780}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + + {632A1F0D-1BA5-C84B-B716-2BE638A92780}.Debug|Any CPU.Build.0 = Debug|Any CPU + + {632A1F0D-1BA5-C84B-B716-2BE638A92780}.Release|Any CPU.ActiveCfg = Release|Any CPU + + {632A1F0D-1BA5-C84B-B716-2BE638A92780}.Release|Any CPU.Build.0 = Release|Any CPU + + {9DE7852B-7E2D-257E-B0F1-45D2687854ED}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + + {9DE7852B-7E2D-257E-B0F1-45D2687854ED}.Debug|Any CPU.Build.0 = Debug|Any CPU + + {9DE7852B-7E2D-257E-B0F1-45D2687854ED}.Release|Any CPU.ActiveCfg = Release|Any CPU + + {9DE7852B-7E2D-257E-B0F1-45D2687854ED}.Release|Any CPU.Build.0 = Release|Any CPU + + {DC2AFC89-C3C8-4E9B-13A7-027EB6386EFA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + + {DC2AFC89-C3C8-4E9B-13A7-027EB6386EFA}.Debug|Any CPU.Build.0 = Debug|Any CPU + + {DC2AFC89-C3C8-4E9B-13A7-027EB6386EFA}.Release|Any CPU.ActiveCfg = Release|Any CPU + + {DC2AFC89-C3C8-4E9B-13A7-027EB6386EFA}.Release|Any CPU.Build.0 = Release|Any CPU + + {9151601C-8784-01A6-C2E7-A5C0FAAB0AEF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + + {9151601C-8784-01A6-C2E7-A5C0FAAB0AEF}.Debug|Any CPU.Build.0 = Debug|Any CPU + + {9151601C-8784-01A6-C2E7-A5C0FAAB0AEF}.Release|Any CPU.ActiveCfg = Release|Any CPU + + {9151601C-8784-01A6-C2E7-A5C0FAAB0AEF}.Release|Any CPU.Build.0 = Release|Any CPU + + {4F1EE2D9-9392-6A1C-7224-6B01FAB934E3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + + {4F1EE2D9-9392-6A1C-7224-6B01FAB934E3}.Debug|Any CPU.Build.0 = Debug|Any CPU + + {4F1EE2D9-9392-6A1C-7224-6B01FAB934E3}.Release|Any CPU.ActiveCfg = Release|Any CPU + + {4F1EE2D9-9392-6A1C-7224-6B01FAB934E3}.Release|Any CPU.Build.0 = Release|Any CPU + + {104A930A-6D8F-8C36-2CB5-0BC4F8FD74D2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + + {104A930A-6D8F-8C36-2CB5-0BC4F8FD74D2}.Debug|Any CPU.Build.0 = Debug|Any CPU + + {104A930A-6D8F-8C36-2CB5-0BC4F8FD74D2}.Release|Any CPU.ActiveCfg = Release|Any CPU + + {104A930A-6D8F-8C36-2CB5-0BC4F8FD74D2}.Release|Any CPU.Build.0 = Release|Any CPU + + {F7947A80-F07C-2FBF-77F8-DDFA57951A97}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + + {F7947A80-F07C-2FBF-77F8-DDFA57951A97}.Debug|Any CPU.Build.0 = Debug|Any CPU + + {F7947A80-F07C-2FBF-77F8-DDFA57951A97}.Release|Any CPU.ActiveCfg = Release|Any CPU + + {F7947A80-F07C-2FBF-77F8-DDFA57951A97}.Release|Any CPU.Build.0 = Release|Any CPU + + {CB296A20-2732-77C1-7F23-27D5BAEDD0C7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + + {CB296A20-2732-77C1-7F23-27D5BAEDD0C7}.Debug|Any CPU.Build.0 = Debug|Any CPU + + {CB296A20-2732-77C1-7F23-27D5BAEDD0C7}.Release|Any CPU.ActiveCfg = Release|Any CPU + + {CB296A20-2732-77C1-7F23-27D5BAEDD0C7}.Release|Any CPU.Build.0 = Release|Any CPU + + {0DBEC9BA-FE1D-3898-B2C6-E4357DC23E0F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + + {0DBEC9BA-FE1D-3898-B2C6-E4357DC23E0F}.Debug|Any CPU.Build.0 = Debug|Any CPU + + {0DBEC9BA-FE1D-3898-B2C6-E4357DC23E0F}.Release|Any CPU.ActiveCfg = Release|Any CPU + + {0DBEC9BA-FE1D-3898-B2C6-E4357DC23E0F}.Release|Any CPU.Build.0 = Release|Any CPU + + {A63897D9-9531-989B-7309-E384BCFC2BB9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + + {A63897D9-9531-989B-7309-E384BCFC2BB9}.Debug|Any CPU.Build.0 = Debug|Any CPU + + {A63897D9-9531-989B-7309-E384BCFC2BB9}.Release|Any CPU.ActiveCfg = Release|Any CPU + + {A63897D9-9531-989B-7309-E384BCFC2BB9}.Release|Any CPU.Build.0 = Release|Any CPU + + {8C594D82-3463-3367-4F06-900AC707753D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + + {8C594D82-3463-3367-4F06-900AC707753D}.Debug|Any CPU.Build.0 = Debug|Any CPU + + {8C594D82-3463-3367-4F06-900AC707753D}.Release|Any CPU.ActiveCfg = Release|Any CPU + + {8C594D82-3463-3367-4F06-900AC707753D}.Release|Any CPU.Build.0 = Release|Any CPU + + {9588FBF9-C37E-D16E-2E8F-CFA226EAC01D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + + {9588FBF9-C37E-D16E-2E8F-CFA226EAC01D}.Debug|Any CPU.Build.0 = Debug|Any CPU + + {9588FBF9-C37E-D16E-2E8F-CFA226EAC01D}.Release|Any CPU.ActiveCfg = Release|Any CPU + + {9588FBF9-C37E-D16E-2E8F-CFA226EAC01D}.Release|Any CPU.Build.0 = Release|Any CPU + + {97998C88-E6E1-D5E2-B632-537B58E00CBF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + + {97998C88-E6E1-D5E2-B632-537B58E00CBF}.Debug|Any CPU.Build.0 = Debug|Any CPU + + {97998C88-E6E1-D5E2-B632-537B58E00CBF}.Release|Any CPU.ActiveCfg = Release|Any CPU + + {97998C88-E6E1-D5E2-B632-537B58E00CBF}.Release|Any CPU.Build.0 = Release|Any CPU + + {20D1569C-2A47-38B8-075E-47225B674394}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + + {20D1569C-2A47-38B8-075E-47225B674394}.Debug|Any CPU.Build.0 = Debug|Any CPU + + {20D1569C-2A47-38B8-075E-47225B674394}.Release|Any CPU.ActiveCfg = Release|Any CPU + + {20D1569C-2A47-38B8-075E-47225B674394}.Release|Any CPU.Build.0 = Release|Any CPU + + {2F7AA715-25AE-086A-7DF4-CAB5EF00E2B7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + + {2F7AA715-25AE-086A-7DF4-CAB5EF00E2B7}.Debug|Any CPU.Build.0 = Debug|Any CPU + + {2F7AA715-25AE-086A-7DF4-CAB5EF00E2B7}.Release|Any CPU.ActiveCfg = Release|Any CPU + + {2F7AA715-25AE-086A-7DF4-CAB5EF00E2B7}.Release|Any CPU.Build.0 = Release|Any CPU + + {38A9EE9B-6FC8-93BC-0D43-2A906E678D66}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + + {38A9EE9B-6FC8-93BC-0D43-2A906E678D66}.Debug|Any CPU.Build.0 = Debug|Any CPU + + {38A9EE9B-6FC8-93BC-0D43-2A906E678D66}.Release|Any CPU.ActiveCfg = Release|Any CPU + + {38A9EE9B-6FC8-93BC-0D43-2A906E678D66}.Release|Any CPU.Build.0 = Release|Any CPU + + {19868E2D-7163-2108-1094-F13887C4F070}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + + {19868E2D-7163-2108-1094-F13887C4F070}.Debug|Any CPU.Build.0 = Debug|Any CPU + + {19868E2D-7163-2108-1094-F13887C4F070}.Release|Any CPU.ActiveCfg = Release|Any CPU + + {19868E2D-7163-2108-1094-F13887C4F070}.Release|Any CPU.Build.0 = Release|Any CPU + + {7D3FC972-467A-4917-8339-9B6462C6A38A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + + {7D3FC972-467A-4917-8339-9B6462C6A38A}.Debug|Any CPU.Build.0 = Debug|Any CPU + + {7D3FC972-467A-4917-8339-9B6462C6A38A}.Release|Any CPU.ActiveCfg = Release|Any CPU + + {7D3FC972-467A-4917-8339-9B6462C6A38A}.Release|Any CPU.Build.0 = Release|Any CPU + + {C154051B-DB4E-5270-AF5A-12A0FFE0E769}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + + {C154051B-DB4E-5270-AF5A-12A0FFE0E769}.Debug|Any CPU.Build.0 = Debug|Any CPU + + {C154051B-DB4E-5270-AF5A-12A0FFE0E769}.Release|Any CPU.ActiveCfg = Release|Any CPU + + {C154051B-DB4E-5270-AF5A-12A0FFE0E769}.Release|Any CPU.Build.0 = Release|Any CPU + + {CC319FC5-F4B1-C3DD-7310-4DAD343E0125}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + + {CC319FC5-F4B1-C3DD-7310-4DAD343E0125}.Debug|Any CPU.Build.0 = Debug|Any CPU + + {CC319FC5-F4B1-C3DD-7310-4DAD343E0125}.Release|Any CPU.ActiveCfg = Release|Any CPU + + {CC319FC5-F4B1-C3DD-7310-4DAD343E0125}.Release|Any CPU.Build.0 = Release|Any CPU + + {CD6B144E-BCDD-D4FE-2749-703DAB054EBC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + + {CD6B144E-BCDD-D4FE-2749-703DAB054EBC}.Debug|Any CPU.Build.0 = Debug|Any CPU + + {CD6B144E-BCDD-D4FE-2749-703DAB054EBC}.Release|Any CPU.ActiveCfg = Release|Any CPU + + {CD6B144E-BCDD-D4FE-2749-703DAB054EBC}.Release|Any CPU.Build.0 = Release|Any CPU + + {B46D185B-A630-8F76-E61B-90084FBF65B0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + + {B46D185B-A630-8F76-E61B-90084FBF65B0}.Debug|Any CPU.Build.0 = Debug|Any CPU + + {B46D185B-A630-8F76-E61B-90084FBF65B0}.Release|Any CPU.ActiveCfg = Release|Any CPU + + {B46D185B-A630-8F76-E61B-90084FBF65B0}.Release|Any CPU.Build.0 = Release|Any CPU + + {84F711C2-C210-28D2-F0D9-B13733FEE23D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + + {84F711C2-C210-28D2-F0D9-B13733FEE23D}.Debug|Any CPU.Build.0 = Debug|Any CPU + + {84F711C2-C210-28D2-F0D9-B13733FEE23D}.Release|Any CPU.ActiveCfg = Release|Any CPU + + {84F711C2-C210-28D2-F0D9-B13733FEE23D}.Release|Any CPU.Build.0 = Release|Any CPU + + {CBB14B90-27F9-8DD6-DFC4-3507DBD1FBC6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + + {CBB14B90-27F9-8DD6-DFC4-3507DBD1FBC6}.Debug|Any CPU.Build.0 = Debug|Any CPU + + {CBB14B90-27F9-8DD6-DFC4-3507DBD1FBC6}.Release|Any CPU.ActiveCfg = Release|Any CPU + + {CBB14B90-27F9-8DD6-DFC4-3507DBD1FBC6}.Release|Any CPU.Build.0 = Release|Any CPU + + {A78EBC0F-C62C-8F56-95C0-330E376242A2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + + {A78EBC0F-C62C-8F56-95C0-330E376242A2}.Debug|Any CPU.Build.0 = Debug|Any CPU + + {A78EBC0F-C62C-8F56-95C0-330E376242A2}.Release|Any CPU.ActiveCfg = Release|Any CPU + + {A78EBC0F-C62C-8F56-95C0-330E376242A2}.Release|Any CPU.Build.0 = Release|Any CPU + + {6D26FB21-7E48-024B-E5D4-E3F0F31976BB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + + {6D26FB21-7E48-024B-E5D4-E3F0F31976BB}.Debug|Any CPU.Build.0 = Debug|Any CPU + + {6D26FB21-7E48-024B-E5D4-E3F0F31976BB}.Release|Any CPU.ActiveCfg = Release|Any CPU + + {6D26FB21-7E48-024B-E5D4-E3F0F31976BB}.Release|Any CPU.Build.0 = Release|Any CPU + + {28D91816-206C-576E-1A83-FD98E08C2E3C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + + {28D91816-206C-576E-1A83-FD98E08C2E3C}.Debug|Any CPU.Build.0 = Debug|Any CPU + + {28D91816-206C-576E-1A83-FD98E08C2E3C}.Release|Any CPU.ActiveCfg = Release|Any CPU + + {28D91816-206C-576E-1A83-FD98E08C2E3C}.Release|Any CPU.Build.0 = Release|Any CPU + + {5EFEC79C-A9F1-96A4-692C-733566107170}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + + {5EFEC79C-A9F1-96A4-692C-733566107170}.Debug|Any CPU.Build.0 = Debug|Any CPU + + {5EFEC79C-A9F1-96A4-692C-733566107170}.Release|Any CPU.ActiveCfg = Release|Any CPU + + {5EFEC79C-A9F1-96A4-692C-733566107170}.Release|Any CPU.Build.0 = Release|Any CPU + + {B7B5D764-C3A0-1743-0739-29966F993626}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + + {B7B5D764-C3A0-1743-0739-29966F993626}.Debug|Any CPU.Build.0 = Debug|Any CPU + + {B7B5D764-C3A0-1743-0739-29966F993626}.Release|Any CPU.ActiveCfg = Release|Any CPU + + {B7B5D764-C3A0-1743-0739-29966F993626}.Release|Any CPU.Build.0 = Release|Any CPU + + {C4EDBBAF-875C-4839-05A8-F6F12A5ED52D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + + {C4EDBBAF-875C-4839-05A8-F6F12A5ED52D}.Debug|Any CPU.Build.0 = Debug|Any CPU + + {C4EDBBAF-875C-4839-05A8-F6F12A5ED52D}.Release|Any CPU.ActiveCfg = Release|Any CPU + + {C4EDBBAF-875C-4839-05A8-F6F12A5ED52D}.Release|Any CPU.Build.0 = Release|Any CPU + + {0EAC8F64-9588-1EF0-C33A-67590CF27590}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + + {0EAC8F64-9588-1EF0-C33A-67590CF27590}.Debug|Any CPU.Build.0 = Debug|Any CPU + + {0EAC8F64-9588-1EF0-C33A-67590CF27590}.Release|Any CPU.ActiveCfg = Release|Any CPU + + {0EAC8F64-9588-1EF0-C33A-67590CF27590}.Release|Any CPU.Build.0 = Release|Any CPU + + {B1B31937-CCC8-D97A-F66D-1849734B780B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + + {B1B31937-CCC8-D97A-F66D-1849734B780B}.Debug|Any CPU.Build.0 = Debug|Any CPU + + {B1B31937-CCC8-D97A-F66D-1849734B780B}.Release|Any CPU.ActiveCfg = Release|Any CPU + + {B1B31937-CCC8-D97A-F66D-1849734B780B}.Release|Any CPU.Build.0 = Release|Any CPU + + {A345E5AC-BDDB-A817-3C92-08C8865D1EF9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + + {A345E5AC-BDDB-A817-3C92-08C8865D1EF9}.Debug|Any CPU.Build.0 = Debug|Any CPU + + {A345E5AC-BDDB-A817-3C92-08C8865D1EF9}.Release|Any CPU.ActiveCfg = Release|Any CPU + + {A345E5AC-BDDB-A817-3C92-08C8865D1EF9}.Release|Any CPU.Build.0 = Release|Any CPU + + {58D8630F-C0F4-B772-8572-BCC98FF0F0D8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + + {58D8630F-C0F4-B772-8572-BCC98FF0F0D8}.Debug|Any CPU.Build.0 = Debug|Any CPU + + {58D8630F-C0F4-B772-8572-BCC98FF0F0D8}.Release|Any CPU.ActiveCfg = Release|Any CPU + + {58D8630F-C0F4-B772-8572-BCC98FF0F0D8}.Release|Any CPU.Build.0 = Release|Any CPU + + {D24E7862-3930-A4F6-1DFA-DA88C759546C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + + {D24E7862-3930-A4F6-1DFA-DA88C759546C}.Debug|Any CPU.Build.0 = Debug|Any CPU + + {D24E7862-3930-A4F6-1DFA-DA88C759546C}.Release|Any CPU.ActiveCfg = Release|Any CPU + + {D24E7862-3930-A4F6-1DFA-DA88C759546C}.Release|Any CPU.Build.0 = Release|Any CPU + + {7CB7FEA8-8A12-A5D6-0057-AA65DB328617}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + + {7CB7FEA8-8A12-A5D6-0057-AA65DB328617}.Debug|Any CPU.Build.0 = Debug|Any CPU + + {7CB7FEA8-8A12-A5D6-0057-AA65DB328617}.Release|Any CPU.ActiveCfg = Release|Any CPU + + {7CB7FEA8-8A12-A5D6-0057-AA65DB328617}.Release|Any CPU.Build.0 = Release|Any CPU + + {52698305-D6F8-C13C-0882-48FC37726404}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + + {52698305-D6F8-C13C-0882-48FC37726404}.Debug|Any CPU.Build.0 = Debug|Any CPU + + {52698305-D6F8-C13C-0882-48FC37726404}.Release|Any CPU.ActiveCfg = Release|Any CPU + + {52698305-D6F8-C13C-0882-48FC37726404}.Release|Any CPU.Build.0 = Release|Any CPU + + {5567139C-0365-B6A0-5DD0-978A09B9F176}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + + {5567139C-0365-B6A0-5DD0-978A09B9F176}.Debug|Any CPU.Build.0 = Debug|Any CPU + + {5567139C-0365-B6A0-5DD0-978A09B9F176}.Release|Any CPU.ActiveCfg = Release|Any CPU + + {5567139C-0365-B6A0-5DD0-978A09B9F176}.Release|Any CPU.Build.0 = Release|Any CPU + + {256D269B-35EA-F833-2F1D-8E0058908DEE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + + {256D269B-35EA-F833-2F1D-8E0058908DEE}.Debug|Any CPU.Build.0 = Debug|Any CPU + + {256D269B-35EA-F833-2F1D-8E0058908DEE}.Release|Any CPU.ActiveCfg = Release|Any CPU + + {256D269B-35EA-F833-2F1D-8E0058908DEE}.Release|Any CPU.Build.0 = Release|Any CPU + + {6E9C9582-67FA-2EB1-C6BA-AD4CD326E276}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + + {6E9C9582-67FA-2EB1-C6BA-AD4CD326E276}.Debug|Any CPU.Build.0 = Debug|Any CPU + + {6E9C9582-67FA-2EB1-C6BA-AD4CD326E276}.Release|Any CPU.ActiveCfg = Release|Any CPU + + {6E9C9582-67FA-2EB1-C6BA-AD4CD326E276}.Release|Any CPU.Build.0 = Release|Any CPU + + {1F372AB9-D8DD-D295-1D5E-CB5D454CBB24}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + + {1F372AB9-D8DD-D295-1D5E-CB5D454CBB24}.Debug|Any CPU.Build.0 = Debug|Any CPU + + {1F372AB9-D8DD-D295-1D5E-CB5D454CBB24}.Release|Any CPU.ActiveCfg = Release|Any CPU + + {1F372AB9-D8DD-D295-1D5E-CB5D454CBB24}.Release|Any CPU.Build.0 = Release|Any CPU + + {D96DA724-3A66-14E2-D6CC-F65CEEE71069}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + + {D96DA724-3A66-14E2-D6CC-F65CEEE71069}.Debug|Any CPU.Build.0 = Debug|Any CPU + + {D96DA724-3A66-14E2-D6CC-F65CEEE71069}.Release|Any CPU.ActiveCfg = Release|Any CPU + + {D96DA724-3A66-14E2-D6CC-F65CEEE71069}.Release|Any CPU.Build.0 = Release|Any CPU + + {0AF13355-173C-3128-5AFC-D32E540DA3EF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + + {0AF13355-173C-3128-5AFC-D32E540DA3EF}.Debug|Any CPU.Build.0 = Debug|Any CPU + + {0AF13355-173C-3128-5AFC-D32E540DA3EF}.Release|Any CPU.ActiveCfg = Release|Any CPU + + {0AF13355-173C-3128-5AFC-D32E540DA3EF}.Release|Any CPU.Build.0 = Release|Any CPU + + {06BC00C6-78D4-05AD-C8C8-FF64CD7968E0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + + {06BC00C6-78D4-05AD-C8C8-FF64CD7968E0}.Debug|Any CPU.Build.0 = Debug|Any CPU + + {06BC00C6-78D4-05AD-C8C8-FF64CD7968E0}.Release|Any CPU.ActiveCfg = Release|Any CPU + + {06BC00C6-78D4-05AD-C8C8-FF64CD7968E0}.Release|Any CPU.Build.0 = Release|Any CPU + + {FFC170B2-A6F0-A1D7-02BD-16D813C8C8C0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + + {FFC170B2-A6F0-A1D7-02BD-16D813C8C8C0}.Debug|Any CPU.Build.0 = Debug|Any CPU + + {FFC170B2-A6F0-A1D7-02BD-16D813C8C8C0}.Release|Any CPU.ActiveCfg = Release|Any CPU + + {FFC170B2-A6F0-A1D7-02BD-16D813C8C8C0}.Release|Any CPU.Build.0 = Release|Any CPU + + {85B8B27B-51DD-025E-EEED-D44BC0D318B8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + + {85B8B27B-51DD-025E-EEED-D44BC0D318B8}.Debug|Any CPU.Build.0 = Debug|Any CPU + + {85B8B27B-51DD-025E-EEED-D44BC0D318B8}.Release|Any CPU.ActiveCfg = Release|Any CPU + + {85B8B27B-51DD-025E-EEED-D44BC0D318B8}.Release|Any CPU.Build.0 = Release|Any CPU + + {AF043113-CCE3-59C1-DF71-9804155F26A8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + + {AF043113-CCE3-59C1-DF71-9804155F26A8}.Debug|Any CPU.Build.0 = Debug|Any CPU + + {AF043113-CCE3-59C1-DF71-9804155F26A8}.Release|Any CPU.ActiveCfg = Release|Any CPU + + {AF043113-CCE3-59C1-DF71-9804155F26A8}.Release|Any CPU.Build.0 = Release|Any CPU + + {9222D186-CD9F-C783-AED5-A3B0E48623BD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + + {9222D186-CD9F-C783-AED5-A3B0E48623BD}.Debug|Any CPU.Build.0 = Debug|Any CPU + + {9222D186-CD9F-C783-AED5-A3B0E48623BD}.Release|Any CPU.ActiveCfg = Release|Any CPU + + {9222D186-CD9F-C783-AED5-A3B0E48623BD}.Release|Any CPU.Build.0 = Release|Any CPU + + {10588F6A-E13D-98DC-4EC9-917DCEE382EE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + + {10588F6A-E13D-98DC-4EC9-917DCEE382EE}.Debug|Any CPU.Build.0 = Debug|Any CPU + + {10588F6A-E13D-98DC-4EC9-917DCEE382EE}.Release|Any CPU.ActiveCfg = Release|Any CPU + + {10588F6A-E13D-98DC-4EC9-917DCEE382EE}.Release|Any CPU.Build.0 = Release|Any CPU + + {E62C8F14-A7CF-47DF-8D60-77308D5D0647}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + + {E62C8F14-A7CF-47DF-8D60-77308D5D0647}.Debug|Any CPU.Build.0 = Debug|Any CPU + + {E62C8F14-A7CF-47DF-8D60-77308D5D0647}.Release|Any CPU.ActiveCfg = Release|Any CPU + + {E62C8F14-A7CF-47DF-8D60-77308D5D0647}.Release|Any CPU.Build.0 = Release|Any CPU + + {1D761F8B-921C-53BF-DCF5-5ABD329EEB0C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + + {1D761F8B-921C-53BF-DCF5-5ABD329EEB0C}.Debug|Any CPU.Build.0 = Debug|Any CPU + + {1D761F8B-921C-53BF-DCF5-5ABD329EEB0C}.Release|Any CPU.ActiveCfg = Release|Any CPU + + {1D761F8B-921C-53BF-DCF5-5ABD329EEB0C}.Release|Any CPU.Build.0 = Release|Any CPU + + EndGlobalSection + + GlobalSection(SolutionProperties) = preSolution + + HideSolutionNode = FALSE + + EndGlobalSection + + GlobalSection(NestedProjects) = preSolution + + {F310596E-88BB-9E54-885E-21C61971917E} = {5B52EF8A-3661-DCFF-797D-BC4D6AC60BDA} + + {EA6E5683-3A20-2E52-1CE6-AE0D6D36AC4D} = {F310596E-88BB-9E54-885E-21C61971917E} + + {D9492ED1-A812-924B-65E4-F518592B49BB} = {F310596E-88BB-9E54-885E-21C61971917E} + + {3823DE1E-2ACE-C956-99E1-00DB786D9E1D} = {D9492ED1-A812-924B-65E4-F518592B49BB} + + {03DFF14F-7321-1784-D4C7-4E99D4120F48} = {5B52EF8A-3661-DCFF-797D-BC4D6AC60BDA} + + {BDD326D6-7616-84F0-B914-74743BFBA520} = {03DFF14F-7321-1784-D4C7-4E99D4120F48} + + {EC506DBE-AB6D-492E-786E-8B176021BF2E} = {BDD326D6-7616-84F0-B914-74743BFBA520} + + {5AC09D9A-F2A5-9CFA-B3C5-8D25F257651C} = {5B52EF8A-3661-DCFF-797D-BC4D6AC60BDA} + + {0B71A5C2-A1C9-BB93-6042-23D1CEE5AD68} = {5AC09D9A-F2A5-9CFA-B3C5-8D25F257651C} + + {33B1AE27-692A-1778-48C1-CCEC2B9BC78F} = {5AC09D9A-F2A5-9CFA-B3C5-8D25F257651C} + + {018E0E11-1CCE-A2BE-641D-21EE14D2E90D} = {5AC09D9A-F2A5-9CFA-B3C5-8D25F257651C} + + {5F27FB4E-CF09-3A6B-F5B4-BF5A709FA609} = {33B1AE27-692A-1778-48C1-CCEC2B9BC78F} + + {AB67BDB9-D701-3AC9-9CDF-ECCDCCD8DB6D} = {5AC09D9A-F2A5-9CFA-B3C5-8D25F257651C} + + {3F605548-87E2-8A1D-306D-0CE6960B8242} = {AB67BDB9-D701-3AC9-9CDF-ECCDCCD8DB6D} + + {45F7FA87-7451-6970-7F6E-F8BAE45E081B} = {AB67BDB9-D701-3AC9-9CDF-ECCDCCD8DB6D} + + {C1DCEFBD-12A5-EAAE-632E-8EEB9BE491B6} = {5B52EF8A-3661-DCFF-797D-BC4D6AC60BDA} + + {A6928CBA-4D4D-AB2B-CA19-FEE6E73ECE70} = {C1DCEFBD-12A5-EAAE-632E-8EEB9BE491B6} + + {F2E6CB0E-DF77-1FAA-582B-62B040DF3848} = {A6928CBA-4D4D-AB2B-CA19-FEE6E73ECE70} + + {C494ECBE-DEA5-3576-D2AF-200FF12BC144} = {A6928CBA-4D4D-AB2B-CA19-FEE6E73ECE70} + + {64689413-46D7-8499-68A6-B6367ACBC597} = {A6928CBA-4D4D-AB2B-CA19-FEE6E73ECE70} + + {5827F4DE-0AA7-FC85-641D-09E3D890DB27} = {C1DCEFBD-12A5-EAAE-632E-8EEB9BE491B6} + + {9BD75659-58CB-06D1-E198-C39007E82C6A} = {5827F4DE-0AA7-FC85-641D-09E3D890DB27} + + {7BF13935-F1DD-D23B-8347-DB1550C69D69} = {5827F4DE-0AA7-FC85-641D-09E3D890DB27} + + {157C3671-CA0B-69FA-A7C9-74A1FDA97B99} = {5B52EF8A-3661-DCFF-797D-BC4D6AC60BDA} + + {F39E09D6-BF93-B64A-CFE7-2BA92815C0FE} = {157C3671-CA0B-69FA-A7C9-74A1FDA97B99} + + {39EFDA5B-F5EE-8212-D5BA-90E1B82013E7} = {F39E09D6-BF93-B64A-CFE7-2BA92815C0FE} + + {6844B539-C2A3-9D4F-139D-9D533BCABADA} = {F39E09D6-BF93-B64A-CFE7-2BA92815C0FE} + + {4263AA71-0335-3F44-9A9B-423C3A3D05E6} = {F39E09D6-BF93-B64A-CFE7-2BA92815C0FE} + + {F1B1DB47-D2D7-59CB-679B-23E4928E8328} = {F39E09D6-BF93-B64A-CFE7-2BA92815C0FE} + + {BC35DE94-4F04-3436-27A3-F11647FEDD5C} = {F39E09D6-BF93-B64A-CFE7-2BA92815C0FE} + + {864C8B80-771A-0C15-30A5-558F99006E0D} = {F39E09D6-BF93-B64A-CFE7-2BA92815C0FE} + + {603E7A23-1D6B-D3A9-B0E6-3E332B13ED5C} = {F39E09D6-BF93-B64A-CFE7-2BA92815C0FE} + + {D2F7E58B-47D4-5205-D917-144CA1CFF4F1} = {F39E09D6-BF93-B64A-CFE7-2BA92815C0FE} + + {1DCF4EBB-DBC4-752C-13D4-D1EECE4E8907} = {F39E09D6-BF93-B64A-CFE7-2BA92815C0FE} + + {1B37A859-E733-60CB-4806-1A24B6F10E05} = {F39E09D6-BF93-B64A-CFE7-2BA92815C0FE} + + {F2B58F4E-6F28-A25F-5BFB-CDEBAD6B9A3E} = {F39E09D6-BF93-B64A-CFE7-2BA92815C0FE} + + {7D49FA52-6EA1-EAC8-4C5A-AC07188D6C57} = {5B52EF8A-3661-DCFF-797D-BC4D6AC60BDA} + + {C9CF27FC-12DB-954F-863C-576BA8E309A5} = {7D49FA52-6EA1-EAC8-4C5A-AC07188D6C57} + + {6DCAF6F3-717F-27A9-D96C-F2BFA5550347} = {C9CF27FC-12DB-954F-863C-576BA8E309A5} + + {83791804-2407-CC2B-34AD-ED8FFAAF3257} = {C9CF27FC-12DB-954F-863C-576BA8E309A5} + + {8E933B6D-39AB-871C-33D6-E57984AA38BA} = {5B52EF8A-3661-DCFF-797D-BC4D6AC60BDA} + + {84C61393-D449-22D3-FA3B-75F7256384E9} = {8E933B6D-39AB-871C-33D6-E57984AA38BA} + + {48007FB6-A895-4ED1-E1AE-E0806BCFFF96} = {84C61393-D449-22D3-FA3B-75F7256384E9} + + {09DD25DA-BBB0-5D9D-A372-751855D00AF0} = {84C61393-D449-22D3-FA3B-75F7256384E9} + + {C4A90603-BE42-0044-CAB4-3EB910AD51A5} = {5B52EF8A-3661-DCFF-797D-BC4D6AC60BDA} + + {054761F9-16D3-B2F8-6F4D-EFC2248805CD} = {C4A90603-BE42-0044-CAB4-3EB910AD51A5} + + {B54CE64C-4167-1DD1-B7D6-2FD7A5AEF715} = {C4A90603-BE42-0044-CAB4-3EB910AD51A5} + + {D2162FEA-AFA4-2A88-6444-2F6D845260BB} = {5B52EF8A-3661-DCFF-797D-BC4D6AC60BDA} + + {63EAEA3B-ADC9-631D-774E-7AA04490EDDD} = {D2162FEA-AFA4-2A88-6444-2F6D845260BB} + + {B0F64757-F7A7-1A11-8DEC-BAC72EB5EC29} = {63EAEA3B-ADC9-631D-774E-7AA04490EDDD} + + {C5F86BAD-155A-591C-9610-55D40F59C775} = {63EAEA3B-ADC9-631D-774E-7AA04490EDDD} + + {8E6B774C-CC4E-CE7C-AD4B-8AF7C92889A6} = {5B52EF8A-3661-DCFF-797D-BC4D6AC60BDA} + + {BC12ED55-6015-7C8B-8384-B39CE93C76D6} = {8E6B774C-CC4E-CE7C-AD4B-8AF7C92889A6} + + {7DE09F4B-E86D-CEA4-EC36-364CC9CCD2A6} = {8E6B774C-CC4E-CE7C-AD4B-8AF7C92889A6} + + {BA20548F-5ADA-BE63-1AE7-BA12CB4E82B3} = {8E6B774C-CC4E-CE7C-AD4B-8AF7C92889A6} + + {FF70543D-AFF9-1D38-4950-4F8EE18D60BB} = {8E6B774C-CC4E-CE7C-AD4B-8AF7C92889A6} + + {831265B0-8896-9C95-3488-E12FD9F6DC53} = {FF70543D-AFF9-1D38-4950-4F8EE18D60BB} + + {97579A99-E7BE-9189-9B9A-CA0EBB5E9C97} = {FF70543D-AFF9-1D38-4950-4F8EE18D60BB} + + {F3131BAC-FF6E-FBF1-1A59-74B89427DFE6} = {FF70543D-AFF9-1D38-4950-4F8EE18D60BB} + + {316BBD0A-04D2-85C9-52EA-7993CC6C8930} = {5B52EF8A-3661-DCFF-797D-BC4D6AC60BDA} + + {9D6AB85A-85EA-D85A-5566-A121D34016E6} = {316BBD0A-04D2-85C9-52EA-7993CC6C8930} + + {FC018E5B-1E2F-DE19-1E97-0C845058C469} = {5B52EF8A-3661-DCFF-797D-BC4D6AC60BDA} + + {1BE5B76C-B486-560B-6CB2-44C6537249AA} = {FC018E5B-1E2F-DE19-1E97-0C845058C469} + + {F4F1CBE2-1CDD-CAA4-41F0-266DB4677C05} = {1BE5B76C-B486-560B-6CB2-44C6537249AA} + + {5896C4B3-31D1-1EDD-11D0-C46DB178DC12} = {5B52EF8A-3661-DCFF-797D-BC4D6AC60BDA} + + {D4D193A8-47D7-0B1A-1327-F9C580E7AD07} = {5896C4B3-31D1-1EDD-11D0-C46DB178DC12} + + {69C91AE6-4555-7B2C-AD32-F7F11B9C605A} = {D4D193A8-47D7-0B1A-1327-F9C580E7AD07} + + {E8061AC3-8163-26F9-4FC8-C0E31D9C1EE1} = {D4D193A8-47D7-0B1A-1327-F9C580E7AD07} + + {AE168BCD-C771-ECB3-6830-12D1D3B1871B} = {D4D193A8-47D7-0B1A-1327-F9C580E7AD07} + + {345E1BA3-820E-DF7C-85FA-A9ABDD8B4057} = {D4D193A8-47D7-0B1A-1327-F9C580E7AD07} + + {AEA0B5AB-830E-DB83-623F-3CE249DB4A1C} = {D4D193A8-47D7-0B1A-1327-F9C580E7AD07} + + {DB6D3C1B-DBD3-4D87-64E5-87146B89E6EA} = {D4D193A8-47D7-0B1A-1327-F9C580E7AD07} + + {0FF1692A-5BF7-62DC-C61C-FD2F44252ED2} = {D4D193A8-47D7-0B1A-1327-F9C580E7AD07} + + {C9BCCEDF-7B8A-BCD8-A6B4-75EB25689FE8} = {D4D193A8-47D7-0B1A-1327-F9C580E7AD07} + + {C0E85164-7AA3-6931-5770-037E3051A499} = {D4D193A8-47D7-0B1A-1327-F9C580E7AD07} + + {9F30DC58-7747-31D8-2403-D7D0F5454C87} = {D4D193A8-47D7-0B1A-1327-F9C580E7AD07} + + {336213F7-1241-D268-8EA5-1C73F0040714} = {D4D193A8-47D7-0B1A-1327-F9C580E7AD07} + + {5693F73D-6707-6F86-65D6-654023205615} = {D4D193A8-47D7-0B1A-1327-F9C580E7AD07} + + {593308D7-2453-DC66-4151-E983E4B3F422} = {D4D193A8-47D7-0B1A-1327-F9C580E7AD07} + + {7D55A179-3CDB-8D44-C448-F502BF7ECB3D} = {D4D193A8-47D7-0B1A-1327-F9C580E7AD07} + + {B24B448A-28D8-778E-DCC1-FCF4A0916DF5} = {5B52EF8A-3661-DCFF-797D-BC4D6AC60BDA} + + {BF1AF1AB-97A8-BD70-63F2-E028DE8EE90F} = {B24B448A-28D8-778E-DCC1-FCF4A0916DF5} + + {3DB6D7AE-8187-5324-1208-D6090D5324C6} = {BF1AF1AB-97A8-BD70-63F2-E028DE8EE90F} + + {F945436F-31AA-CA1E-6C57-CCA4E8F854B4} = {BF1AF1AB-97A8-BD70-63F2-E028DE8EE90F} + + {3247EE0D-B3E9-9C11-B0AE-FE719410390B} = {5B52EF8A-3661-DCFF-797D-BC4D6AC60BDA} + + {CD7C09DA-FEC8-2CC5-D00C-E525638DFF4A} = {3247EE0D-B3E9-9C11-B0AE-FE719410390B} + + {79B10804-91E9-972E-1913-EE0F0B11663E} = {CD7C09DA-FEC8-2CC5-D00C-E525638DFF4A} + + {7C2831B0-C6BE-6A5A-D8AF-0FB8CE7CC181} = {CD7C09DA-FEC8-2CC5-D00C-E525638DFF4A} + + {B67B057E-97D2-C6C5-0D7C-D41CA935778A} = {5B52EF8A-3661-DCFF-797D-BC4D6AC60BDA} + + {0749F755-0A1A-7265-20BC-F2DE9EAE4DC3} = {B67B057E-97D2-C6C5-0D7C-D41CA935778A} + + {EFA3BD2C-84D2-5AA8-C5B6-DD41A302A229} = {B67B057E-97D2-C6C5-0D7C-D41CA935778A} + + {0C91EE5B-C434-750F-C923-6D7F9993BF94} = {5B52EF8A-3661-DCFF-797D-BC4D6AC60BDA} + + {2EB6434B-85BC-51D4-4BA4-DD291B656FA7} = {0C91EE5B-C434-750F-C923-6D7F9993BF94} + + {420AE456-2C11-B598-ECCF-8A00F8BAA467} = {2EB6434B-85BC-51D4-4BA4-DD291B656FA7} + + {1345DD29-BB3A-FB5F-4B3D-E29F6045A27A} = {5B52EF8A-3661-DCFF-797D-BC4D6AC60BDA} + + {232347E1-9BB1-0E46-AA39-C22E3B91BC39} = {1345DD29-BB3A-FB5F-4B3D-E29F6045A27A} + + {9C2DD234-FA33-FDB6-86F0-EF9B75A13450} = {1345DD29-BB3A-FB5F-4B3D-E29F6045A27A} + + {79E122F4-2325-3E92-438E-5825A307B594} = {1345DD29-BB3A-FB5F-4B3D-E29F6045A27A} + + {584C3E3B-3CC8-504F-C662-C23A1DF3D002} = {1345DD29-BB3A-FB5F-4B3D-E29F6045A27A} + + {538E2D98-5325-3F54-BE74-EFE5FC1ECBD8} = {1345DD29-BB3A-FB5F-4B3D-E29F6045A27A} + + {66557252-B5C4-664B-D807-07018C627474} = {1345DD29-BB3A-FB5F-4B3D-E29F6045A27A} + + {7203223D-FF02-7BEB-2798-D1639ACC01C4} = {1345DD29-BB3A-FB5F-4B3D-E29F6045A27A} + + {5AC9EE40-1881-5F8A-46A2-2C303950D3C8} = {1345DD29-BB3A-FB5F-4B3D-E29F6045A27A} + + {927E3CD3-4C20-4DE5-A395-D0977152A8D3} = {1345DD29-BB3A-FB5F-4B3D-E29F6045A27A} + + {3C69853C-90E3-D889-1960-3B9229882590} = {1345DD29-BB3A-FB5F-4B3D-E29F6045A27A} + + {695330E8-D292-889E-1D7F-1250A378492A} = {1345DD29-BB3A-FB5F-4B3D-E29F6045A27A} + + {9FB0DDD7-7A77-8DA4-F9E2-A94E60ED8FC7} = {1345DD29-BB3A-FB5F-4B3D-E29F6045A27A} + + {643E4D4C-BC96-A37F-E0EC-488127F0B127} = {1345DD29-BB3A-FB5F-4B3D-E29F6045A27A} + + {6F2CA7F5-3E7C-C61B-94E6-E7DD1227B5B1} = {1345DD29-BB3A-FB5F-4B3D-E29F6045A27A} + + {F04B7DBB-77A5-C978-B2DE-8C189A32AA72} = {1345DD29-BB3A-FB5F-4B3D-E29F6045A27A} + + {7C72F22A-20FF-DF5B-9191-6DFD0D497DB2} = {1345DD29-BB3A-FB5F-4B3D-E29F6045A27A} + + {C896CC0A-F5E6-9AA4-C582-E691441F8D32} = {1345DD29-BB3A-FB5F-4B3D-E29F6045A27A} + + {0AA3A418-AB45-CCA4-46D4-EEBFE011FECA} = {1345DD29-BB3A-FB5F-4B3D-E29F6045A27A} + + {225D9926-4AE8-E539-70AD-8698E688F271} = {1345DD29-BB3A-FB5F-4B3D-E29F6045A27A} + + {D6E8E69C-F721-BBCB-8C39-9716D53D72AD} = {1345DD29-BB3A-FB5F-4B3D-E29F6045A27A} + + {9529EE99-D6A5-B570-EB1F-15BD2D57DFE2} = {1345DD29-BB3A-FB5F-4B3D-E29F6045A27A} + + {589A43FD-8213-E9E3-6CFF-9CBA72D53E98} = {1345DD29-BB3A-FB5F-4B3D-E29F6045A27A} + + {2BACF7E3-1278-FE99-8343-8221E6FBA9DE} = {1345DD29-BB3A-FB5F-4B3D-E29F6045A27A} + + {75E47125-E4D7-8482-F1A4-726564970864} = {1345DD29-BB3A-FB5F-4B3D-E29F6045A27A} + + {FCD529E0-DD17-6587-B29C-12D425C0AD0C} = {1345DD29-BB3A-FB5F-4B3D-E29F6045A27A} + + {61B23570-4F2D-B060-BE1F-37995682E494} = {1345DD29-BB3A-FB5F-4B3D-E29F6045A27A} + + {1182764D-2143-EEF0-9270-3DCE392F5D06} = {1345DD29-BB3A-FB5F-4B3D-E29F6045A27A} + + {772B02B5-6280-E1D4-3E2E-248D0455C2FB} = {1345DD29-BB3A-FB5F-4B3D-E29F6045A27A} + + {48F90289-938C-CCA7-B60F-D2143E7C9A69} = {1345DD29-BB3A-FB5F-4B3D-E29F6045A27A} + + {E69FA1A0-6D1B-A6E4-2DC0-8F4C5F21BF04} = {1345DD29-BB3A-FB5F-4B3D-E29F6045A27A} + + {083067CF-CE89-EF39-9BD3-4741919E26F3} = {1345DD29-BB3A-FB5F-4B3D-E29F6045A27A} + + {8380A20C-A5B8-EE91-1A58-270323688CB9} = {1345DD29-BB3A-FB5F-4B3D-E29F6045A27A} + + {8F128EAE-E97E-82A0-A748-A13F1A85AC8F} = {1345DD29-BB3A-FB5F-4B3D-E29F6045A27A} + + {A7542386-71EB-4F34-E1CE-27D399325955} = {1345DD29-BB3A-FB5F-4B3D-E29F6045A27A} + + {90659617-4DF7-809A-4E5B-29BB5A98E8E1} = {5B52EF8A-3661-DCFF-797D-BC4D6AC60BDA} + + {AB8B269C-5A2A-A4B8-0488-B5F81E55B4D9} = {90659617-4DF7-809A-4E5B-29BB5A98E8E1} + + {EDBA6A07-B0FD-81C5-B3C5-1F7020F8065F} = {AB8B269C-5A2A-A4B8-0488-B5F81E55B4D9} + + {122C01BB-BAD0-E507-AD3F-ABA8F00A80DC} = {A5C98087-E847-D2C4-2143-20869479839D} + + {5788C133-8A9B-0810-2AF4-EA77504A7379} = {A5C98087-E847-D2C4-2143-20869479839D} + + {86CBB26D-D368-4DC4-2F5E-E47E5078BF37} = {A5C98087-E847-D2C4-2143-20869479839D} + + {7C3E7AD5-8E96-4BD0-5AF5-1FCB0F0D175C} = {A5C98087-E847-D2C4-2143-20869479839D} + + {3B68EBC3-2752-608B-8F6D-BC7A28A3DAB7} = {A5C98087-E847-D2C4-2143-20869479839D} + + {DD40725E-6473-AB10-786C-C3B68881A622} = {BB76B5A5-14BA-E317-828D-110B711D71F5} + + {22B129C7-C609-3B90-AD56-64C746A1505E} = {EA6E5683-3A20-2E52-1CE6-AE0D6D36AC4D} + + {AD31623A-BC43-52C2-D906-AC1D8784A541} = {3823DE1E-2ACE-C956-99E1-00DB786D9E1D} + + {776E2142-804F-03B9-C804-D061D64C6092} = {EC506DBE-AB6D-492E-786E-8B176021BF2E} + + {E106BC8E-B20D-C1B5-130C-DAC28922112A} = {0B71A5C2-A1C9-BB93-6042-23D1CEE5AD68} + + {5B4DF41E-C8CC-2606-FA2D-967118BD3C59} = {5F27FB4E-CF09-3A6B-F5B4-BF5A709FA609} + + {3D8C5A6C-462D-7487-5BD0-A3EF6B657EB6} = {018E0E11-1CCE-A2BE-641D-21EE14D2E90D} + + {2609BC1A-6765-29BE-78CC-C0F1D2814F10} = {3F605548-87E2-8A1D-306D-0CE6960B8242} + + {C6822231-A4F4-9E69-6CE2-4FDB3E81C728} = {45F7FA87-7451-6970-7F6E-F8BAE45E081B} + + {28F2F8EE-CD31-0DEF-446C-D868B139F139} = {232347E1-9BB1-0E46-AA39-C22E3B91BC39} + + {55D9B653-FB76-FCE8-1A3C-67B1BEDEC214} = {F2E6CB0E-DF77-1FAA-582B-62B040DF3848} + + {DE5BF139-1E5C-D6EA-4FAA-661EF353A194} = {C494ECBE-DEA5-3576-D2AF-200FF12BC144} + + {335E62C0-9E69-A952-680B-753B1B17C6D0} = {9C2DD234-FA33-FDB6-86F0-EF9B75A13450} + + {5A6CD890-8142-F920-3734-D67CA3E65F61} = {9BD75659-58CB-06D1-E198-C39007E82C6A} + + {A260E14F-DBA4-862E-53CD-18D3B92ADA3D} = {7BF13935-F1DD-D23B-8347-DB1550C69D69} + + {97F94029-5419-6187-5A63-5C8FD9232FAE} = {64689413-46D7-8499-68A6-B6367ACBC597} + + {AF9E7F02-25AD-3540-18D7-F6A4F8BA5A60} = {79E122F4-2325-3E92-438E-5825A307B594} + + {301015C5-1F56-2266-84AA-AB6D83F28893} = {584C3E3B-3CC8-504F-C662-C23A1DF3D002} + + {0C51F029-7C57-B767-AFFA-4800230A6B1F} = {000B0CE4-1FA5-04BB-64A0-CF75B545CE86} + + {1BAEE7A9-C442-D76D-8531-AE20501395C7} = {122C01BB-BAD0-E507-AD3F-ABA8F00A80DC} + + {E7CCD23E-AFD3-B46F-48B0-908E5BF0825B} = {5788C133-8A9B-0810-2AF4-EA77504A7379} + + {8D3B990F-E832-139D-DDFD-1076A8E0834E} = {86CBB26D-D368-4DC4-2F5E-E47E5078BF37} + + {058E17AA-8F9F-426B-2364-65467F6891F7} = {7C3E7AD5-8E96-4BD0-5AF5-1FCB0F0D175C} + + {33767BF5-0175-51A7-9B37-9312610359FC} = {3B68EBC3-2752-608B-8F6D-BC7A28A3DAB7} + + {D1322A50-ABAB-EEFC-17B5-60EDCA13DF8C} = {DD40725E-6473-AB10-786C-C3B68881A622} + + {AB6AE2B6-8D6B-2D9F-2A88-7C596C59F4FC} = {39EFDA5B-F5EE-8212-D5BA-90E1B82013E7} + + {BA45605A-1CCE-6B0C-489D-C113915B243F} = {6844B539-C2A3-9D4F-139D-9D533BCABADA} + + {9D31FC8A-2A69-B78A-D3E5-4F867B16D971} = {4263AA71-0335-3F44-9A9B-423C3A3D05E6} + + {92268008-FBB0-C7AD-ECC2-7B75BED9F5E1} = {F1B1DB47-D2D7-59CB-679B-23E4928E8328} + + {8DCCAF70-D364-4C8B-4E90-AF65091DE0C5} = {BC35DE94-4F04-3436-27A3-F11647FEDD5C} + + {7828C164-DD01-2809-CCB3-364486834F60} = {864C8B80-771A-0C15-30A5-558F99006E0D} + + {DE95E7B2-0937-A980-441F-829E023BC43E} = {603E7A23-1D6B-D3A9-B0E6-3E332B13ED5C} + + {91D69463-23E2-E2C7-AA7E-A78B13CED620} = {D2F7E58B-47D4-5205-D917-144CA1CFF4F1} + + {34EFF636-81A7-8DF6-7CC9-4DA784BAC7F3} = {1DCF4EBB-DBC4-752C-13D4-D1EECE4E8907} + + {5DCF16A8-97C6-2CB4-6A63-0370239039EB} = {1B37A859-E733-60CB-4806-1A24B6F10E05} + + {EB093C48-CDAC-106B-1196-AE34809B34C0} = {F2B58F4E-6F28-A25F-5BFB-CDEBAD6B9A3E} + + {92C62F7B-8028-6EE1-B71B-F45F459B8E97} = {538E2D98-5325-3F54-BE74-EFE5FC1ECBD8} + + {F664A948-E352-5808-E780-77A03F19E93E} = {66557252-B5C4-664B-D807-07018C627474} + + {FA83F778-5252-0B80-5555-E69F790322EA} = {7203223D-FF02-7BEB-2798-D1639ACC01C4} + + {F3A27846-6DE0-3448-222C-25A273E86B2E} = {5AC9EE40-1881-5F8A-46A2-2C303950D3C8} + + {166F4DEC-9886-92D5-6496-085664E9F08F} = {927E3CD3-4C20-4DE5-A395-D0977152A8D3} + + {C53E0895-879A-D9E6-0A43-24AD17A2F270} = {3C69853C-90E3-D889-1960-3B9229882590} + + {1EE42F0F-3F9A-613C-D01F-8BCDB4C42C0E} = {695330E8-D292-889E-1D7F-1250A378492A} + + {246FCC7C-1437-742D-BAE5-E77A24164F08} = {9FB0DDD7-7A77-8DA4-F9E2-A94E60ED8FC7} + + {0AED303F-69E6-238F-EF80-81985080EDB7} = {643E4D4C-BC96-A37F-E0EC-488127F0B127} + + {2904D288-CE64-A565-2C46-C2E85A96A1EE} = {6F2CA7F5-3E7C-C61B-94E6-E7DD1227B5B1} + + {A6667CC3-B77F-023E-3A67-05F99E9FF46A} = {F04B7DBB-77A5-C978-B2DE-8C189A32AA72} + + {A26E2816-F787-F76B-1D6C-E086DD3E19CE} = {7C72F22A-20FF-DF5B-9191-6DFD0D497DB2} + + {B3DEC619-67AC-1B5A-4F3E-A1F24C3F6877} = {C896CC0A-F5E6-9AA4-C582-E691441F8D32} + + {90DB65B4-8F6E-FB8E-0281-505AD8BC6BA6} = {0AA3A418-AB45-CCA4-46D4-EEBFE011FECA} + + {059FBB86-DEE6-8207-3F23-2A1A3EC00DEA} = {225D9926-4AE8-E539-70AD-8698E688F271} + + {8BBA3159-C4CC-F685-A28C-7FE6CBD3D2A1} = {D6E8E69C-F721-BBCB-8C39-9716D53D72AD} + + {EA0974E3-CD2B-5792-EF1E-9B5B7CCBDF00} = {9529EE99-D6A5-B570-EB1F-15BD2D57DFE2} + + {632A1F0D-1BA5-C84B-B716-2BE638A92780} = {589A43FD-8213-E9E3-6CFF-9CBA72D53E98} + + {9DE7852B-7E2D-257E-B0F1-45D2687854ED} = {2BACF7E3-1278-FE99-8343-8221E6FBA9DE} + + {DC2AFC89-C3C8-4E9B-13A7-027EB6386EFA} = {75E47125-E4D7-8482-F1A4-726564970864} + + {9151601C-8784-01A6-C2E7-A5C0FAAB0AEF} = {6DCAF6F3-717F-27A9-D96C-F2BFA5550347} + + {4F1EE2D9-9392-6A1C-7224-6B01FAB934E3} = {83791804-2407-CC2B-34AD-ED8FFAAF3257} + + {104A930A-6D8F-8C36-2CB5-0BC4F8FD74D2} = {48007FB6-A895-4ED1-E1AE-E0806BCFFF96} + + {F7947A80-F07C-2FBF-77F8-DDFA57951A97} = {09DD25DA-BBB0-5D9D-A372-751855D00AF0} + + {CB296A20-2732-77C1-7F23-27D5BAEDD0C7} = {054761F9-16D3-B2F8-6F4D-EFC2248805CD} + + {0DBEC9BA-FE1D-3898-B2C6-E4357DC23E0F} = {B54CE64C-4167-1DD1-B7D6-2FD7A5AEF715} + + {A63897D9-9531-989B-7309-E384BCFC2BB9} = {FCD529E0-DD17-6587-B29C-12D425C0AD0C} + + {8C594D82-3463-3367-4F06-900AC707753D} = {61B23570-4F2D-B060-BE1F-37995682E494} + + {9588FBF9-C37E-D16E-2E8F-CFA226EAC01D} = {1182764D-2143-EEF0-9270-3DCE392F5D06} + + {97998C88-E6E1-D5E2-B632-537B58E00CBF} = {F4F1CBE2-1CDD-CAA4-41F0-266DB4677C05} + + {20D1569C-2A47-38B8-075E-47225B674394} = {B0F64757-F7A7-1A11-8DEC-BAC72EB5EC29} + + {2F7AA715-25AE-086A-7DF4-CAB5EF00E2B7} = {C5F86BAD-155A-591C-9610-55D40F59C775} + + {38A9EE9B-6FC8-93BC-0D43-2A906E678D66} = {772B02B5-6280-E1D4-3E2E-248D0455C2FB} + + {19868E2D-7163-2108-1094-F13887C4F070} = {831265B0-8896-9C95-3488-E12FD9F6DC53} + + {7D3FC972-467A-4917-8339-9B6462C6A38A} = {97579A99-E7BE-9189-9B9A-CA0EBB5E9C97} + + {C154051B-DB4E-5270-AF5A-12A0FFE0E769} = {F3131BAC-FF6E-FBF1-1A59-74B89427DFE6} + + {CC319FC5-F4B1-C3DD-7310-4DAD343E0125} = {BC12ED55-6015-7C8B-8384-B39CE93C76D6} + + {CD6B144E-BCDD-D4FE-2749-703DAB054EBC} = {7DE09F4B-E86D-CEA4-EC36-364CC9CCD2A6} + + {B46D185B-A630-8F76-E61B-90084FBF65B0} = {BA20548F-5ADA-BE63-1AE7-BA12CB4E82B3} + + {84F711C2-C210-28D2-F0D9-B13733FEE23D} = {48F90289-938C-CCA7-B60F-D2143E7C9A69} + + {CBB14B90-27F9-8DD6-DFC4-3507DBD1FBC6} = {E69FA1A0-6D1B-A6E4-2DC0-8F4C5F21BF04} + + {A78EBC0F-C62C-8F56-95C0-330E376242A2} = {9D6AB85A-85EA-D85A-5566-A121D34016E6} + + {6D26FB21-7E48-024B-E5D4-E3F0F31976BB} = {083067CF-CE89-EF39-9BD3-4741919E26F3} + + {28D91816-206C-576E-1A83-FD98E08C2E3C} = {69C91AE6-4555-7B2C-AD32-F7F11B9C605A} + + {5EFEC79C-A9F1-96A4-692C-733566107170} = {E8061AC3-8163-26F9-4FC8-C0E31D9C1EE1} + + {B7B5D764-C3A0-1743-0739-29966F993626} = {AE168BCD-C771-ECB3-6830-12D1D3B1871B} + + {C4EDBBAF-875C-4839-05A8-F6F12A5ED52D} = {345E1BA3-820E-DF7C-85FA-A9ABDD8B4057} + + {0EAC8F64-9588-1EF0-C33A-67590CF27590} = {AEA0B5AB-830E-DB83-623F-3CE249DB4A1C} + + {B1B31937-CCC8-D97A-F66D-1849734B780B} = {DB6D3C1B-DBD3-4D87-64E5-87146B89E6EA} + + {A345E5AC-BDDB-A817-3C92-08C8865D1EF9} = {0FF1692A-5BF7-62DC-C61C-FD2F44252ED2} + + {58D8630F-C0F4-B772-8572-BCC98FF0F0D8} = {C9BCCEDF-7B8A-BCD8-A6B4-75EB25689FE8} + + {D24E7862-3930-A4F6-1DFA-DA88C759546C} = {C0E85164-7AA3-6931-5770-037E3051A499} + + {7CB7FEA8-8A12-A5D6-0057-AA65DB328617} = {9F30DC58-7747-31D8-2403-D7D0F5454C87} + + {52698305-D6F8-C13C-0882-48FC37726404} = {336213F7-1241-D268-8EA5-1C73F0040714} + + {5567139C-0365-B6A0-5DD0-978A09B9F176} = {5693F73D-6707-6F86-65D6-654023205615} + + {256D269B-35EA-F833-2F1D-8E0058908DEE} = {593308D7-2453-DC66-4151-E983E4B3F422} + + {6E9C9582-67FA-2EB1-C6BA-AD4CD326E276} = {7D55A179-3CDB-8D44-C448-F502BF7ECB3D} + + {1F372AB9-D8DD-D295-1D5E-CB5D454CBB24} = {3DB6D7AE-8187-5324-1208-D6090D5324C6} + + {D96DA724-3A66-14E2-D6CC-F65CEEE71069} = {F945436F-31AA-CA1E-6C57-CCA4E8F854B4} + + {0AF13355-173C-3128-5AFC-D32E540DA3EF} = {79B10804-91E9-972E-1913-EE0F0B11663E} + + {06BC00C6-78D4-05AD-C8C8-FF64CD7968E0} = {7C2831B0-C6BE-6A5A-D8AF-0FB8CE7CC181} + + {FFC170B2-A6F0-A1D7-02BD-16D813C8C8C0} = {0749F755-0A1A-7265-20BC-F2DE9EAE4DC3} + + {85B8B27B-51DD-025E-EEED-D44BC0D318B8} = {EFA3BD2C-84D2-5AA8-C5B6-DD41A302A229} + + {AF043113-CCE3-59C1-DF71-9804155F26A8} = {8380A20C-A5B8-EE91-1A58-270323688CB9} + + {9222D186-CD9F-C783-AED5-A3B0E48623BD} = {EDBA6A07-B0FD-81C5-B3C5-1F7020F8065F} + + {10588F6A-E13D-98DC-4EC9-917DCEE382EE} = {420AE456-2C11-B598-ECCF-8A00F8BAA467} + + {E62C8F14-A7CF-47DF-8D60-77308D5D0647} = {8F128EAE-E97E-82A0-A748-A13F1A85AC8F} + + {1D761F8B-921C-53BF-DCF5-5ABD329EEB0C} = {A7542386-71EB-4F34-E1CE-27D399325955} + + {FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} = {831265B0-8896-9C95-3488-E12FD9F6DC53} + EndGlobalSection + + GlobalSection(ExtensibilityGlobals) = postSolution + + SolutionGuid = {258695E4-E399-5944-2BC9-675391C4BB15} + + EndGlobalSection + +EndGlobal + diff --git a/src/Cli/StellaOps.Cli/Commands/CommandFactory.cs b/src/Cli/StellaOps.Cli/Commands/CommandFactory.cs index bfc928f5e..5045b6629 100644 --- a/src/Cli/StellaOps.Cli/Commands/CommandFactory.cs +++ b/src/Cli/StellaOps.Cli/Commands/CommandFactory.cs @@ -52,6 +52,7 @@ internal static class CommandFactory root.Add(BuildAuthCommand(services, options, verboseOption, cancellationToken)); root.Add(BuildTenantsCommand(services, options, verboseOption, cancellationToken)); root.Add(BuildPolicyCommand(services, options, verboseOption, cancellationToken)); + root.Add(ToolsCommandGroup.BuildToolsCommand(loggerFactory, cancellationToken)); root.Add(BuildTaskRunnerCommand(services, verboseOption, cancellationToken)); root.Add(BuildFindingsCommand(services, verboseOption, cancellationToken)); root.Add(BuildAdviseCommand(services, options, verboseOption, cancellationToken)); diff --git a/src/Cli/StellaOps.Cli/Commands/ReplayCommandGroup.cs b/src/Cli/StellaOps.Cli/Commands/ReplayCommandGroup.cs index b9e7777df..422d76d45 100644 --- a/src/Cli/StellaOps.Cli/Commands/ReplayCommandGroup.cs +++ b/src/Cli/StellaOps.Cli/Commands/ReplayCommandGroup.cs @@ -10,13 +10,12 @@ using System.Text.Json; using System.Text.Json.Serialization; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; +using StellaOps.Cli.Replay; using StellaOps.Canonicalization.Json; using StellaOps.Canonicalization.Verification; using StellaOps.Policy.Replay; using StellaOps.Replay.Core; using StellaOps.Replay.Core.Export; -using StellaOps.Testing.Manifests.Models; -using StellaOps.Testing.Manifests.Serialization; namespace StellaOps.Cli.Commands; diff --git a/src/Cli/StellaOps.Cli/Commands/ToolsCommandGroup.cs b/src/Cli/StellaOps.Cli/Commands/ToolsCommandGroup.cs new file mode 100644 index 000000000..17d7b3956 --- /dev/null +++ b/src/Cli/StellaOps.Cli/Commands/ToolsCommandGroup.cs @@ -0,0 +1,25 @@ +using System; +using System.CommandLine; +using System.Threading; +using Microsoft.Extensions.Logging; +using StellaOps.Policy; +using StellaOps.Policy.Tools; + +namespace StellaOps.Cli.Commands; + +internal static class ToolsCommandGroup +{ + internal static Command BuildToolsCommand(ILoggerFactory loggerFactory, CancellationToken cancellationToken) + { + ArgumentNullException.ThrowIfNull(loggerFactory); + + var tools = new Command("tools", "Local policy tooling and maintenance commands."); + var validationRunner = new PolicyValidationRunner(new PolicyValidationCli()); + + tools.Add(PolicyDslValidatorCommand.BuildCommand(validationRunner, cancellationToken)); + tools.Add(PolicySchemaExporterCommand.BuildCommand(new PolicySchemaExporterRunner(), cancellationToken)); + tools.Add(PolicySimulationSmokeCommand.BuildCommand(new PolicySimulationSmokeRunner(loggerFactory), cancellationToken)); + + return tools; + } +} diff --git a/src/Cli/StellaOps.Cli/Replay/RunManifest.cs b/src/Cli/StellaOps.Cli/Replay/RunManifest.cs new file mode 100644 index 000000000..9945c5e23 --- /dev/null +++ b/src/Cli/StellaOps.Cli/Replay/RunManifest.cs @@ -0,0 +1,60 @@ +using System.Collections.Immutable; + +namespace StellaOps.Cli.Replay; + +public sealed record RunManifest +{ + public required string RunId { get; init; } + public string SchemaVersion { get; init; } = "1.0.0"; + public required ImmutableArray ArtifactDigests { get; init; } + public ImmutableArray SbomDigests { get; init; } = []; + public required FeedSnapshot FeedSnapshot { get; init; } + public required PolicySnapshot PolicySnapshot { get; init; } + public required ToolVersions ToolVersions { get; init; } + public required CryptoProfile CryptoProfile { get; init; } + public required EnvironmentProfile EnvironmentProfile { get; init; } + public long? PrngSeed { get; init; } + public required string CanonicalizationVersion { get; init; } + public required DateTimeOffset InitiatedAt { get; init; } + public string? ManifestDigest { get; init; } +} + +public sealed record ArtifactDigest( + string Algorithm, + string Digest, + string? MediaType, + string? Reference); + +public sealed record SbomReference( + string Format, + string Digest, + string? Uri); + +public sealed record FeedSnapshot( + string FeedId, + string Version, + string Digest, + DateTimeOffset SnapshotAt); + +public sealed record PolicySnapshot( + string PolicyVersion, + string LatticeRulesDigest, + ImmutableArray EnabledRules); + +public sealed record ToolVersions( + string ScannerVersion, + string SbomGeneratorVersion, + string ReachabilityEngineVersion, + string AttestorVersion, + ImmutableDictionary AdditionalTools); + +public sealed record CryptoProfile( + string ProfileName, + ImmutableArray TrustRootIds, + ImmutableArray AllowedAlgorithms); + +public sealed record EnvironmentProfile( + string Name, + bool ValkeyEnabled, + string? PostgresVersion, + string? ValkeyVersion); diff --git a/src/Cli/StellaOps.Cli/Replay/RunManifestSerializer.cs b/src/Cli/StellaOps.Cli/Replay/RunManifestSerializer.cs new file mode 100644 index 000000000..81872042b --- /dev/null +++ b/src/Cli/StellaOps.Cli/Replay/RunManifestSerializer.cs @@ -0,0 +1,43 @@ +using System.Security.Cryptography; +using System.Text; +using System.Text.Encodings.Web; +using System.Text.Json; +using System.Text.Json.Serialization; +using StellaOps.Canonical.Json; + +namespace StellaOps.Cli.Replay; + +internal static class RunManifestSerializer +{ + private static readonly JsonSerializerOptions JsonOptions = new(JsonSerializerDefaults.Web) + { + WriteIndented = false, + PropertyNamingPolicy = JsonNamingPolicy.CamelCase, + DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull, + Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping + }; + + public static string Serialize(RunManifest manifest) + { + var jsonBytes = JsonSerializer.SerializeToUtf8Bytes(manifest, JsonOptions); + var canonicalBytes = CanonJson.CanonicalizeParsedJson(jsonBytes); + return Encoding.UTF8.GetString(canonicalBytes); + } + + public static RunManifest Deserialize(string json) + { + return JsonSerializer.Deserialize(json, JsonOptions) + ?? throw new InvalidOperationException("Failed to deserialize manifest"); + } + + public static string ComputeDigest(RunManifest manifest) + { + var withoutDigest = manifest with { ManifestDigest = null }; + var json = Serialize(withoutDigest); + var hash = SHA256.HashData(Encoding.UTF8.GetBytes(json)); + return Convert.ToHexString(hash).ToLowerInvariant(); + } + + public static RunManifest WithDigest(RunManifest manifest) + => manifest with { ManifestDigest = ComputeDigest(manifest) }; +} diff --git a/src/Cli/StellaOps.Cli/StellaOps.Cli.csproj b/src/Cli/StellaOps.Cli/StellaOps.Cli.csproj index 2f1e0a167..f0bbc3481 100644 --- a/src/Cli/StellaOps.Cli/StellaOps.Cli.csproj +++ b/src/Cli/StellaOps.Cli/StellaOps.Cli.csproj @@ -49,8 +49,8 @@ + - @@ -69,6 +69,7 @@ + diff --git a/src/Cli/__Tests/StellaOps.Cli.Tests/Commands/ScannerDownloadVerifyTests.cs b/src/Cli/__Tests/StellaOps.Cli.Tests/Commands/ScannerDownloadVerifyTests.cs index e354242f8..7a6da9430 100644 --- a/src/Cli/__Tests/StellaOps.Cli.Tests/Commands/ScannerDownloadVerifyTests.cs +++ b/src/Cli/__Tests/StellaOps.Cli.Tests/Commands/ScannerDownloadVerifyTests.cs @@ -1,5 +1,6 @@ using System; using System.IO; +using System.Reflection; using System.Threading; using System.Threading.Tasks; using Microsoft.Extensions.Logging; @@ -54,8 +55,20 @@ public sealed class ScannerDownloadVerifyTests internal static class CommandHandlersTestShim { public static Task VerifyBundlePublicAsync(string path, ILogger logger, CancellationToken token) - => typeof(CommandHandlers) - .GetMethod("VerifyBundleAsync", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Static)! - .Invoke(null, new object[] { path, logger, token }) as Task - ?? Task.CompletedTask; + { + var method = typeof(CommandHandlers).GetMethod( + "VerifyBundleAsync", + BindingFlags.NonPublic | BindingFlags.Static, + binder: null, + types: new[] { typeof(string), typeof(ILogger), typeof(CancellationToken) }, + modifiers: null); + + if (method is null) + { + throw new MissingMethodException(nameof(CommandHandlers), "VerifyBundleAsync"); + } + + return method.Invoke(null, new object[] { path, logger, token }) as Task + ?? Task.CompletedTask; + } } diff --git a/src/Cli/__Tests/StellaOps.Cli.Tests/Commands/ToolsCommandGroupTests.cs b/src/Cli/__Tests/StellaOps.Cli.Tests/Commands/ToolsCommandGroupTests.cs new file mode 100644 index 000000000..d74488c37 --- /dev/null +++ b/src/Cli/__Tests/StellaOps.Cli.Tests/Commands/ToolsCommandGroupTests.cs @@ -0,0 +1,69 @@ +using System; +using System.CommandLine; +using System.Linq; +using System.Threading; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; +using StellaOps.Cli.Commands; +using StellaOps.Cli.Configuration; + +namespace StellaOps.Cli.Tests.Commands; + +public sealed class ToolsCommandGroupTests +{ + [Fact] + public void Create_ExposesToolsCommands() + { + using var loggerFactory = LoggerFactory.Create(builder => builder.SetMinimumLevel(LogLevel.None)); + var services = new ServiceCollection().BuildServiceProvider(); + var root = CommandFactory.Create(services, new StellaOpsCliOptions(), CancellationToken.None, loggerFactory); + + var tools = Assert.Single(root.Subcommands, command => string.Equals(command.Name, "tools", StringComparison.Ordinal)); + + Assert.Contains(tools.Subcommands, command => string.Equals(command.Name, "policy-dsl-validate", StringComparison.Ordinal)); + Assert.Contains(tools.Subcommands, command => string.Equals(command.Name, "policy-schema-export", StringComparison.Ordinal)); + Assert.Contains(tools.Subcommands, command => string.Equals(command.Name, "policy-simulation-smoke", StringComparison.Ordinal)); + } + + [Fact] + public void ToolsCommand_PolicyDslValidator_HasExpectedOptions() + { + var command = BuildToolsCommand().Subcommands.First(c => c.Name == "policy-dsl-validate"); + + Assert.NotNull(FindOption(command, "--strict", "-s")); + Assert.NotNull(FindOption(command, "--json", "-j")); + Assert.Contains(command.Arguments, argument => string.Equals(argument.Name, "inputs", StringComparison.Ordinal)); + } + + [Fact] + public void ToolsCommand_PolicySchemaExporter_HasExpectedOptions() + { + var command = BuildToolsCommand().Subcommands.First(c => c.Name == "policy-schema-export"); + + Assert.NotNull(FindOption(command, "--output", "-o")); + Assert.NotNull(FindOption(command, "--repo-root", "-r")); + } + + [Fact] + public void ToolsCommand_PolicySimulationSmoke_HasExpectedOptions() + { + var command = BuildToolsCommand().Subcommands.First(c => c.Name == "policy-simulation-smoke"); + + Assert.NotNull(FindOption(command, "--scenario-root", "-r")); + Assert.NotNull(FindOption(command, "--output", "-o")); + Assert.NotNull(FindOption(command, "--repo-root")); + Assert.NotNull(FindOption(command, "--fixed-time")); + } + + private static Command BuildToolsCommand() + { + using var loggerFactory = LoggerFactory.Create(builder => builder.SetMinimumLevel(LogLevel.None)); + return ToolsCommandGroup.BuildToolsCommand(loggerFactory, CancellationToken.None); + } + + private static Option? FindOption(Command command, params string[] aliases) + { + return command.Options.FirstOrDefault(option => + aliases.Any(alias => string.Equals(option.Name, alias, StringComparison.Ordinal) || option.Aliases.Contains(alias))); + } +} diff --git a/src/Cli/__Tests/StellaOps.Cli.Tests/Integration/CliIntegrationTests.cs b/src/Cli/__Tests/StellaOps.Cli.Tests/Integration/CliIntegrationTests.cs index 3445b436e..bb1a543fe 100644 --- a/src/Cli/__Tests/StellaOps.Cli.Tests/Integration/CliIntegrationTests.cs +++ b/src/Cli/__Tests/StellaOps.Cli.Tests/Integration/CliIntegrationTests.cs @@ -122,7 +122,8 @@ public sealed class CliIntegrationTests : IDisposable // Act & Assert var act = async () => await client.ScanAsync("slow/image:v1"); - await act.Should().ThrowAsync(); + await act.Should().ThrowAsync() + .Where(ex => ex is TimeoutException || ex is TaskCanceledException); } [Fact] diff --git a/src/Cli/__Tests/StellaOps.Cli.Tests/Replay/RunManifestSerializerTests.cs b/src/Cli/__Tests/StellaOps.Cli.Tests/Replay/RunManifestSerializerTests.cs new file mode 100644 index 000000000..baaa675e3 --- /dev/null +++ b/src/Cli/__Tests/StellaOps.Cli.Tests/Replay/RunManifestSerializerTests.cs @@ -0,0 +1,65 @@ +using System.Collections.Immutable; +using StellaOps.Cli.Replay; +using Xunit; + +namespace StellaOps.Cli.Tests.Replay; + +public sealed class RunManifestSerializerTests +{ + [Fact] + public void Serialize_UsesCanonicalOrdering() + { + var manifest = CreateManifest(); + + var json1 = RunManifestSerializer.Serialize(manifest); + var json2 = RunManifestSerializer.Serialize(manifest); + + Assert.Equal(json1, json2); + } + + [Fact] + public void ComputeDigest_IsStable() + { + var manifest = CreateManifest(); + + var digest1 = RunManifestSerializer.ComputeDigest(manifest); + var digest2 = RunManifestSerializer.ComputeDigest(manifest); + + Assert.Equal(digest1, digest2); + Assert.Equal(64, digest1.Length); + } + + [Fact] + public void RoundTrip_PreservesFields() + { + var manifest = CreateManifest(); + + var json = RunManifestSerializer.Serialize(manifest); + var deserialized = RunManifestSerializer.Deserialize(json); + + var normalized = RunManifestSerializer.Serialize(deserialized); + + Assert.Equal(json, normalized); + } + + private static RunManifest CreateManifest() + { + return new RunManifest + { + RunId = "run-1", + SchemaVersion = "1.0.0", + ArtifactDigests = ImmutableArray.Create( + new ArtifactDigest("sha256", new string('a', 64), "application/vnd.oci.image.layer.v1.tar", "example")), + SbomDigests = ImmutableArray.Create( + new SbomReference("cyclonedx-1.6", new string('b', 64), "sbom.json")), + FeedSnapshot = new FeedSnapshot("nvd", "2025.12.01", new string('c', 64), new DateTimeOffset(2025, 12, 1, 0, 0, 0, TimeSpan.Zero)), + PolicySnapshot = new PolicySnapshot("policy-1", new string('d', 64), ImmutableArray.Create("rule-1")), + ToolVersions = new ToolVersions("1.0.0", "1.0.0", "1.0.0", "1.0.0", ImmutableDictionary.Empty), + CryptoProfile = new CryptoProfile("default", ImmutableArray.Create("root-1"), ImmutableArray.Create("sha256")), + EnvironmentProfile = new EnvironmentProfile("postgres-only", false, "16", null), + PrngSeed = 42, + CanonicalizationVersion = "1.0.0", + InitiatedAt = new DateTimeOffset(2025, 12, 1, 0, 0, 0, TimeSpan.Zero) + }; + } +} diff --git a/src/Concelier/__Tests/StellaOps.Concelier.Connector.Osv.Tests/Fixtures/osv-ghsa.ghsa.json b/src/Concelier/__Tests/StellaOps.Concelier.Connector.Ghsa.Tests/Fixtures/osv-ghsa.ghsa.json similarity index 97% rename from src/Concelier/__Tests/StellaOps.Concelier.Connector.Osv.Tests/Fixtures/osv-ghsa.ghsa.json rename to src/Concelier/__Tests/StellaOps.Concelier.Connector.Ghsa.Tests/Fixtures/osv-ghsa.ghsa.json index 6e2905bb6..03c5c7ae2 100644 --- a/src/Concelier/__Tests/StellaOps.Concelier.Connector.Osv.Tests/Fixtures/osv-ghsa.ghsa.json +++ b/src/Concelier/__Tests/StellaOps.Concelier.Connector.Ghsa.Tests/Fixtures/osv-ghsa.ghsa.json @@ -1,1199 +1,1199 @@ -[ - { - "advisoryKey": "GHSA-77vh-xpmg-72qh", - "affectedPackages": [ - { - "type": "semver", - "identifier": "pkg:golang/github.com/opencontainers/image-spec", - "platform": "go", - "versionRanges": [ - { - "fixedVersion": "1.0.2", - "introducedVersion": null, - "lastAffectedVersion": null, - "primitives": null, - "provenance": { - "source": "ghsa", - "kind": "range", - "value": "pkg:golang/github.com/opencontainers/image-spec", - "decisionReason": null, - "recordedAt": "2023-01-09T05:05:32+00:00", - "fieldMask": [ - "affectedpackages[].versionranges[]" - ] - }, - "rangeExpression": "< 1.0.2", - "rangeKind": "semver" - } - ], - "normalizedVersions": [], - "statuses": [], - "provenance": [ - { - "source": "ghsa", - "kind": "package", - "value": "pkg:golang/github.com/opencontainers/image-spec", - "decisionReason": null, - "recordedAt": "2023-01-09T05:05:32+00:00", - "fieldMask": [ - "affectedpackages[]" - ] - } - ] - } - ], - "aliases": [ - "GHSA-77vh-xpmg-72qh" - ], - "canonicalMetricId": null, - "credits": [], - "cvssMetrics": [ - { - "baseScore": 3, - "baseSeverity": "low", - "provenance": { - "source": "ghsa", - "kind": "cvss", - "value": "CVSS:3.1/AV:N/AC:H/PR:L/UI:R/S:C/C:N/I:L/A:N", - "decisionReason": null, - "recordedAt": "2023-01-09T05:05:32+00:00", - "fieldMask": [ - "cvssmetrics[]" - ] - }, - "vector": "CVSS:3.1/AV:N/AC:H/PR:L/UI:R/S:C/C:N/I:L/A:N", - "version": "3.1" - } - ], - "cwes": [], - "description": null, - "exploitKnown": false, - "language": "en", - "modified": "2023-01-09T05:05:32+00:00", - "provenance": [ - { - "source": "ghsa", - "kind": "map", - "value": "GHSA-77vh-xpmg-72qh", - "decisionReason": null, - "recordedAt": "2023-01-09T05:05:32+00:00", - "fieldMask": [ - "advisory" - ] - } - ], - "published": "2021-11-18T16:02:41+00:00", - "references": [ - { - "kind": "advisory", - "provenance": { - "source": "ghsa", - "kind": "reference", - "value": "https://github.com/advisories/GHSA-77vh-xpmg-72qh", - "decisionReason": null, - "recordedAt": "2023-01-09T05:05:32+00:00", - "fieldMask": [ - "references[]" - ] - }, - "sourceTag": "github.com", - "summary": null, - "url": "https://github.com/advisories/GHSA-77vh-xpmg-72qh" - }, - { - "kind": "advisory", - "provenance": { - "source": "ghsa", - "kind": "reference", - "value": "https://github.com/opencontainers/distribution-spec/security/advisories/GHSA-mc8v-mgrf-8f4m", - "decisionReason": null, - "recordedAt": "2023-01-09T05:05:32+00:00", - "fieldMask": [ - "references[]" - ] - }, - "sourceTag": "github.com", - "summary": null, - "url": "https://github.com/opencontainers/distribution-spec/security/advisories/GHSA-mc8v-mgrf-8f4m" - }, - { - "kind": "patch", - "provenance": { - "source": "ghsa", - "kind": "reference", - "value": "https://github.com/opencontainers/image-spec/commit/693428a734f5bab1a84bd2f990d92ef1111cd60c", - "decisionReason": null, - "recordedAt": "2023-01-09T05:05:32+00:00", - "fieldMask": [ - "references[]" - ] - }, - "sourceTag": "github.com", - "summary": null, - "url": "https://github.com/opencontainers/image-spec/commit/693428a734f5bab1a84bd2f990d92ef1111cd60c" - }, - { - "kind": "patch", - "provenance": { - "source": "ghsa", - "kind": "reference", - "value": "https://github.com/opencontainers/image-spec/releases/tag/v1.0.2", - "decisionReason": null, - "recordedAt": "2023-01-09T05:05:32+00:00", - "fieldMask": [ - "references[]" - ] - }, - "sourceTag": "github.com", - "summary": null, - "url": "https://github.com/opencontainers/image-spec/releases/tag/v1.0.2" - }, - { - "kind": "advisory", - "provenance": { - "source": "ghsa", - "kind": "reference", - "value": "https://github.com/opencontainers/image-spec/security/advisories/GHSA-77vh-xpmg-72qh", - "decisionReason": null, - "recordedAt": "2023-01-09T05:05:32+00:00", - "fieldMask": [ - "references[]" - ] - }, - "sourceTag": "github.com", - "summary": null, - "url": "https://github.com/opencontainers/image-spec/security/advisories/GHSA-77vh-xpmg-72qh" - } - ], - "severity": "low", - "summary": "### Impact\nIn the OCI Image Specification version 1.0.1 and prior, manifest and index documents are not self-describing and documents with a single digest could be interpreted as either a manifest or an index.\n\n### Patches\nThe Image Specification will be updated to recommend that both manifest and index documents contain a `mediaType` field to identify the type of document.\nRelease [v1.0.2](https://github.com/opencontainers/image-spec/releases/tag/v1.0.2) includes these updates.\n\n### Workarounds\nSoftware attempting to deserialize an ambiguous document may reject the document if it contains both “manifests” and “layers” fields or “manifests” and “config” fields.\n\n### References\nhttps://github.com/opencontainers/distribution-spec/security/advisories/GHSA-mc8v-mgrf-8f4m\n\n### For more information\nIf you have any questions or comments about this advisory:\n* Open an issue in https://github.com/opencontainers/image-spec\n* Email us at [security@opencontainers.org](mailto:security@opencontainers.org)\n* https://github.com/opencontainers/image-spec/commits/v1.0.2", - "title": "Clarify `mediaType` handling" - }, - { - "advisoryKey": "GHSA-7rjr-3q55-vv33", - "affectedPackages": [ - { - "type": "semver", - "identifier": "pkg:maven/org.apache.logging.log4j/log4j-core", - "platform": "maven", - "versionRanges": [ - { - "fixedVersion": "2.16.0", - "introducedVersion": "2.13.0", - "lastAffectedVersion": null, - "primitives": null, - "provenance": { - "source": "ghsa", - "kind": "range", - "value": "pkg:maven/org.apache.logging.log4j/log4j-core", - "decisionReason": null, - "recordedAt": "2025-05-09T12:28:41+00:00", - "fieldMask": [ - "affectedpackages[].versionranges[]" - ] - }, - "rangeExpression": ">= 2.13.0, < 2.16.0", - "rangeKind": "semver" - } - ], - "normalizedVersions": [], - "statuses": [], - "provenance": [ - { - "source": "ghsa", - "kind": "package", - "value": "pkg:maven/org.apache.logging.log4j/log4j-core", - "decisionReason": null, - "recordedAt": "2025-05-09T12:28:41+00:00", - "fieldMask": [ - "affectedpackages[]" - ] - } - ] - }, - { - "type": "semver", - "identifier": "pkg:maven/org.apache.logging.log4j/log4j-core", - "platform": "maven", - "versionRanges": [ - { - "fixedVersion": "2.12.2", - "introducedVersion": null, - "lastAffectedVersion": null, - "primitives": null, - "provenance": { - "source": "ghsa", - "kind": "range", - "value": "pkg:maven/org.apache.logging.log4j/log4j-core", - "decisionReason": null, - "recordedAt": "2025-05-09T12:28:41+00:00", - "fieldMask": [ - "affectedpackages[].versionranges[]" - ] - }, - "rangeExpression": "< 2.12.2", - "rangeKind": "semver" - } - ], - "normalizedVersions": [], - "statuses": [], - "provenance": [ - { - "source": "ghsa", - "kind": "package", - "value": "pkg:maven/org.apache.logging.log4j/log4j-core", - "decisionReason": null, - "recordedAt": "2025-05-09T12:28:41+00:00", - "fieldMask": [ - "affectedpackages[]" - ] - } - ] - }, - { - "type": "semver", - "identifier": "pkg:maven/org.ops4j.pax.logging/pax-logging-log4j2", - "platform": "maven", - "versionRanges": [ - { - "fixedVersion": "1.9.2", - "introducedVersion": "1.8.0", - "lastAffectedVersion": null, - "primitives": null, - "provenance": { - "source": "ghsa", - "kind": "range", - "value": "pkg:maven/org.ops4j.pax.logging/pax-logging-log4j2", - "decisionReason": null, - "recordedAt": "2025-05-09T12:28:41+00:00", - "fieldMask": [ - "affectedpackages[].versionranges[]" - ] - }, - "rangeExpression": ">= 1.8.0, < 1.9.2", - "rangeKind": "semver" - } - ], - "normalizedVersions": [], - "statuses": [], - "provenance": [ - { - "source": "ghsa", - "kind": "package", - "value": "pkg:maven/org.ops4j.pax.logging/pax-logging-log4j2", - "decisionReason": null, - "recordedAt": "2025-05-09T12:28:41+00:00", - "fieldMask": [ - "affectedpackages[]" - ] - } - ] - }, - { - "type": "semver", - "identifier": "pkg:maven/org.ops4j.pax.logging/pax-logging-log4j2", - "platform": "maven", - "versionRanges": [ - { - "fixedVersion": "1.10.8", - "introducedVersion": "1.10.0", - "lastAffectedVersion": null, - "primitives": null, - "provenance": { - "source": "ghsa", - "kind": "range", - "value": "pkg:maven/org.ops4j.pax.logging/pax-logging-log4j2", - "decisionReason": null, - "recordedAt": "2025-05-09T12:28:41+00:00", - "fieldMask": [ - "affectedpackages[].versionranges[]" - ] - }, - "rangeExpression": ">= 1.10.0, < 1.10.8", - "rangeKind": "semver" - } - ], - "normalizedVersions": [], - "statuses": [], - "provenance": [ - { - "source": "ghsa", - "kind": "package", - "value": "pkg:maven/org.ops4j.pax.logging/pax-logging-log4j2", - "decisionReason": null, - "recordedAt": "2025-05-09T12:28:41+00:00", - "fieldMask": [ - "affectedpackages[]" - ] - } - ] - }, - { - "type": "semver", - "identifier": "pkg:maven/org.ops4j.pax.logging/pax-logging-log4j2", - "platform": "maven", - "versionRanges": [ - { - "fixedVersion": "1.11.11", - "introducedVersion": "1.11.0", - "lastAffectedVersion": null, - "primitives": null, - "provenance": { - "source": "ghsa", - "kind": "range", - "value": "pkg:maven/org.ops4j.pax.logging/pax-logging-log4j2", - "decisionReason": null, - "recordedAt": "2025-05-09T12:28:41+00:00", - "fieldMask": [ - "affectedpackages[].versionranges[]" - ] - }, - "rangeExpression": ">= 1.11.0, < 1.11.11", - "rangeKind": "semver" - } - ], - "normalizedVersions": [], - "statuses": [], - "provenance": [ - { - "source": "ghsa", - "kind": "package", - "value": "pkg:maven/org.ops4j.pax.logging/pax-logging-log4j2", - "decisionReason": null, - "recordedAt": "2025-05-09T12:28:41+00:00", - "fieldMask": [ - "affectedpackages[]" - ] - } - ] - }, - { - "type": "semver", - "identifier": "pkg:maven/org.ops4j.pax.logging/pax-logging-log4j2", - "platform": "maven", - "versionRanges": [ - { - "fixedVersion": "2.0.12", - "introducedVersion": "2.0.0", - "lastAffectedVersion": null, - "primitives": null, - "provenance": { - "source": "ghsa", - "kind": "range", - "value": "pkg:maven/org.ops4j.pax.logging/pax-logging-log4j2", - "decisionReason": null, - "recordedAt": "2025-05-09T12:28:41+00:00", - "fieldMask": [ - "affectedpackages[].versionranges[]" - ] - }, - "rangeExpression": ">= 2.0.0, < 2.0.12", - "rangeKind": "semver" - } - ], - "normalizedVersions": [], - "statuses": [], - "provenance": [ - { - "source": "ghsa", - "kind": "package", - "value": "pkg:maven/org.ops4j.pax.logging/pax-logging-log4j2", - "decisionReason": null, - "recordedAt": "2025-05-09T12:28:41+00:00", - "fieldMask": [ - "affectedpackages[]" - ] - } - ] - } - ], - "aliases": [ - "CVE-2021-45046", - "GHSA-7rjr-3q55-vv33" - ], - "canonicalMetricId": null, - "credits": [], - "cvssMetrics": [ - { - "baseScore": 9.1, - "baseSeverity": "critical", - "provenance": { - "source": "ghsa", - "kind": "cvss", - "value": "CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:C/C:H/I:H/A:H", - "decisionReason": null, - "recordedAt": "2025-05-09T12:28:41+00:00", - "fieldMask": [ - "cvssmetrics[]" - ] - }, - "vector": "CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:C/C:H/I:H/A:H", - "version": "3.1" - } - ], - "cwes": [], - "description": null, - "exploitKnown": false, - "language": "en", - "modified": "2025-05-09T12:28:41+00:00", - "provenance": [ - { - "source": "ghsa", - "kind": "map", - "value": "GHSA-7rjr-3q55-vv33", - "decisionReason": null, - "recordedAt": "2025-05-09T12:28:41+00:00", - "fieldMask": [ - "advisory" - ] - } - ], - "published": "2021-12-14T18:01:28+00:00", - "references": [ - { - "kind": "advisory", - "provenance": { - "source": "ghsa", - "kind": "reference", - "value": "http://www.openwall.com/lists/oss-security/2021/12/14/4", - "decisionReason": null, - "recordedAt": "2025-05-09T12:28:41+00:00", - "fieldMask": [ - "references[]" - ] - }, - "sourceTag": "www.openwall.com", - "summary": null, - "url": "http://www.openwall.com/lists/oss-security/2021/12/14/4" - }, - { - "kind": "advisory", - "provenance": { - "source": "ghsa", - "kind": "reference", - "value": "http://www.openwall.com/lists/oss-security/2021/12/15/3", - "decisionReason": null, - "recordedAt": "2025-05-09T12:28:41+00:00", - "fieldMask": [ - "references[]" - ] - }, - "sourceTag": "www.openwall.com", - "summary": null, - "url": "http://www.openwall.com/lists/oss-security/2021/12/15/3" - }, - { - "kind": "advisory", - "provenance": { - "source": "ghsa", - "kind": "reference", - "value": "http://www.openwall.com/lists/oss-security/2021/12/18/1", - "decisionReason": null, - "recordedAt": "2025-05-09T12:28:41+00:00", - "fieldMask": [ - "references[]" - ] - }, - "sourceTag": "www.openwall.com", - "summary": null, - "url": "http://www.openwall.com/lists/oss-security/2021/12/18/1" - }, - { - "kind": null, - "provenance": { - "source": "ghsa", - "kind": "reference", - "value": "https://cert-portal.siemens.com/productcert/pdf/ssa-397453.pdf", - "decisionReason": null, - "recordedAt": "2025-05-09T12:28:41+00:00", - "fieldMask": [ - "references[]" - ] - }, - "sourceTag": "cert-portal.siemens.com", - "summary": null, - "url": "https://cert-portal.siemens.com/productcert/pdf/ssa-397453.pdf" - }, - { - "kind": null, - "provenance": { - "source": "ghsa", - "kind": "reference", - "value": "https://cert-portal.siemens.com/productcert/pdf/ssa-479842.pdf", - "decisionReason": null, - "recordedAt": "2025-05-09T12:28:41+00:00", - "fieldMask": [ - "references[]" - ] - }, - "sourceTag": "cert-portal.siemens.com", - "summary": null, - "url": "https://cert-portal.siemens.com/productcert/pdf/ssa-479842.pdf" - }, - { - "kind": null, - "provenance": { - "source": "ghsa", - "kind": "reference", - "value": "https://cert-portal.siemens.com/productcert/pdf/ssa-661247.pdf", - "decisionReason": null, - "recordedAt": "2025-05-09T12:28:41+00:00", - "fieldMask": [ - "references[]" - ] - }, - "sourceTag": "cert-portal.siemens.com", - "summary": null, - "url": "https://cert-portal.siemens.com/productcert/pdf/ssa-661247.pdf" - }, - { - "kind": null, - "provenance": { - "source": "ghsa", - "kind": "reference", - "value": "https://cert-portal.siemens.com/productcert/pdf/ssa-714170.pdf", - "decisionReason": null, - "recordedAt": "2025-05-09T12:28:41+00:00", - "fieldMask": [ - "references[]" - ] - }, - "sourceTag": "cert-portal.siemens.com", - "summary": null, - "url": "https://cert-portal.siemens.com/productcert/pdf/ssa-714170.pdf" - }, - { - "kind": "advisory", - "provenance": { - "source": "ghsa", - "kind": "reference", - "value": "https://github.com/advisories/GHSA-7rjr-3q55-vv33", - "decisionReason": null, - "recordedAt": "2025-05-09T12:28:41+00:00", - "fieldMask": [ - "references[]" - ] - }, - "sourceTag": "github.com", - "summary": null, - "url": "https://github.com/advisories/GHSA-7rjr-3q55-vv33" - }, - { - "kind": "advisory", - "provenance": { - "source": "ghsa", - "kind": "reference", - "value": "https://github.com/advisories/GHSA-jfh8-c2jp-5v3q", - "decisionReason": null, - "recordedAt": "2025-05-09T12:28:41+00:00", - "fieldMask": [ - "references[]" - ] - }, - "sourceTag": "github.com", - "summary": null, - "url": "https://github.com/advisories/GHSA-jfh8-c2jp-5v3q" - }, - { - "kind": null, - "provenance": { - "source": "ghsa", - "kind": "reference", - "value": "https://lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/EOKPQGV24RRBBI4TBZUDQMM4MEH7MXCY", - "decisionReason": null, - "recordedAt": "2025-05-09T12:28:41+00:00", - "fieldMask": [ - "references[]" - ] - }, - "sourceTag": "lists.fedoraproject.org", - "summary": null, - "url": "https://lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/EOKPQGV24RRBBI4TBZUDQMM4MEH7MXCY" - }, - { - "kind": null, - "provenance": { - "source": "ghsa", - "kind": "reference", - "value": "https://lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/SIG7FZULMNK2XF6FZRU4VWYDQXNMUGAJ", - "decisionReason": null, - "recordedAt": "2025-05-09T12:28:41+00:00", - "fieldMask": [ - "references[]" - ] - }, - "sourceTag": "lists.fedoraproject.org", - "summary": null, - "url": "https://lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/SIG7FZULMNK2XF6FZRU4VWYDQXNMUGAJ" - }, - { - "kind": "advisory", - "provenance": { - "source": "ghsa", - "kind": "reference", - "value": "https://logging.apache.org/log4j/2.x/security.html", - "decisionReason": null, - "recordedAt": "2025-05-09T12:28:41+00:00", - "fieldMask": [ - "references[]" - ] - }, - "sourceTag": "logging.apache.org", - "summary": null, - "url": "https://logging.apache.org/log4j/2.x/security.html" - }, - { - "kind": "advisory", - "provenance": { - "source": "ghsa", - "kind": "reference", - "value": "https://nvd.nist.gov/vuln/detail/CVE-2021-45046", - "decisionReason": null, - "recordedAt": "2025-05-09T12:28:41+00:00", - "fieldMask": [ - "references[]" - ] - }, - "sourceTag": "nvd.nist.gov", - "summary": null, - "url": "https://nvd.nist.gov/vuln/detail/CVE-2021-45046" - }, - { - "kind": null, - "provenance": { - "source": "ghsa", - "kind": "reference", - "value": "https://psirt.global.sonicwall.com/vuln-detail/SNWLID-2021-0032", - "decisionReason": null, - "recordedAt": "2025-05-09T12:28:41+00:00", - "fieldMask": [ - "references[]" - ] - }, - "sourceTag": "psirt.global.sonicwall.com", - "summary": null, - "url": "https://psirt.global.sonicwall.com/vuln-detail/SNWLID-2021-0032" - }, - { - "kind": "advisory", - "provenance": { - "source": "ghsa", - "kind": "reference", - "value": "https://sec.cloudapps.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-apache-log4j-qRuKNEbd", - "decisionReason": null, - "recordedAt": "2025-05-09T12:28:41+00:00", - "fieldMask": [ - "references[]" - ] - }, - "sourceTag": "sec.cloudapps.cisco.com", - "summary": null, - "url": "https://sec.cloudapps.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-apache-log4j-qRuKNEbd" - }, - { - "kind": "advisory", - "provenance": { - "source": "ghsa", - "kind": "reference", - "value": "https://security.gentoo.org/glsa/202310-16", - "decisionReason": null, - "recordedAt": "2025-05-09T12:28:41+00:00", - "fieldMask": [ - "references[]" - ] - }, - "sourceTag": "security.gentoo.org", - "summary": null, - "url": "https://security.gentoo.org/glsa/202310-16" - }, - { - "kind": "advisory", - "provenance": { - "source": "ghsa", - "kind": "reference", - "value": "https://www.cve.org/CVERecord?id=CVE-2021-44228", - "decisionReason": null, - "recordedAt": "2025-05-09T12:28:41+00:00", - "fieldMask": [ - "references[]" - ] - }, - "sourceTag": "www.cve.org", - "summary": null, - "url": "https://www.cve.org/CVERecord?id=CVE-2021-44228" - }, - { - "kind": "advisory", - "provenance": { - "source": "ghsa", - "kind": "reference", - "value": "https://www.debian.org/security/2021/dsa-5022", - "decisionReason": null, - "recordedAt": "2025-05-09T12:28:41+00:00", - "fieldMask": [ - "references[]" - ] - }, - "sourceTag": "www.debian.org", - "summary": null, - "url": "https://www.debian.org/security/2021/dsa-5022" - }, - { - "kind": "advisory", - "provenance": { - "source": "ghsa", - "kind": "reference", - "value": "https://www.intel.com/content/www/us/en/security-center/advisory/intel-sa-00646.html", - "decisionReason": null, - "recordedAt": "2025-05-09T12:28:41+00:00", - "fieldMask": [ - "references[]" - ] - }, - "sourceTag": "www.intel.com", - "summary": null, - "url": "https://www.intel.com/content/www/us/en/security-center/advisory/intel-sa-00646.html" - }, - { - "kind": null, - "provenance": { - "source": "ghsa", - "kind": "reference", - "value": "https://www.kb.cert.org/vuls/id/930724", - "decisionReason": null, - "recordedAt": "2025-05-09T12:28:41+00:00", - "fieldMask": [ - "references[]" - ] - }, - "sourceTag": "www.kb.cert.org", - "summary": null, - "url": "https://www.kb.cert.org/vuls/id/930724" - }, - { - "kind": "advisory", - "provenance": { - "source": "ghsa", - "kind": "reference", - "value": "https://www.openwall.com/lists/oss-security/2021/12/14/4", - "decisionReason": null, - "recordedAt": "2025-05-09T12:28:41+00:00", - "fieldMask": [ - "references[]" - ] - }, - "sourceTag": "www.openwall.com", - "summary": null, - "url": "https://www.openwall.com/lists/oss-security/2021/12/14/4" - }, - { - "kind": "advisory", - "provenance": { - "source": "ghsa", - "kind": "reference", - "value": "https://www.oracle.com/security-alerts/alert-cve-2021-44228.html", - "decisionReason": null, - "recordedAt": "2025-05-09T12:28:41+00:00", - "fieldMask": [ - "references[]" - ] - }, - "sourceTag": "www.oracle.com", - "summary": null, - "url": "https://www.oracle.com/security-alerts/alert-cve-2021-44228.html" - }, - { - "kind": "advisory", - "provenance": { - "source": "ghsa", - "kind": "reference", - "value": "https://www.oracle.com/security-alerts/cpuapr2022.html", - "decisionReason": null, - "recordedAt": "2025-05-09T12:28:41+00:00", - "fieldMask": [ - "references[]" - ] - }, - "sourceTag": "www.oracle.com", - "summary": null, - "url": "https://www.oracle.com/security-alerts/cpuapr2022.html" - }, - { - "kind": "advisory", - "provenance": { - "source": "ghsa", - "kind": "reference", - "value": "https://www.oracle.com/security-alerts/cpujan2022.html", - "decisionReason": null, - "recordedAt": "2025-05-09T12:28:41+00:00", - "fieldMask": [ - "references[]" - ] - }, - "sourceTag": "www.oracle.com", - "summary": null, - "url": "https://www.oracle.com/security-alerts/cpujan2022.html" - }, - { - "kind": "advisory", - "provenance": { - "source": "ghsa", - "kind": "reference", - "value": "https://www.oracle.com/security-alerts/cpujul2022.html", - "decisionReason": null, - "recordedAt": "2025-05-09T12:28:41+00:00", - "fieldMask": [ - "references[]" - ] - }, - "sourceTag": "www.oracle.com", - "summary": null, - "url": "https://www.oracle.com/security-alerts/cpujul2022.html" - } - ], - "severity": "critical", - "summary": "# Impact\n\nThe fix to address [CVE-2021-44228](https://nvd.nist.gov/vuln/detail/CVE-2021-44228) in Apache Log4j 2.15.0 was incomplete in certain non-default configurations. This could allow attackers with control over Thread Context Map (MDC) input data when the logging configuration uses a non-default Pattern Layout with either a Context Lookup (for example, $${ctx:loginId}) or a Thread Context Map pattern (%X, %mdc, or %MDC) to craft malicious input data using a JNDI Lookup pattern resulting in a remote code execution (RCE) attack. \n\n## Affected packages\nOnly the `org.apache.logging.log4j:log4j-core` package is directly affected by this vulnerability. The `org.apache.logging.log4j:log4j-api` should be kept at the same version as the `org.apache.logging.log4j:log4j-core` package to ensure compatability if in use.\n\n# Mitigation\n\nLog4j 2.16.0 fixes this issue by removing support for message lookup patterns and disabling JNDI functionality by default. This issue can be mitigated in prior releases (< 2.16.0) by removing the JndiLookup class from the classpath (example: zip -q -d log4j-core-*.jar org/apache/logging/log4j/core/lookup/JndiLookup.class).\n\nLog4j 2.15.0 restricts JNDI LDAP lookups to localhost by default. Note that previous mitigations involving configuration such as to set the system property `log4j2.formatMsgNoLookups` to `true` do NOT mitigate this specific vulnerability.", - "title": "Incomplete fix for Apache Log4j vulnerability" - }, - { - "advisoryKey": "GHSA-cjjf-27cc-pvmv", - "affectedPackages": [ - { - "type": "semver", - "identifier": "pyload-ng", - "platform": "pip", - "versionRanges": [ - { - "fixedVersion": "0.5.0b3.dev91", - "introducedVersion": null, - "lastAffectedVersion": null, - "primitives": null, - "provenance": { - "source": "ghsa", - "kind": "range", - "value": "pyload-ng", - "decisionReason": null, - "recordedAt": "2025-10-09T15:19:48+00:00", - "fieldMask": [ - "affectedpackages[].versionranges[]" - ] - }, - "rangeExpression": "< 0.5.0b3.dev91", - "rangeKind": "semver" - } - ], - "normalizedVersions": [], - "statuses": [], - "provenance": [ - { - "source": "ghsa", - "kind": "package", - "value": "pyload-ng", - "decisionReason": null, - "recordedAt": "2025-10-09T15:19:48+00:00", - "fieldMask": [ - "affectedpackages[]" - ] - } - ] - } - ], - "aliases": [ - "CVE-2025-61773", - "GHSA-cjjf-27cc-pvmv" - ], - "canonicalMetricId": null, - "credits": [], - "cvssMetrics": [ - { - "baseScore": 8.1, - "baseSeverity": "high", - "provenance": { - "source": "ghsa", - "kind": "cvss", - "value": "CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:N", - "decisionReason": null, - "recordedAt": "2025-10-09T15:19:48+00:00", - "fieldMask": [ - "cvssmetrics[]" - ] - }, - "vector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:N", - "version": "3.1" - } - ], - "cwes": [], - "description": null, - "exploitKnown": false, - "language": "en", - "modified": "2025-10-09T15:19:48+00:00", - "provenance": [ - { - "source": "ghsa", - "kind": "map", - "value": "GHSA-cjjf-27cc-pvmv", - "decisionReason": null, - "recordedAt": "2025-10-09T15:19:48+00:00", - "fieldMask": [ - "advisory" - ] - } - ], - "published": "2025-10-09T15:19:48+00:00", - "references": [ - { - "kind": "advisory", - "provenance": { - "source": "ghsa", - "kind": "reference", - "value": "https://github.com/advisories/GHSA-cjjf-27cc-pvmv", - "decisionReason": null, - "recordedAt": "2025-10-09T15:19:48+00:00", - "fieldMask": [ - "references[]" - ] - }, - "sourceTag": "github.com", - "summary": null, - "url": "https://github.com/advisories/GHSA-cjjf-27cc-pvmv" - }, - { - "kind": "patch", - "provenance": { - "source": "ghsa", - "kind": "reference", - "value": "https://github.com/pyload/pyload/commit/5823327d0b797161c7195a1f660266d30a69f0ca", - "decisionReason": null, - "recordedAt": "2025-10-09T15:19:48+00:00", - "fieldMask": [ - "references[]" - ] - }, - "sourceTag": "github.com", - "summary": null, - "url": "https://github.com/pyload/pyload/commit/5823327d0b797161c7195a1f660266d30a69f0ca" - }, - { - "kind": "patch", - "provenance": { - "source": "ghsa", - "kind": "reference", - "value": "https://github.com/pyload/pyload/pull/4624", - "decisionReason": null, - "recordedAt": "2025-10-09T15:19:48+00:00", - "fieldMask": [ - "references[]" - ] - }, - "sourceTag": "github.com", - "summary": null, - "url": "https://github.com/pyload/pyload/pull/4624" - }, - { - "kind": "advisory", - "provenance": { - "source": "ghsa", - "kind": "reference", - "value": "https://github.com/pyload/pyload/security/advisories/GHSA-cjjf-27cc-pvmv", - "decisionReason": null, - "recordedAt": "2025-10-09T15:19:48+00:00", - "fieldMask": [ - "references[]" - ] - }, - "sourceTag": "github.com", - "summary": null, - "url": "https://github.com/pyload/pyload/security/advisories/GHSA-cjjf-27cc-pvmv" - } - ], - "severity": "high", - "summary": "### Summary\npyLoad web interface contained insufficient input validation in both the Captcha script endpoint and the Click'N'Load (CNL) Blueprint. This flaw allowed untrusted user input to be processed unsafely, which could be exploited by an attacker to inject arbitrary content into the web UI or manipulate request handling. The vulnerability could lead to client-side code execution (XSS) or other unintended behaviors when a malicious payload is submitted.\n\nuser-supplied parameters from HTTP requests were not adequately validated or sanitized before being passed into the application logic and response generation. This allowed crafted input to alter the expected execution flow.\n CNL (Click'N'Load) blueprint exposed unsafe handling of untrusted parameters in HTTP requests. The application did not consistently enforce input validation or encoding, making it possible for an attacker to craft malicious requests.\n\n### PoC\n\n1. Run a vulnerable version of pyLoad prior to commit [`f9d27f2`](https://github.com/pyload/pyload/pull/4624).\n2. Start the web UI and access the Captcha or CNL endpoints.\n3. Submit a crafted request containing malicious JavaScript payloads in unvalidated parameters (`/flash/addcrypted2?jk=function(){alert(1)}&crypted=12345`).\n4. Observe that the payload is reflected and executed in the client’s browser, demonstrating cross-site scripting (XSS).\n\nExample request:\n\n```http\nGET /flash/addcrypted2?jk=function(){alert(1)}&crypted=12345 HTTP/1.1\nHost: 127.0.0.1:8000\nContent-Type: application/x-www-form-urlencoded\nContent-Length: 107\n```\n\n### Impact\n\nExploiting this vulnerability allows an attacker to inject and execute arbitrary JavaScript within the browser session of a user accessing the pyLoad Web UI. In practice, this means an attacker could impersonate an administrator, steal authentication cookies or tokens, and perform unauthorized actions on behalf of the victim. Because the affected endpoints are part of the core interface, a successful attack undermines the trust and security of the entire application, potentially leading to a full compromise of the management interface and the data it controls. The impact is particularly severe in cases where the Web UI is exposed over a network without additional access restrictions, as it enables remote attackers to directly target users with crafted links or requests that trigger the vulnerability.", - "title": "pyLoad CNL and captcha handlers allow Code Injection via unsanitized parameters" - }, - { - "advisoryKey": "GHSA-wv4w-6qv2-qqfg", - "affectedPackages": [ - { - "type": "semver", - "identifier": "social-auth-app-django", - "platform": "pip", - "versionRanges": [ - { - "fixedVersion": "5.6.0", - "introducedVersion": null, - "lastAffectedVersion": null, - "primitives": null, - "provenance": { - "source": "ghsa", - "kind": "range", - "value": "social-auth-app-django", - "decisionReason": null, - "recordedAt": "2025-10-09T17:08:06+00:00", - "fieldMask": [ - "affectedpackages[].versionranges[]" - ] - }, - "rangeExpression": "< 5.6.0", - "rangeKind": "semver" - } - ], - "normalizedVersions": [], - "statuses": [], - "provenance": [ - { - "source": "ghsa", - "kind": "package", - "value": "social-auth-app-django", - "decisionReason": null, - "recordedAt": "2025-10-09T17:08:06+00:00", - "fieldMask": [ - "affectedpackages[]" - ] - } - ] - } - ], - "aliases": [ - "CVE-2025-61783", - "GHSA-wv4w-6qv2-qqfg" - ], - "canonicalMetricId": null, - "credits": [], - "cvssMetrics": [], - "cwes": [], - "description": null, - "exploitKnown": false, - "language": "en", - "modified": "2025-10-09T17:08:06+00:00", - "provenance": [ - { - "source": "ghsa", - "kind": "map", - "value": "GHSA-wv4w-6qv2-qqfg", - "decisionReason": null, - "recordedAt": "2025-10-09T17:08:06+00:00", - "fieldMask": [ - "advisory" - ] - } - ], - "published": "2025-10-09T17:08:05+00:00", - "references": [ - { - "kind": "advisory", - "provenance": { - "source": "ghsa", - "kind": "reference", - "value": "https://github.com/advisories/GHSA-wv4w-6qv2-qqfg", - "decisionReason": null, - "recordedAt": "2025-10-09T17:08:06+00:00", - "fieldMask": [ - "references[]" - ] - }, - "sourceTag": "github.com", - "summary": null, - "url": "https://github.com/advisories/GHSA-wv4w-6qv2-qqfg" - }, - { - "kind": "patch", - "provenance": { - "source": "ghsa", - "kind": "reference", - "value": "https://github.com/python-social-auth/social-app-django/commit/10c80e2ebabeccd4e9c84ad0e16e1db74148ed4c", - "decisionReason": null, - "recordedAt": "2025-10-09T17:08:06+00:00", - "fieldMask": [ - "references[]" - ] - }, - "sourceTag": "github.com", - "summary": null, - "url": "https://github.com/python-social-auth/social-app-django/commit/10c80e2ebabeccd4e9c84ad0e16e1db74148ed4c" - }, - { - "kind": null, - "provenance": { - "source": "ghsa", - "kind": "reference", - "value": "https://github.com/python-social-auth/social-app-django/issues/220", - "decisionReason": null, - "recordedAt": "2025-10-09T17:08:06+00:00", - "fieldMask": [ - "references[]" - ] - }, - "sourceTag": "github.com", - "summary": null, - "url": "https://github.com/python-social-auth/social-app-django/issues/220" - }, - { - "kind": null, - "provenance": { - "source": "ghsa", - "kind": "reference", - "value": "https://github.com/python-social-auth/social-app-django/issues/231", - "decisionReason": null, - "recordedAt": "2025-10-09T17:08:06+00:00", - "fieldMask": [ - "references[]" - ] - }, - "sourceTag": "github.com", - "summary": null, - "url": "https://github.com/python-social-auth/social-app-django/issues/231" - }, - { - "kind": null, - "provenance": { - "source": "ghsa", - "kind": "reference", - "value": "https://github.com/python-social-auth/social-app-django/issues/634", - "decisionReason": null, - "recordedAt": "2025-10-09T17:08:06+00:00", - "fieldMask": [ - "references[]" - ] - }, - "sourceTag": "github.com", - "summary": null, - "url": "https://github.com/python-social-auth/social-app-django/issues/634" - }, - { - "kind": "patch", - "provenance": { - "source": "ghsa", - "kind": "reference", - "value": "https://github.com/python-social-auth/social-app-django/pull/803", - "decisionReason": null, - "recordedAt": "2025-10-09T17:08:06+00:00", - "fieldMask": [ - "references[]" - ] - }, - "sourceTag": "github.com", - "summary": null, - "url": "https://github.com/python-social-auth/social-app-django/pull/803" - }, - { - "kind": "advisory", - "provenance": { - "source": "ghsa", - "kind": "reference", - "value": "https://github.com/python-social-auth/social-app-django/security/advisories/GHSA-wv4w-6qv2-qqfg", - "decisionReason": null, - "recordedAt": "2025-10-09T17:08:06+00:00", - "fieldMask": [ - "references[]" - ] - }, - "sourceTag": "github.com", - "summary": null, - "url": "https://github.com/python-social-auth/social-app-django/security/advisories/GHSA-wv4w-6qv2-qqfg" - } - ], - "severity": "medium", - "summary": "### Impact\n\nUpon authentication, the user could be associated by e-mail even if the `associate_by_email` pipeline was not included. This could lead to account compromise when a third-party authentication service does not validate provided e-mail addresses or doesn't require unique e-mail addresses.\n\n### Patches\n\n* https://github.com/python-social-auth/social-app-django/pull/803\n\n### Workarounds\n\nReview the authentication service policy on e-mail addresses; many will not allow exploiting this vulnerability.", - "title": "Python Social Auth - Django has unsafe account association" - } +[ + { + "advisoryKey": "GHSA-77vh-xpmg-72qh", + "affectedPackages": [ + { + "type": "semver", + "identifier": "pkg:golang/github.com/opencontainers/image-spec", + "platform": "go", + "versionRanges": [ + { + "fixedVersion": "1.0.2", + "introducedVersion": null, + "lastAffectedVersion": null, + "primitives": null, + "provenance": { + "source": "ghsa", + "kind": "range", + "value": "pkg:golang/github.com/opencontainers/image-spec", + "decisionReason": null, + "recordedAt": "2023-01-09T05:05:32+00:00", + "fieldMask": [ + "affectedpackages[].versionranges[]" + ] + }, + "rangeExpression": "< 1.0.2", + "rangeKind": "semver" + } + ], + "normalizedVersions": [], + "statuses": [], + "provenance": [ + { + "source": "ghsa", + "kind": "package", + "value": "pkg:golang/github.com/opencontainers/image-spec", + "decisionReason": null, + "recordedAt": "2023-01-09T05:05:32+00:00", + "fieldMask": [ + "affectedpackages[]" + ] + } + ] + } + ], + "aliases": [ + "GHSA-77vh-xpmg-72qh" + ], + "canonicalMetricId": null, + "credits": [], + "cvssMetrics": [ + { + "baseScore": 3, + "baseSeverity": "low", + "provenance": { + "source": "ghsa", + "kind": "cvss", + "value": "CVSS:3.1/AV:N/AC:H/PR:L/UI:R/S:C/C:N/I:L/A:N", + "decisionReason": null, + "recordedAt": "2023-01-09T05:05:32+00:00", + "fieldMask": [ + "cvssmetrics[]" + ] + }, + "vector": "CVSS:3.1/AV:N/AC:H/PR:L/UI:R/S:C/C:N/I:L/A:N", + "version": "3.1" + } + ], + "cwes": [], + "description": null, + "exploitKnown": false, + "language": "en", + "modified": "2023-01-09T05:05:32+00:00", + "provenance": [ + { + "source": "ghsa", + "kind": "map", + "value": "GHSA-77vh-xpmg-72qh", + "decisionReason": null, + "recordedAt": "2023-01-09T05:05:32+00:00", + "fieldMask": [ + "advisory" + ] + } + ], + "published": "2021-11-18T16:02:41+00:00", + "references": [ + { + "kind": "advisory", + "provenance": { + "source": "ghsa", + "kind": "reference", + "value": "https://github.com/advisories/GHSA-77vh-xpmg-72qh", + "decisionReason": null, + "recordedAt": "2023-01-09T05:05:32+00:00", + "fieldMask": [ + "references[]" + ] + }, + "sourceTag": "github.com", + "summary": null, + "url": "https://github.com/advisories/GHSA-77vh-xpmg-72qh" + }, + { + "kind": "advisory", + "provenance": { + "source": "ghsa", + "kind": "reference", + "value": "https://github.com/opencontainers/distribution-spec/security/advisories/GHSA-mc8v-mgrf-8f4m", + "decisionReason": null, + "recordedAt": "2023-01-09T05:05:32+00:00", + "fieldMask": [ + "references[]" + ] + }, + "sourceTag": "github.com", + "summary": null, + "url": "https://github.com/opencontainers/distribution-spec/security/advisories/GHSA-mc8v-mgrf-8f4m" + }, + { + "kind": "patch", + "provenance": { + "source": "ghsa", + "kind": "reference", + "value": "https://github.com/opencontainers/image-spec/commit/693428a734f5bab1a84bd2f990d92ef1111cd60c", + "decisionReason": null, + "recordedAt": "2023-01-09T05:05:32+00:00", + "fieldMask": [ + "references[]" + ] + }, + "sourceTag": "github.com", + "summary": null, + "url": "https://github.com/opencontainers/image-spec/commit/693428a734f5bab1a84bd2f990d92ef1111cd60c" + }, + { + "kind": "patch", + "provenance": { + "source": "ghsa", + "kind": "reference", + "value": "https://github.com/opencontainers/image-spec/releases/tag/v1.0.2", + "decisionReason": null, + "recordedAt": "2023-01-09T05:05:32+00:00", + "fieldMask": [ + "references[]" + ] + }, + "sourceTag": "github.com", + "summary": null, + "url": "https://github.com/opencontainers/image-spec/releases/tag/v1.0.2" + }, + { + "kind": "advisory", + "provenance": { + "source": "ghsa", + "kind": "reference", + "value": "https://github.com/opencontainers/image-spec/security/advisories/GHSA-77vh-xpmg-72qh", + "decisionReason": null, + "recordedAt": "2023-01-09T05:05:32+00:00", + "fieldMask": [ + "references[]" + ] + }, + "sourceTag": "github.com", + "summary": null, + "url": "https://github.com/opencontainers/image-spec/security/advisories/GHSA-77vh-xpmg-72qh" + } + ], + "severity": "low", + "summary": "### Impact\nIn the OCI Image Specification version 1.0.1 and prior, manifest and index documents are not self-describing and documents with a single digest could be interpreted as either a manifest or an index.\n\n### Patches\nThe Image Specification will be updated to recommend that both manifest and index documents contain a `mediaType` field to identify the type of document.\nRelease [v1.0.2](https://github.com/opencontainers/image-spec/releases/tag/v1.0.2) includes these updates.\n\n### Workarounds\nSoftware attempting to deserialize an ambiguous document may reject the document if it contains both “manifests” and “layers” fields or “manifests” and “config” fields.\n\n### References\nhttps://github.com/opencontainers/distribution-spec/security/advisories/GHSA-mc8v-mgrf-8f4m\n\n### For more information\nIf you have any questions or comments about this advisory:\n* Open an issue in https://github.com/opencontainers/image-spec\n* Email us at [security@opencontainers.org](mailto:security@opencontainers.org)\n* https://github.com/opencontainers/image-spec/commits/v1.0.2", + "title": "Clarify `mediaType` handling" + }, + { + "advisoryKey": "GHSA-7rjr-3q55-vv33", + "affectedPackages": [ + { + "type": "semver", + "identifier": "pkg:maven/org.apache.logging.log4j/log4j-core", + "platform": "maven", + "versionRanges": [ + { + "fixedVersion": "2.16.0", + "introducedVersion": "2.13.0", + "lastAffectedVersion": null, + "primitives": null, + "provenance": { + "source": "ghsa", + "kind": "range", + "value": "pkg:maven/org.apache.logging.log4j/log4j-core", + "decisionReason": null, + "recordedAt": "2025-05-09T12:28:41+00:00", + "fieldMask": [ + "affectedpackages[].versionranges[]" + ] + }, + "rangeExpression": ">= 2.13.0, < 2.16.0", + "rangeKind": "semver" + } + ], + "normalizedVersions": [], + "statuses": [], + "provenance": [ + { + "source": "ghsa", + "kind": "package", + "value": "pkg:maven/org.apache.logging.log4j/log4j-core", + "decisionReason": null, + "recordedAt": "2025-05-09T12:28:41+00:00", + "fieldMask": [ + "affectedpackages[]" + ] + } + ] + }, + { + "type": "semver", + "identifier": "pkg:maven/org.apache.logging.log4j/log4j-core", + "platform": "maven", + "versionRanges": [ + { + "fixedVersion": "2.12.2", + "introducedVersion": null, + "lastAffectedVersion": null, + "primitives": null, + "provenance": { + "source": "ghsa", + "kind": "range", + "value": "pkg:maven/org.apache.logging.log4j/log4j-core", + "decisionReason": null, + "recordedAt": "2025-05-09T12:28:41+00:00", + "fieldMask": [ + "affectedpackages[].versionranges[]" + ] + }, + "rangeExpression": "< 2.12.2", + "rangeKind": "semver" + } + ], + "normalizedVersions": [], + "statuses": [], + "provenance": [ + { + "source": "ghsa", + "kind": "package", + "value": "pkg:maven/org.apache.logging.log4j/log4j-core", + "decisionReason": null, + "recordedAt": "2025-05-09T12:28:41+00:00", + "fieldMask": [ + "affectedpackages[]" + ] + } + ] + }, + { + "type": "semver", + "identifier": "pkg:maven/org.ops4j.pax.logging/pax-logging-log4j2", + "platform": "maven", + "versionRanges": [ + { + "fixedVersion": "1.9.2", + "introducedVersion": "1.8.0", + "lastAffectedVersion": null, + "primitives": null, + "provenance": { + "source": "ghsa", + "kind": "range", + "value": "pkg:maven/org.ops4j.pax.logging/pax-logging-log4j2", + "decisionReason": null, + "recordedAt": "2025-05-09T12:28:41+00:00", + "fieldMask": [ + "affectedpackages[].versionranges[]" + ] + }, + "rangeExpression": ">= 1.8.0, < 1.9.2", + "rangeKind": "semver" + } + ], + "normalizedVersions": [], + "statuses": [], + "provenance": [ + { + "source": "ghsa", + "kind": "package", + "value": "pkg:maven/org.ops4j.pax.logging/pax-logging-log4j2", + "decisionReason": null, + "recordedAt": "2025-05-09T12:28:41+00:00", + "fieldMask": [ + "affectedpackages[]" + ] + } + ] + }, + { + "type": "semver", + "identifier": "pkg:maven/org.ops4j.pax.logging/pax-logging-log4j2", + "platform": "maven", + "versionRanges": [ + { + "fixedVersion": "1.10.8", + "introducedVersion": "1.10.0", + "lastAffectedVersion": null, + "primitives": null, + "provenance": { + "source": "ghsa", + "kind": "range", + "value": "pkg:maven/org.ops4j.pax.logging/pax-logging-log4j2", + "decisionReason": null, + "recordedAt": "2025-05-09T12:28:41+00:00", + "fieldMask": [ + "affectedpackages[].versionranges[]" + ] + }, + "rangeExpression": ">= 1.10.0, < 1.10.8", + "rangeKind": "semver" + } + ], + "normalizedVersions": [], + "statuses": [], + "provenance": [ + { + "source": "ghsa", + "kind": "package", + "value": "pkg:maven/org.ops4j.pax.logging/pax-logging-log4j2", + "decisionReason": null, + "recordedAt": "2025-05-09T12:28:41+00:00", + "fieldMask": [ + "affectedpackages[]" + ] + } + ] + }, + { + "type": "semver", + "identifier": "pkg:maven/org.ops4j.pax.logging/pax-logging-log4j2", + "platform": "maven", + "versionRanges": [ + { + "fixedVersion": "1.11.11", + "introducedVersion": "1.11.0", + "lastAffectedVersion": null, + "primitives": null, + "provenance": { + "source": "ghsa", + "kind": "range", + "value": "pkg:maven/org.ops4j.pax.logging/pax-logging-log4j2", + "decisionReason": null, + "recordedAt": "2025-05-09T12:28:41+00:00", + "fieldMask": [ + "affectedpackages[].versionranges[]" + ] + }, + "rangeExpression": ">= 1.11.0, < 1.11.11", + "rangeKind": "semver" + } + ], + "normalizedVersions": [], + "statuses": [], + "provenance": [ + { + "source": "ghsa", + "kind": "package", + "value": "pkg:maven/org.ops4j.pax.logging/pax-logging-log4j2", + "decisionReason": null, + "recordedAt": "2025-05-09T12:28:41+00:00", + "fieldMask": [ + "affectedpackages[]" + ] + } + ] + }, + { + "type": "semver", + "identifier": "pkg:maven/org.ops4j.pax.logging/pax-logging-log4j2", + "platform": "maven", + "versionRanges": [ + { + "fixedVersion": "2.0.12", + "introducedVersion": "2.0.0", + "lastAffectedVersion": null, + "primitives": null, + "provenance": { + "source": "ghsa", + "kind": "range", + "value": "pkg:maven/org.ops4j.pax.logging/pax-logging-log4j2", + "decisionReason": null, + "recordedAt": "2025-05-09T12:28:41+00:00", + "fieldMask": [ + "affectedpackages[].versionranges[]" + ] + }, + "rangeExpression": ">= 2.0.0, < 2.0.12", + "rangeKind": "semver" + } + ], + "normalizedVersions": [], + "statuses": [], + "provenance": [ + { + "source": "ghsa", + "kind": "package", + "value": "pkg:maven/org.ops4j.pax.logging/pax-logging-log4j2", + "decisionReason": null, + "recordedAt": "2025-05-09T12:28:41+00:00", + "fieldMask": [ + "affectedpackages[]" + ] + } + ] + } + ], + "aliases": [ + "CVE-2021-45046", + "GHSA-7rjr-3q55-vv33" + ], + "canonicalMetricId": null, + "credits": [], + "cvssMetrics": [ + { + "baseScore": 9.1, + "baseSeverity": "critical", + "provenance": { + "source": "ghsa", + "kind": "cvss", + "value": "CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:C/C:H/I:H/A:H", + "decisionReason": null, + "recordedAt": "2025-05-09T12:28:41+00:00", + "fieldMask": [ + "cvssmetrics[]" + ] + }, + "vector": "CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:C/C:H/I:H/A:H", + "version": "3.1" + } + ], + "cwes": [], + "description": null, + "exploitKnown": false, + "language": "en", + "modified": "2025-05-09T12:28:41+00:00", + "provenance": [ + { + "source": "ghsa", + "kind": "map", + "value": "GHSA-7rjr-3q55-vv33", + "decisionReason": null, + "recordedAt": "2025-05-09T12:28:41+00:00", + "fieldMask": [ + "advisory" + ] + } + ], + "published": "2021-12-14T18:01:28+00:00", + "references": [ + { + "kind": "advisory", + "provenance": { + "source": "ghsa", + "kind": "reference", + "value": "http://www.openwall.com/lists/oss-security/2021/12/14/4", + "decisionReason": null, + "recordedAt": "2025-05-09T12:28:41+00:00", + "fieldMask": [ + "references[]" + ] + }, + "sourceTag": "www.openwall.com", + "summary": null, + "url": "http://www.openwall.com/lists/oss-security/2021/12/14/4" + }, + { + "kind": "advisory", + "provenance": { + "source": "ghsa", + "kind": "reference", + "value": "http://www.openwall.com/lists/oss-security/2021/12/15/3", + "decisionReason": null, + "recordedAt": "2025-05-09T12:28:41+00:00", + "fieldMask": [ + "references[]" + ] + }, + "sourceTag": "www.openwall.com", + "summary": null, + "url": "http://www.openwall.com/lists/oss-security/2021/12/15/3" + }, + { + "kind": "advisory", + "provenance": { + "source": "ghsa", + "kind": "reference", + "value": "http://www.openwall.com/lists/oss-security/2021/12/18/1", + "decisionReason": null, + "recordedAt": "2025-05-09T12:28:41+00:00", + "fieldMask": [ + "references[]" + ] + }, + "sourceTag": "www.openwall.com", + "summary": null, + "url": "http://www.openwall.com/lists/oss-security/2021/12/18/1" + }, + { + "kind": null, + "provenance": { + "source": "ghsa", + "kind": "reference", + "value": "https://cert-portal.siemens.com/productcert/pdf/ssa-397453.pdf", + "decisionReason": null, + "recordedAt": "2025-05-09T12:28:41+00:00", + "fieldMask": [ + "references[]" + ] + }, + "sourceTag": "cert-portal.siemens.com", + "summary": null, + "url": "https://cert-portal.siemens.com/productcert/pdf/ssa-397453.pdf" + }, + { + "kind": null, + "provenance": { + "source": "ghsa", + "kind": "reference", + "value": "https://cert-portal.siemens.com/productcert/pdf/ssa-479842.pdf", + "decisionReason": null, + "recordedAt": "2025-05-09T12:28:41+00:00", + "fieldMask": [ + "references[]" + ] + }, + "sourceTag": "cert-portal.siemens.com", + "summary": null, + "url": "https://cert-portal.siemens.com/productcert/pdf/ssa-479842.pdf" + }, + { + "kind": null, + "provenance": { + "source": "ghsa", + "kind": "reference", + "value": "https://cert-portal.siemens.com/productcert/pdf/ssa-661247.pdf", + "decisionReason": null, + "recordedAt": "2025-05-09T12:28:41+00:00", + "fieldMask": [ + "references[]" + ] + }, + "sourceTag": "cert-portal.siemens.com", + "summary": null, + "url": "https://cert-portal.siemens.com/productcert/pdf/ssa-661247.pdf" + }, + { + "kind": null, + "provenance": { + "source": "ghsa", + "kind": "reference", + "value": "https://cert-portal.siemens.com/productcert/pdf/ssa-714170.pdf", + "decisionReason": null, + "recordedAt": "2025-05-09T12:28:41+00:00", + "fieldMask": [ + "references[]" + ] + }, + "sourceTag": "cert-portal.siemens.com", + "summary": null, + "url": "https://cert-portal.siemens.com/productcert/pdf/ssa-714170.pdf" + }, + { + "kind": "advisory", + "provenance": { + "source": "ghsa", + "kind": "reference", + "value": "https://github.com/advisories/GHSA-7rjr-3q55-vv33", + "decisionReason": null, + "recordedAt": "2025-05-09T12:28:41+00:00", + "fieldMask": [ + "references[]" + ] + }, + "sourceTag": "github.com", + "summary": null, + "url": "https://github.com/advisories/GHSA-7rjr-3q55-vv33" + }, + { + "kind": "advisory", + "provenance": { + "source": "ghsa", + "kind": "reference", + "value": "https://github.com/advisories/GHSA-jfh8-c2jp-5v3q", + "decisionReason": null, + "recordedAt": "2025-05-09T12:28:41+00:00", + "fieldMask": [ + "references[]" + ] + }, + "sourceTag": "github.com", + "summary": null, + "url": "https://github.com/advisories/GHSA-jfh8-c2jp-5v3q" + }, + { + "kind": null, + "provenance": { + "source": "ghsa", + "kind": "reference", + "value": "https://lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/EOKPQGV24RRBBI4TBZUDQMM4MEH7MXCY", + "decisionReason": null, + "recordedAt": "2025-05-09T12:28:41+00:00", + "fieldMask": [ + "references[]" + ] + }, + "sourceTag": "lists.fedoraproject.org", + "summary": null, + "url": "https://lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/EOKPQGV24RRBBI4TBZUDQMM4MEH7MXCY" + }, + { + "kind": null, + "provenance": { + "source": "ghsa", + "kind": "reference", + "value": "https://lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/SIG7FZULMNK2XF6FZRU4VWYDQXNMUGAJ", + "decisionReason": null, + "recordedAt": "2025-05-09T12:28:41+00:00", + "fieldMask": [ + "references[]" + ] + }, + "sourceTag": "lists.fedoraproject.org", + "summary": null, + "url": "https://lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/SIG7FZULMNK2XF6FZRU4VWYDQXNMUGAJ" + }, + { + "kind": "advisory", + "provenance": { + "source": "ghsa", + "kind": "reference", + "value": "https://logging.apache.org/log4j/2.x/security.html", + "decisionReason": null, + "recordedAt": "2025-05-09T12:28:41+00:00", + "fieldMask": [ + "references[]" + ] + }, + "sourceTag": "logging.apache.org", + "summary": null, + "url": "https://logging.apache.org/log4j/2.x/security.html" + }, + { + "kind": "advisory", + "provenance": { + "source": "ghsa", + "kind": "reference", + "value": "https://nvd.nist.gov/vuln/detail/CVE-2021-45046", + "decisionReason": null, + "recordedAt": "2025-05-09T12:28:41+00:00", + "fieldMask": [ + "references[]" + ] + }, + "sourceTag": "nvd.nist.gov", + "summary": null, + "url": "https://nvd.nist.gov/vuln/detail/CVE-2021-45046" + }, + { + "kind": null, + "provenance": { + "source": "ghsa", + "kind": "reference", + "value": "https://psirt.global.sonicwall.com/vuln-detail/SNWLID-2021-0032", + "decisionReason": null, + "recordedAt": "2025-05-09T12:28:41+00:00", + "fieldMask": [ + "references[]" + ] + }, + "sourceTag": "psirt.global.sonicwall.com", + "summary": null, + "url": "https://psirt.global.sonicwall.com/vuln-detail/SNWLID-2021-0032" + }, + { + "kind": "advisory", + "provenance": { + "source": "ghsa", + "kind": "reference", + "value": "https://sec.cloudapps.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-apache-log4j-qRuKNEbd", + "decisionReason": null, + "recordedAt": "2025-05-09T12:28:41+00:00", + "fieldMask": [ + "references[]" + ] + }, + "sourceTag": "sec.cloudapps.cisco.com", + "summary": null, + "url": "https://sec.cloudapps.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-apache-log4j-qRuKNEbd" + }, + { + "kind": "advisory", + "provenance": { + "source": "ghsa", + "kind": "reference", + "value": "https://security.gentoo.org/glsa/202310-16", + "decisionReason": null, + "recordedAt": "2025-05-09T12:28:41+00:00", + "fieldMask": [ + "references[]" + ] + }, + "sourceTag": "security.gentoo.org", + "summary": null, + "url": "https://security.gentoo.org/glsa/202310-16" + }, + { + "kind": "advisory", + "provenance": { + "source": "ghsa", + "kind": "reference", + "value": "https://www.cve.org/CVERecord?id=CVE-2021-44228", + "decisionReason": null, + "recordedAt": "2025-05-09T12:28:41+00:00", + "fieldMask": [ + "references[]" + ] + }, + "sourceTag": "www.cve.org", + "summary": null, + "url": "https://www.cve.org/CVERecord?id=CVE-2021-44228" + }, + { + "kind": "advisory", + "provenance": { + "source": "ghsa", + "kind": "reference", + "value": "https://www.debian.org/security/2021/dsa-5022", + "decisionReason": null, + "recordedAt": "2025-05-09T12:28:41+00:00", + "fieldMask": [ + "references[]" + ] + }, + "sourceTag": "www.debian.org", + "summary": null, + "url": "https://www.debian.org/security/2021/dsa-5022" + }, + { + "kind": "advisory", + "provenance": { + "source": "ghsa", + "kind": "reference", + "value": "https://www.intel.com/content/www/us/en/security-center/advisory/intel-sa-00646.html", + "decisionReason": null, + "recordedAt": "2025-05-09T12:28:41+00:00", + "fieldMask": [ + "references[]" + ] + }, + "sourceTag": "www.intel.com", + "summary": null, + "url": "https://www.intel.com/content/www/us/en/security-center/advisory/intel-sa-00646.html" + }, + { + "kind": null, + "provenance": { + "source": "ghsa", + "kind": "reference", + "value": "https://www.kb.cert.org/vuls/id/930724", + "decisionReason": null, + "recordedAt": "2025-05-09T12:28:41+00:00", + "fieldMask": [ + "references[]" + ] + }, + "sourceTag": "www.kb.cert.org", + "summary": null, + "url": "https://www.kb.cert.org/vuls/id/930724" + }, + { + "kind": "advisory", + "provenance": { + "source": "ghsa", + "kind": "reference", + "value": "https://www.openwall.com/lists/oss-security/2021/12/14/4", + "decisionReason": null, + "recordedAt": "2025-05-09T12:28:41+00:00", + "fieldMask": [ + "references[]" + ] + }, + "sourceTag": "www.openwall.com", + "summary": null, + "url": "https://www.openwall.com/lists/oss-security/2021/12/14/4" + }, + { + "kind": "advisory", + "provenance": { + "source": "ghsa", + "kind": "reference", + "value": "https://www.oracle.com/security-alerts/alert-cve-2021-44228.html", + "decisionReason": null, + "recordedAt": "2025-05-09T12:28:41+00:00", + "fieldMask": [ + "references[]" + ] + }, + "sourceTag": "www.oracle.com", + "summary": null, + "url": "https://www.oracle.com/security-alerts/alert-cve-2021-44228.html" + }, + { + "kind": "advisory", + "provenance": { + "source": "ghsa", + "kind": "reference", + "value": "https://www.oracle.com/security-alerts/cpuapr2022.html", + "decisionReason": null, + "recordedAt": "2025-05-09T12:28:41+00:00", + "fieldMask": [ + "references[]" + ] + }, + "sourceTag": "www.oracle.com", + "summary": null, + "url": "https://www.oracle.com/security-alerts/cpuapr2022.html" + }, + { + "kind": "advisory", + "provenance": { + "source": "ghsa", + "kind": "reference", + "value": "https://www.oracle.com/security-alerts/cpujan2022.html", + "decisionReason": null, + "recordedAt": "2025-05-09T12:28:41+00:00", + "fieldMask": [ + "references[]" + ] + }, + "sourceTag": "www.oracle.com", + "summary": null, + "url": "https://www.oracle.com/security-alerts/cpujan2022.html" + }, + { + "kind": "advisory", + "provenance": { + "source": "ghsa", + "kind": "reference", + "value": "https://www.oracle.com/security-alerts/cpujul2022.html", + "decisionReason": null, + "recordedAt": "2025-05-09T12:28:41+00:00", + "fieldMask": [ + "references[]" + ] + }, + "sourceTag": "www.oracle.com", + "summary": null, + "url": "https://www.oracle.com/security-alerts/cpujul2022.html" + } + ], + "severity": "critical", + "summary": "# Impact\n\nThe fix to address [CVE-2021-44228](https://nvd.nist.gov/vuln/detail/CVE-2021-44228) in Apache Log4j 2.15.0 was incomplete in certain non-default configurations. This could allow attackers with control over Thread Context Map (MDC) input data when the logging configuration uses a non-default Pattern Layout with either a Context Lookup (for example, $${ctx:loginId}) or a Thread Context Map pattern (%X, %mdc, or %MDC) to craft malicious input data using a JNDI Lookup pattern resulting in a remote code execution (RCE) attack. \n\n## Affected packages\nOnly the `org.apache.logging.log4j:log4j-core` package is directly affected by this vulnerability. The `org.apache.logging.log4j:log4j-api` should be kept at the same version as the `org.apache.logging.log4j:log4j-core` package to ensure compatability if in use.\n\n# Mitigation\n\nLog4j 2.16.0 fixes this issue by removing support for message lookup patterns and disabling JNDI functionality by default. This issue can be mitigated in prior releases (< 2.16.0) by removing the JndiLookup class from the classpath (example: zip -q -d log4j-core-*.jar org/apache/logging/log4j/core/lookup/JndiLookup.class).\n\nLog4j 2.15.0 restricts JNDI LDAP lookups to localhost by default. Note that previous mitigations involving configuration such as to set the system property `log4j2.formatMsgNoLookups` to `true` do NOT mitigate this specific vulnerability.", + "title": "Incomplete fix for Apache Log4j vulnerability" + }, + { + "advisoryKey": "GHSA-cjjf-27cc-pvmv", + "affectedPackages": [ + { + "type": "semver", + "identifier": "pyload-ng", + "platform": "pip", + "versionRanges": [ + { + "fixedVersion": "0.5.0b3.dev91", + "introducedVersion": null, + "lastAffectedVersion": null, + "primitives": null, + "provenance": { + "source": "ghsa", + "kind": "range", + "value": "pyload-ng", + "decisionReason": null, + "recordedAt": "2025-10-09T15:19:48+00:00", + "fieldMask": [ + "affectedpackages[].versionranges[]" + ] + }, + "rangeExpression": "< 0.5.0b3.dev91", + "rangeKind": "semver" + } + ], + "normalizedVersions": [], + "statuses": [], + "provenance": [ + { + "source": "ghsa", + "kind": "package", + "value": "pyload-ng", + "decisionReason": null, + "recordedAt": "2025-10-09T15:19:48+00:00", + "fieldMask": [ + "affectedpackages[]" + ] + } + ] + } + ], + "aliases": [ + "CVE-2025-61773", + "GHSA-cjjf-27cc-pvmv" + ], + "canonicalMetricId": null, + "credits": [], + "cvssMetrics": [ + { + "baseScore": 8.1, + "baseSeverity": "high", + "provenance": { + "source": "ghsa", + "kind": "cvss", + "value": "CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:N", + "decisionReason": null, + "recordedAt": "2025-10-09T15:19:48+00:00", + "fieldMask": [ + "cvssmetrics[]" + ] + }, + "vector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:N", + "version": "3.1" + } + ], + "cwes": [], + "description": null, + "exploitKnown": false, + "language": "en", + "modified": "2025-10-09T15:19:48+00:00", + "provenance": [ + { + "source": "ghsa", + "kind": "map", + "value": "GHSA-cjjf-27cc-pvmv", + "decisionReason": null, + "recordedAt": "2025-10-09T15:19:48+00:00", + "fieldMask": [ + "advisory" + ] + } + ], + "published": "2025-10-09T15:19:48+00:00", + "references": [ + { + "kind": "advisory", + "provenance": { + "source": "ghsa", + "kind": "reference", + "value": "https://github.com/advisories/GHSA-cjjf-27cc-pvmv", + "decisionReason": null, + "recordedAt": "2025-10-09T15:19:48+00:00", + "fieldMask": [ + "references[]" + ] + }, + "sourceTag": "github.com", + "summary": null, + "url": "https://github.com/advisories/GHSA-cjjf-27cc-pvmv" + }, + { + "kind": "patch", + "provenance": { + "source": "ghsa", + "kind": "reference", + "value": "https://github.com/pyload/pyload/commit/5823327d0b797161c7195a1f660266d30a69f0ca", + "decisionReason": null, + "recordedAt": "2025-10-09T15:19:48+00:00", + "fieldMask": [ + "references[]" + ] + }, + "sourceTag": "github.com", + "summary": null, + "url": "https://github.com/pyload/pyload/commit/5823327d0b797161c7195a1f660266d30a69f0ca" + }, + { + "kind": "patch", + "provenance": { + "source": "ghsa", + "kind": "reference", + "value": "https://github.com/pyload/pyload/pull/4624", + "decisionReason": null, + "recordedAt": "2025-10-09T15:19:48+00:00", + "fieldMask": [ + "references[]" + ] + }, + "sourceTag": "github.com", + "summary": null, + "url": "https://github.com/pyload/pyload/pull/4624" + }, + { + "kind": "advisory", + "provenance": { + "source": "ghsa", + "kind": "reference", + "value": "https://github.com/pyload/pyload/security/advisories/GHSA-cjjf-27cc-pvmv", + "decisionReason": null, + "recordedAt": "2025-10-09T15:19:48+00:00", + "fieldMask": [ + "references[]" + ] + }, + "sourceTag": "github.com", + "summary": null, + "url": "https://github.com/pyload/pyload/security/advisories/GHSA-cjjf-27cc-pvmv" + } + ], + "severity": "high", + "summary": "### Summary\npyLoad web interface contained insufficient input validation in both the Captcha script endpoint and the Click'N'Load (CNL) Blueprint. This flaw allowed untrusted user input to be processed unsafely, which could be exploited by an attacker to inject arbitrary content into the web UI or manipulate request handling. The vulnerability could lead to client-side code execution (XSS) or other unintended behaviors when a malicious payload is submitted.\n\nuser-supplied parameters from HTTP requests were not adequately validated or sanitized before being passed into the application logic and response generation. This allowed crafted input to alter the expected execution flow.\n CNL (Click'N'Load) blueprint exposed unsafe handling of untrusted parameters in HTTP requests. The application did not consistently enforce input validation or encoding, making it possible for an attacker to craft malicious requests.\n\n### PoC\n\n1. Run a vulnerable version of pyLoad prior to commit [`f9d27f2`](https://github.com/pyload/pyload/pull/4624).\n2. Start the web UI and access the Captcha or CNL endpoints.\n3. Submit a crafted request containing malicious JavaScript payloads in unvalidated parameters (`/flash/addcrypted2?jk=function(){alert(1)}&crypted=12345`).\n4. Observe that the payload is reflected and executed in the client’s browser, demonstrating cross-site scripting (XSS).\n\nExample request:\n\n```http\nGET /flash/addcrypted2?jk=function(){alert(1)}&crypted=12345 HTTP/1.1\nHost: 127.0.0.1:8000\nContent-Type: application/x-www-form-urlencoded\nContent-Length: 107\n```\n\n### Impact\n\nExploiting this vulnerability allows an attacker to inject and execute arbitrary JavaScript within the browser session of a user accessing the pyLoad Web UI. In practice, this means an attacker could impersonate an administrator, steal authentication cookies or tokens, and perform unauthorized actions on behalf of the victim. Because the affected endpoints are part of the core interface, a successful attack undermines the trust and security of the entire application, potentially leading to a full compromise of the management interface and the data it controls. The impact is particularly severe in cases where the Web UI is exposed over a network without additional access restrictions, as it enables remote attackers to directly target users with crafted links or requests that trigger the vulnerability.", + "title": "pyLoad CNL and captcha handlers allow Code Injection via unsanitized parameters" + }, + { + "advisoryKey": "GHSA-wv4w-6qv2-qqfg", + "affectedPackages": [ + { + "type": "semver", + "identifier": "social-auth-app-django", + "platform": "pip", + "versionRanges": [ + { + "fixedVersion": "5.6.0", + "introducedVersion": null, + "lastAffectedVersion": null, + "primitives": null, + "provenance": { + "source": "ghsa", + "kind": "range", + "value": "social-auth-app-django", + "decisionReason": null, + "recordedAt": "2025-10-09T17:08:06+00:00", + "fieldMask": [ + "affectedpackages[].versionranges[]" + ] + }, + "rangeExpression": "< 5.6.0", + "rangeKind": "semver" + } + ], + "normalizedVersions": [], + "statuses": [], + "provenance": [ + { + "source": "ghsa", + "kind": "package", + "value": "social-auth-app-django", + "decisionReason": null, + "recordedAt": "2025-10-09T17:08:06+00:00", + "fieldMask": [ + "affectedpackages[]" + ] + } + ] + } + ], + "aliases": [ + "CVE-2025-61783", + "GHSA-wv4w-6qv2-qqfg" + ], + "canonicalMetricId": null, + "credits": [], + "cvssMetrics": [], + "cwes": [], + "description": null, + "exploitKnown": false, + "language": "en", + "modified": "2025-10-09T17:08:06+00:00", + "provenance": [ + { + "source": "ghsa", + "kind": "map", + "value": "GHSA-wv4w-6qv2-qqfg", + "decisionReason": null, + "recordedAt": "2025-10-09T17:08:06+00:00", + "fieldMask": [ + "advisory" + ] + } + ], + "published": "2025-10-09T17:08:05+00:00", + "references": [ + { + "kind": "advisory", + "provenance": { + "source": "ghsa", + "kind": "reference", + "value": "https://github.com/advisories/GHSA-wv4w-6qv2-qqfg", + "decisionReason": null, + "recordedAt": "2025-10-09T17:08:06+00:00", + "fieldMask": [ + "references[]" + ] + }, + "sourceTag": "github.com", + "summary": null, + "url": "https://github.com/advisories/GHSA-wv4w-6qv2-qqfg" + }, + { + "kind": "patch", + "provenance": { + "source": "ghsa", + "kind": "reference", + "value": "https://github.com/python-social-auth/social-app-django/commit/10c80e2ebabeccd4e9c84ad0e16e1db74148ed4c", + "decisionReason": null, + "recordedAt": "2025-10-09T17:08:06+00:00", + "fieldMask": [ + "references[]" + ] + }, + "sourceTag": "github.com", + "summary": null, + "url": "https://github.com/python-social-auth/social-app-django/commit/10c80e2ebabeccd4e9c84ad0e16e1db74148ed4c" + }, + { + "kind": null, + "provenance": { + "source": "ghsa", + "kind": "reference", + "value": "https://github.com/python-social-auth/social-app-django/issues/220", + "decisionReason": null, + "recordedAt": "2025-10-09T17:08:06+00:00", + "fieldMask": [ + "references[]" + ] + }, + "sourceTag": "github.com", + "summary": null, + "url": "https://github.com/python-social-auth/social-app-django/issues/220" + }, + { + "kind": null, + "provenance": { + "source": "ghsa", + "kind": "reference", + "value": "https://github.com/python-social-auth/social-app-django/issues/231", + "decisionReason": null, + "recordedAt": "2025-10-09T17:08:06+00:00", + "fieldMask": [ + "references[]" + ] + }, + "sourceTag": "github.com", + "summary": null, + "url": "https://github.com/python-social-auth/social-app-django/issues/231" + }, + { + "kind": null, + "provenance": { + "source": "ghsa", + "kind": "reference", + "value": "https://github.com/python-social-auth/social-app-django/issues/634", + "decisionReason": null, + "recordedAt": "2025-10-09T17:08:06+00:00", + "fieldMask": [ + "references[]" + ] + }, + "sourceTag": "github.com", + "summary": null, + "url": "https://github.com/python-social-auth/social-app-django/issues/634" + }, + { + "kind": "patch", + "provenance": { + "source": "ghsa", + "kind": "reference", + "value": "https://github.com/python-social-auth/social-app-django/pull/803", + "decisionReason": null, + "recordedAt": "2025-10-09T17:08:06+00:00", + "fieldMask": [ + "references[]" + ] + }, + "sourceTag": "github.com", + "summary": null, + "url": "https://github.com/python-social-auth/social-app-django/pull/803" + }, + { + "kind": "advisory", + "provenance": { + "source": "ghsa", + "kind": "reference", + "value": "https://github.com/python-social-auth/social-app-django/security/advisories/GHSA-wv4w-6qv2-qqfg", + "decisionReason": null, + "recordedAt": "2025-10-09T17:08:06+00:00", + "fieldMask": [ + "references[]" + ] + }, + "sourceTag": "github.com", + "summary": null, + "url": "https://github.com/python-social-auth/social-app-django/security/advisories/GHSA-wv4w-6qv2-qqfg" + } + ], + "severity": "medium", + "summary": "### Impact\n\nUpon authentication, the user could be associated by e-mail even if the `associate_by_email` pipeline was not included. This could lead to account compromise when a third-party authentication service does not validate provided e-mail addresses or doesn't require unique e-mail addresses.\n\n### Patches\n\n* https://github.com/python-social-auth/social-app-django/pull/803\n\n### Workarounds\n\nReview the authentication service policy on e-mail addresses; many will not allow exploiting this vulnerability.", + "title": "Python Social Auth - Django has unsafe account association" + } ] \ No newline at end of file diff --git a/src/Concelier/__Tests/StellaOps.Concelier.Connector.Osv.Tests/Fixtures/osv-ghsa.raw-ghsa.json b/src/Concelier/__Tests/StellaOps.Concelier.Connector.Ghsa.Tests/Fixtures/osv-ghsa.raw-ghsa.json similarity index 98% rename from src/Concelier/__Tests/StellaOps.Concelier.Connector.Osv.Tests/Fixtures/osv-ghsa.raw-ghsa.json rename to src/Concelier/__Tests/StellaOps.Concelier.Connector.Ghsa.Tests/Fixtures/osv-ghsa.raw-ghsa.json index 4d2d84b1c..34893ac5c 100644 --- a/src/Concelier/__Tests/StellaOps.Concelier.Connector.Osv.Tests/Fixtures/osv-ghsa.raw-ghsa.json +++ b/src/Concelier/__Tests/StellaOps.Concelier.Connector.Ghsa.Tests/Fixtures/osv-ghsa.raw-ghsa.json @@ -1,519 +1,519 @@ -[ - { - "ghsa_id": "GHSA-wv4w-6qv2-qqfg", - "cve_id": "CVE-2025-61783", - "url": "https://api.github.com/advisories/GHSA-wv4w-6qv2-qqfg", - "html_url": "https://github.com/advisories/GHSA-wv4w-6qv2-qqfg", - "summary": "Python Social Auth - Django has unsafe account association ", - "description": "### Impact\n\nUpon authentication, the user could be associated by e-mail even if the \u0060associate_by_email\u0060 pipeline was not included. This could lead to account compromise when a third-party authentication service does not validate provided e-mail addresses or doesn\u0027t require unique e-mail addresses.\n\n### Patches\n\n* https://github.com/python-social-auth/social-app-django/pull/803\n\n### Workarounds\n\nReview the authentication service policy on e-mail addresses; many will not allow exploiting this vulnerability.", - "type": "reviewed", - "severity": "medium", - "repository_advisory_url": "https://api.github.com/repos/python-social-auth/social-app-django/security-advisories/GHSA-wv4w-6qv2-qqfg", - "source_code_location": "https://github.com/python-social-auth/social-app-django", - "identifiers": [ - { - "value": "GHSA-wv4w-6qv2-qqfg", - "type": "GHSA" - }, - { - "value": "CVE-2025-61783", - "type": "CVE" - } - ], - "references": [ - "https://github.com/python-social-auth/social-app-django/security/advisories/GHSA-wv4w-6qv2-qqfg", - "https://github.com/python-social-auth/social-app-django/issues/220", - "https://github.com/python-social-auth/social-app-django/issues/231", - "https://github.com/python-social-auth/social-app-django/issues/634", - "https://github.com/python-social-auth/social-app-django/pull/803", - "https://github.com/python-social-auth/social-app-django/commit/10c80e2ebabeccd4e9c84ad0e16e1db74148ed4c", - "https://github.com/advisories/GHSA-wv4w-6qv2-qqfg" - ], - "published_at": "2025-10-09T17:08:05Z", - "updated_at": "2025-10-09T17:08:06Z", - "github_reviewed_at": "2025-10-09T17:08:05Z", - "nvd_published_at": null, - "withdrawn_at": null, - "vulnerabilities": [ - { - "package": { - "ecosystem": "pip", - "name": "social-auth-app-django" - }, - "vulnerable_version_range": "\u003C 5.6.0", - "first_patched_version": "5.6.0", - "vulnerable_functions": [] - } - ], - "cvss_severities": { - "cvss_v3": { - "vector_string": null, - "score": 0.0 - }, - "cvss_v4": { - "vector_string": "CVSS:4.0/AV:N/AC:H/AT:N/PR:N/UI:N/VC:L/VI:L/VA:N/SC:N/SI:N/SA:N", - "score": 6.3 - } - }, - "cwes": [ - { - "cwe_id": "CWE-290", - "name": "Authentication Bypass by Spoofing" - } - ], - "credits": [ - { - "user": { - "login": "mel-mason", - "id": 19391457, - "node_id": "MDQ6VXNlcjE5MzkxNDU3", - "avatar_url": "https://avatars.githubusercontent.com/u/19391457?v=4", - "gravatar_id": "", - "url": "https://api.github.com/users/mel-mason", - "html_url": "https://github.com/mel-mason", - "followers_url": "https://api.github.com/users/mel-mason/followers", - "following_url": "https://api.github.com/users/mel-mason/following{/other_user}", - "gists_url": "https://api.github.com/users/mel-mason/gists{/gist_id}", - "starred_url": "https://api.github.com/users/mel-mason/starred{/owner}{/repo}", - "subscriptions_url": "https://api.github.com/users/mel-mason/subscriptions", - "organizations_url": "https://api.github.com/users/mel-mason/orgs", - "repos_url": "https://api.github.com/users/mel-mason/repos", - "events_url": "https://api.github.com/users/mel-mason/events{/privacy}", - "received_events_url": "https://api.github.com/users/mel-mason/received_events", - "type": "User", - "user_view_type": "public", - "site_admin": false - }, - "type": "reporter" - }, - { - "user": { - "login": "vanya909", - "id": 53380238, - "node_id": "MDQ6VXNlcjUzMzgwMjM4", - "avatar_url": "https://avatars.githubusercontent.com/u/53380238?v=4", - "gravatar_id": "", - "url": "https://api.github.com/users/vanya909", - "html_url": "https://github.com/vanya909", - "followers_url": "https://api.github.com/users/vanya909/followers", - "following_url": "https://api.github.com/users/vanya909/following{/other_user}", - "gists_url": "https://api.github.com/users/vanya909/gists{/gist_id}", - "starred_url": "https://api.github.com/users/vanya909/starred{/owner}{/repo}", - "subscriptions_url": "https://api.github.com/users/vanya909/subscriptions", - "organizations_url": "https://api.github.com/users/vanya909/orgs", - "repos_url": "https://api.github.com/users/vanya909/repos", - "events_url": "https://api.github.com/users/vanya909/events{/privacy}", - "received_events_url": "https://api.github.com/users/vanya909/received_events", - "type": "User", - "user_view_type": "public", - "site_admin": false - }, - "type": "reporter" - }, - { - "user": { - "login": "nijel", - "id": 212189, - "node_id": "MDQ6VXNlcjIxMjE4OQ==", - "avatar_url": "https://avatars.githubusercontent.com/u/212189?v=4", - "gravatar_id": "", - "url": "https://api.github.com/users/nijel", - "html_url": "https://github.com/nijel", - "followers_url": "https://api.github.com/users/nijel/followers", - "following_url": "https://api.github.com/users/nijel/following{/other_user}", - "gists_url": "https://api.github.com/users/nijel/gists{/gist_id}", - "starred_url": "https://api.github.com/users/nijel/starred{/owner}{/repo}", - "subscriptions_url": "https://api.github.com/users/nijel/subscriptions", - "organizations_url": "https://api.github.com/users/nijel/orgs", - "repos_url": "https://api.github.com/users/nijel/repos", - "events_url": "https://api.github.com/users/nijel/events{/privacy}", - "received_events_url": "https://api.github.com/users/nijel/received_events", - "type": "User", - "user_view_type": "public", - "site_admin": false - }, - "type": "remediation_developer" - } - ], - "cvss": { - "vector_string": null, - "score": null - } - }, - { - "ghsa_id": "GHSA-cjjf-27cc-pvmv", - "cve_id": "CVE-2025-61773", - "url": "https://api.github.com/advisories/GHSA-cjjf-27cc-pvmv", - "html_url": "https://github.com/advisories/GHSA-cjjf-27cc-pvmv", - "summary": "pyLoad CNL and captcha handlers allow Code Injection via unsanitized parameters", - "description": "### Summary\npyLoad web interface contained insufficient input validation in both the Captcha script endpoint and the Click\u0027N\u0027Load (CNL) Blueprint. This flaw allowed untrusted user input to be processed unsafely, which could be exploited by an attacker to inject arbitrary content into the web UI or manipulate request handling. The vulnerability could lead to client-side code execution (XSS) or other unintended behaviors when a malicious payload is submitted.\n\nuser-supplied parameters from HTTP requests were not adequately validated or sanitized before being passed into the application logic and response generation. This allowed crafted input to alter the expected execution flow.\n CNL (Click\u0027N\u0027Load) blueprint exposed unsafe handling of untrusted parameters in HTTP requests. The application did not consistently enforce input validation or encoding, making it possible for an attacker to craft malicious requests.\n\n### PoC\n\n1. Run a vulnerable version of pyLoad prior to commit [\u0060f9d27f2\u0060](https://github.com/pyload/pyload/pull/4624).\n2. Start the web UI and access the Captcha or CNL endpoints.\n3. Submit a crafted request containing malicious JavaScript payloads in unvalidated parameters (\u0060/flash/addcrypted2?jk=function(){alert(1)}\u0026crypted=12345\u0060).\n4. Observe that the payload is reflected and executed in the client\u2019s browser, demonstrating cross-site scripting (XSS).\n\nExample request:\n\n\u0060\u0060\u0060http\nGET /flash/addcrypted2?jk=function(){alert(1)}\u0026crypted=12345 HTTP/1.1\nHost: 127.0.0.1:8000\nContent-Type: application/x-www-form-urlencoded\nContent-Length: 107\n\u0060\u0060\u0060\n\n### Impact\n\nExploiting this vulnerability allows an attacker to inject and execute arbitrary JavaScript within the browser session of a user accessing the pyLoad Web UI. In practice, this means an attacker could impersonate an administrator, steal authentication cookies or tokens, and perform unauthorized actions on behalf of the victim. Because the affected endpoints are part of the core interface, a successful attack undermines the trust and security of the entire application, potentially leading to a full compromise of the management interface and the data it controls. The impact is particularly severe in cases where the Web UI is exposed over a network without additional access restrictions, as it enables remote attackers to directly target users with crafted links or requests that trigger the vulnerability.", - "type": "reviewed", - "severity": "high", - "repository_advisory_url": "https://api.github.com/repos/pyload/pyload/security-advisories/GHSA-cjjf-27cc-pvmv", - "source_code_location": "https://github.com/pyload/pyload", - "identifiers": [ - { - "value": "GHSA-cjjf-27cc-pvmv", - "type": "GHSA" - }, - { - "value": "CVE-2025-61773", - "type": "CVE" - } - ], - "references": [ - "https://github.com/pyload/pyload/security/advisories/GHSA-cjjf-27cc-pvmv", - "https://github.com/pyload/pyload/pull/4624", - "https://github.com/pyload/pyload/commit/5823327d0b797161c7195a1f660266d30a69f0ca", - "https://github.com/advisories/GHSA-cjjf-27cc-pvmv" - ], - "published_at": "2025-10-09T15:19:48Z", - "updated_at": "2025-10-09T15:19:48Z", - "github_reviewed_at": "2025-10-09T15:19:48Z", - "nvd_published_at": null, - "withdrawn_at": null, - "vulnerabilities": [ - { - "package": { - "ecosystem": "pip", - "name": "pyload-ng" - }, - "vulnerable_version_range": "\u003C 0.5.0b3.dev91", - "first_patched_version": "0.5.0b3.dev91", - "vulnerable_functions": [] - } - ], - "cvss_severities": { - "cvss_v3": { - "vector_string": "CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:N", - "score": 8.1 - }, - "cvss_v4": { - "vector_string": null, - "score": 0.0 - } - }, - "cwes": [ - { - "cwe_id": "CWE-74", - "name": "Improper Neutralization of Special Elements in Output Used by a Downstream Component (\u0027Injection\u0027)" - }, - { - "cwe_id": "CWE-79", - "name": "Improper Neutralization of Input During Web Page Generation (\u0027Cross-site Scripting\u0027)" - }, - { - "cwe_id": "CWE-94", - "name": "Improper Control of Generation of Code (\u0027Code Injection\u0027)" - }, - { - "cwe_id": "CWE-116", - "name": "Improper Encoding or Escaping of Output" - } - ], - "credits": [ - { - "user": { - "login": "odaysec", - "id": 47859767, - "node_id": "MDQ6VXNlcjQ3ODU5NzY3", - "avatar_url": "https://avatars.githubusercontent.com/u/47859767?v=4", - "gravatar_id": "", - "url": "https://api.github.com/users/odaysec", - "html_url": "https://github.com/odaysec", - "followers_url": "https://api.github.com/users/odaysec/followers", - "following_url": "https://api.github.com/users/odaysec/following{/other_user}", - "gists_url": "https://api.github.com/users/odaysec/gists{/gist_id}", - "starred_url": "https://api.github.com/users/odaysec/starred{/owner}{/repo}", - "subscriptions_url": "https://api.github.com/users/odaysec/subscriptions", - "organizations_url": "https://api.github.com/users/odaysec/orgs", - "repos_url": "https://api.github.com/users/odaysec/repos", - "events_url": "https://api.github.com/users/odaysec/events{/privacy}", - "received_events_url": "https://api.github.com/users/odaysec/received_events", - "type": "User", - "user_view_type": "public", - "site_admin": false - }, - "type": "reporter" - } - ], - "cvss": { - "vector_string": "CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:N", - "score": 8.1 - } - }, - { - "ghsa_id": "GHSA-77vh-xpmg-72qh", - "cve_id": null, - "url": "https://api.github.com/advisories/GHSA-77vh-xpmg-72qh", - "html_url": "https://github.com/advisories/GHSA-77vh-xpmg-72qh", - "summary": "Clarify \u0060mediaType\u0060 handling", - "description": "### Impact\nIn the OCI Image Specification version 1.0.1 and prior, manifest and index documents are not self-describing and documents with a single digest could be interpreted as either a manifest or an index.\n\n### Patches\nThe Image Specification will be updated to recommend that both manifest and index documents contain a \u0060mediaType\u0060 field to identify the type of document.\nRelease [v1.0.2](https://github.com/opencontainers/image-spec/releases/tag/v1.0.2) includes these updates.\n\n### Workarounds\nSoftware attempting to deserialize an ambiguous document may reject the document if it contains both \u201Cmanifests\u201D and \u201Clayers\u201D fields or \u201Cmanifests\u201D and \u201Cconfig\u201D fields.\n\n### References\nhttps://github.com/opencontainers/distribution-spec/security/advisories/GHSA-mc8v-mgrf-8f4m\n\n### For more information\nIf you have any questions or comments about this advisory:\n* Open an issue in https://github.com/opencontainers/image-spec\n* Email us at [security@opencontainers.org](mailto:security@opencontainers.org)\n* https://github.com/opencontainers/image-spec/commits/v1.0.2\n", - "type": "reviewed", - "severity": "low", - "repository_advisory_url": "https://api.github.com/repos/opencontainers/image-spec/security-advisories/GHSA-77vh-xpmg-72qh", - "source_code_location": "https://github.com/opencontainers/image-spec", - "identifiers": [ - { - "value": "GHSA-77vh-xpmg-72qh", - "type": "GHSA" - } - ], - "references": [ - "https://github.com/opencontainers/distribution-spec/security/advisories/GHSA-mc8v-mgrf-8f4m", - "https://github.com/opencontainers/image-spec/security/advisories/GHSA-77vh-xpmg-72qh", - "https://github.com/opencontainers/image-spec/commit/693428a734f5bab1a84bd2f990d92ef1111cd60c", - "https://github.com/opencontainers/image-spec/releases/tag/v1.0.2", - "https://github.com/advisories/GHSA-77vh-xpmg-72qh" - ], - "published_at": "2021-11-18T16:02:41Z", - "updated_at": "2023-01-09T05:05:32Z", - "github_reviewed_at": "2021-11-17T23:13:41Z", - "nvd_published_at": null, - "withdrawn_at": null, - "vulnerabilities": [ - { - "package": { - "ecosystem": "go", - "name": "github.com/opencontainers/image-spec" - }, - "vulnerable_version_range": "\u003C 1.0.2", - "first_patched_version": "1.0.2", - "vulnerable_functions": [] - } - ], - "cvss_severities": { - "cvss_v3": { - "vector_string": "CVSS:3.1/AV:N/AC:H/PR:L/UI:R/S:C/C:N/I:L/A:N", - "score": 3.0 - }, - "cvss_v4": { - "vector_string": null, - "score": 0.0 - } - }, - "cwes": [ - { - "cwe_id": "CWE-843", - "name": "Access of Resource Using Incompatible Type (\u0027Type Confusion\u0027)" - } - ], - "credits": [], - "cvss": { - "vector_string": "CVSS:3.1/AV:N/AC:H/PR:L/UI:R/S:C/C:N/I:L/A:N", - "score": 3.0 - } - }, - { - "ghsa_id": "GHSA-7rjr-3q55-vv33", - "cve_id": "CVE-2021-45046", - "url": "https://api.github.com/advisories/GHSA-7rjr-3q55-vv33", - "html_url": "https://github.com/advisories/GHSA-7rjr-3q55-vv33", - "summary": "Incomplete fix for Apache Log4j vulnerability", - "description": "# Impact\n\nThe fix to address [CVE-2021-44228](https://nvd.nist.gov/vuln/detail/CVE-2021-44228) in Apache Log4j 2.15.0 was incomplete in certain non-default configurations. This could allow attackers with control over Thread Context Map (MDC) input data when the logging configuration uses a non-default Pattern Layout with either a Context Lookup (for example, $${ctx:loginId}) or a Thread Context Map pattern (%X, %mdc, or %MDC) to craft malicious input data using a JNDI Lookup pattern resulting in a remote code execution (RCE) attack. \n\n## Affected packages\nOnly the \u0060org.apache.logging.log4j:log4j-core\u0060 package is directly affected by this vulnerability. The \u0060org.apache.logging.log4j:log4j-api\u0060 should be kept at the same version as the \u0060org.apache.logging.log4j:log4j-core\u0060 package to ensure compatability if in use.\n\n# Mitigation\n\nLog4j 2.16.0 fixes this issue by removing support for message lookup patterns and disabling JNDI functionality by default. This issue can be mitigated in prior releases (\u003C 2.16.0) by removing the JndiLookup class from the classpath (example: zip -q -d log4j-core-*.jar org/apache/logging/log4j/core/lookup/JndiLookup.class).\n\nLog4j 2.15.0 restricts JNDI LDAP lookups to localhost by default. Note that previous mitigations involving configuration such as to set the system property \u0060log4j2.formatMsgNoLookups\u0060 to \u0060true\u0060 do NOT mitigate this specific vulnerability.", - "type": "reviewed", - "severity": "critical", - "repository_advisory_url": null, - "source_code_location": "", - "identifiers": [ - { - "value": "GHSA-7rjr-3q55-vv33", - "type": "GHSA" - }, - { - "value": "CVE-2021-45046", - "type": "CVE" - } - ], - "references": [ - "https://nvd.nist.gov/vuln/detail/CVE-2021-45046", - "https://github.com/advisories/GHSA-jfh8-c2jp-5v3q", - "https://logging.apache.org/log4j/2.x/security.html", - "https://www.openwall.com/lists/oss-security/2021/12/14/4", - "https://www.cve.org/CVERecord?id=CVE-2021-44228", - "http://www.openwall.com/lists/oss-security/2021/12/14/4", - "https://www.intel.com/content/www/us/en/security-center/advisory/intel-sa-00646.html", - "http://www.openwall.com/lists/oss-security/2021/12/15/3", - "https://cert-portal.siemens.com/productcert/pdf/ssa-661247.pdf", - "https://cert-portal.siemens.com/productcert/pdf/ssa-714170.pdf", - "https://www.kb.cert.org/vuls/id/930724", - "https://www.debian.org/security/2021/dsa-5022", - "https://psirt.global.sonicwall.com/vuln-detail/SNWLID-2021-0032", - "https://www.oracle.com/security-alerts/alert-cve-2021-44228.html", - "http://www.openwall.com/lists/oss-security/2021/12/18/1", - "https://cert-portal.siemens.com/productcert/pdf/ssa-397453.pdf", - "https://cert-portal.siemens.com/productcert/pdf/ssa-479842.pdf", - "https://www.oracle.com/security-alerts/cpujan2022.html", - "https://www.oracle.com/security-alerts/cpuapr2022.html", - "https://www.oracle.com/security-alerts/cpujul2022.html", - "https://security.gentoo.org/glsa/202310-16", - "https://lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/SIG7FZULMNK2XF6FZRU4VWYDQXNMUGAJ", - "https://lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/EOKPQGV24RRBBI4TBZUDQMM4MEH7MXCY", - "https://sec.cloudapps.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-apache-log4j-qRuKNEbd", - "https://github.com/advisories/GHSA-7rjr-3q55-vv33" - ], - "published_at": "2021-12-14T18:01:28Z", - "updated_at": "2025-05-09T12:28:41Z", - "github_reviewed_at": "2021-12-14T17:55:00Z", - "nvd_published_at": "2021-12-14T19:15:00Z", - "withdrawn_at": null, - "vulnerabilities": [ - { - "package": { - "ecosystem": "maven", - "name": "org.apache.logging.log4j:log4j-core" - }, - "vulnerable_version_range": "\u003E= 2.13.0, \u003C 2.16.0", - "first_patched_version": "2.16.0", - "vulnerable_functions": [] - }, - { - "package": { - "ecosystem": "maven", - "name": "org.apache.logging.log4j:log4j-core" - }, - "vulnerable_version_range": "\u003C 2.12.2", - "first_patched_version": "2.12.2", - "vulnerable_functions": [] - }, - { - "package": { - "ecosystem": "maven", - "name": "org.ops4j.pax.logging:pax-logging-log4j2" - }, - "vulnerable_version_range": "\u003E= 1.8.0, \u003C 1.9.2", - "first_patched_version": "1.9.2", - "vulnerable_functions": [] - }, - { - "package": { - "ecosystem": "maven", - "name": "org.ops4j.pax.logging:pax-logging-log4j2" - }, - "vulnerable_version_range": "\u003E= 1.10.0, \u003C 1.10.8", - "first_patched_version": "1.10.8", - "vulnerable_functions": [] - }, - { - "package": { - "ecosystem": "maven", - "name": "org.ops4j.pax.logging:pax-logging-log4j2" - }, - "vulnerable_version_range": "\u003E= 1.11.0, \u003C 1.11.11", - "first_patched_version": "1.11.11", - "vulnerable_functions": [] - }, - { - "package": { - "ecosystem": "maven", - "name": "org.ops4j.pax.logging:pax-logging-log4j2" - }, - "vulnerable_version_range": "\u003E= 2.0.0, \u003C 2.0.12", - "first_patched_version": "2.0.12", - "vulnerable_functions": [] - } - ], - "cvss_severities": { - "cvss_v3": { - "vector_string": "CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:C/C:H/I:H/A:H", - "score": 9.1 - }, - "cvss_v4": { - "vector_string": null, - "score": 0.0 - } - }, - "cwes": [ - { - "cwe_id": "CWE-502", - "name": "Deserialization of Untrusted Data" - }, - { - "cwe_id": "CWE-917", - "name": "Improper Neutralization of Special Elements used in an Expression Language Statement (\u0027Expression Language Injection\u0027)" - } - ], - "credits": [ - { - "user": { - "login": "mrjonstrong", - "id": 42520909, - "node_id": "MDQ6VXNlcjQyNTIwOTA5", - "avatar_url": "https://avatars.githubusercontent.com/u/42520909?v=4", - "gravatar_id": "", - "url": "https://api.github.com/users/mrjonstrong", - "html_url": "https://github.com/mrjonstrong", - "followers_url": "https://api.github.com/users/mrjonstrong/followers", - "following_url": "https://api.github.com/users/mrjonstrong/following{/other_user}", - "gists_url": "https://api.github.com/users/mrjonstrong/gists{/gist_id}", - "starred_url": "https://api.github.com/users/mrjonstrong/starred{/owner}{/repo}", - "subscriptions_url": "https://api.github.com/users/mrjonstrong/subscriptions", - "organizations_url": "https://api.github.com/users/mrjonstrong/orgs", - "repos_url": "https://api.github.com/users/mrjonstrong/repos", - "events_url": "https://api.github.com/users/mrjonstrong/events{/privacy}", - "received_events_url": "https://api.github.com/users/mrjonstrong/received_events", - "type": "User", - "user_view_type": "public", - "site_admin": false - }, - "type": "analyst" - }, - { - "user": { - "login": "afdesk", - "id": 19297627, - "node_id": "MDQ6VXNlcjE5Mjk3NjI3", - "avatar_url": "https://avatars.githubusercontent.com/u/19297627?v=4", - "gravatar_id": "", - "url": "https://api.github.com/users/afdesk", - "html_url": "https://github.com/afdesk", - "followers_url": "https://api.github.com/users/afdesk/followers", - "following_url": "https://api.github.com/users/afdesk/following{/other_user}", - "gists_url": "https://api.github.com/users/afdesk/gists{/gist_id}", - "starred_url": "https://api.github.com/users/afdesk/starred{/owner}{/repo}", - "subscriptions_url": "https://api.github.com/users/afdesk/subscriptions", - "organizations_url": "https://api.github.com/users/afdesk/orgs", - "repos_url": "https://api.github.com/users/afdesk/repos", - "events_url": "https://api.github.com/users/afdesk/events{/privacy}", - "received_events_url": "https://api.github.com/users/afdesk/received_events", - "type": "User", - "user_view_type": "public", - "site_admin": false - }, - "type": "analyst" - }, - { - "user": { - "login": "ppkarwasz", - "id": 12533274, - "node_id": "MDQ6VXNlcjEyNTMzMjc0", - "avatar_url": "https://avatars.githubusercontent.com/u/12533274?v=4", - "gravatar_id": "", - "url": "https://api.github.com/users/ppkarwasz", - "html_url": "https://github.com/ppkarwasz", - "followers_url": "https://api.github.com/users/ppkarwasz/followers", - "following_url": "https://api.github.com/users/ppkarwasz/following{/other_user}", - "gists_url": "https://api.github.com/users/ppkarwasz/gists{/gist_id}", - "starred_url": "https://api.github.com/users/ppkarwasz/starred{/owner}{/repo}", - "subscriptions_url": "https://api.github.com/users/ppkarwasz/subscriptions", - "organizations_url": "https://api.github.com/users/ppkarwasz/orgs", - "repos_url": "https://api.github.com/users/ppkarwasz/repos", - "events_url": "https://api.github.com/users/ppkarwasz/events{/privacy}", - "received_events_url": "https://api.github.com/users/ppkarwasz/received_events", - "type": "User", - "user_view_type": "public", - "site_admin": false - }, - "type": "analyst" - } - ], - "cvss": { - "vector_string": "CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:C/C:H/I:H/A:H", - "score": 9.1 - }, - "epss": { - "percentage": 0.9434, - "percentile": 0.9995 - } - } +[ + { + "ghsa_id": "GHSA-wv4w-6qv2-qqfg", + "cve_id": "CVE-2025-61783", + "url": "https://api.github.com/advisories/GHSA-wv4w-6qv2-qqfg", + "html_url": "https://github.com/advisories/GHSA-wv4w-6qv2-qqfg", + "summary": "Python Social Auth - Django has unsafe account association ", + "description": "### Impact\n\nUpon authentication, the user could be associated by e-mail even if the \u0060associate_by_email\u0060 pipeline was not included. This could lead to account compromise when a third-party authentication service does not validate provided e-mail addresses or doesn\u0027t require unique e-mail addresses.\n\n### Patches\n\n* https://github.com/python-social-auth/social-app-django/pull/803\n\n### Workarounds\n\nReview the authentication service policy on e-mail addresses; many will not allow exploiting this vulnerability.", + "type": "reviewed", + "severity": "medium", + "repository_advisory_url": "https://api.github.com/repos/python-social-auth/social-app-django/security-advisories/GHSA-wv4w-6qv2-qqfg", + "source_code_location": "https://github.com/python-social-auth/social-app-django", + "identifiers": [ + { + "value": "GHSA-wv4w-6qv2-qqfg", + "type": "GHSA" + }, + { + "value": "CVE-2025-61783", + "type": "CVE" + } + ], + "references": [ + "https://github.com/python-social-auth/social-app-django/security/advisories/GHSA-wv4w-6qv2-qqfg", + "https://github.com/python-social-auth/social-app-django/issues/220", + "https://github.com/python-social-auth/social-app-django/issues/231", + "https://github.com/python-social-auth/social-app-django/issues/634", + "https://github.com/python-social-auth/social-app-django/pull/803", + "https://github.com/python-social-auth/social-app-django/commit/10c80e2ebabeccd4e9c84ad0e16e1db74148ed4c", + "https://github.com/advisories/GHSA-wv4w-6qv2-qqfg" + ], + "published_at": "2025-10-09T17:08:05Z", + "updated_at": "2025-10-09T17:08:06Z", + "github_reviewed_at": "2025-10-09T17:08:05Z", + "nvd_published_at": null, + "withdrawn_at": null, + "vulnerabilities": [ + { + "package": { + "ecosystem": "pip", + "name": "social-auth-app-django" + }, + "vulnerable_version_range": "\u003C 5.6.0", + "first_patched_version": "5.6.0", + "vulnerable_functions": [] + } + ], + "cvss_severities": { + "cvss_v3": { + "vector_string": null, + "score": 0.0 + }, + "cvss_v4": { + "vector_string": "CVSS:4.0/AV:N/AC:H/AT:N/PR:N/UI:N/VC:L/VI:L/VA:N/SC:N/SI:N/SA:N", + "score": 6.3 + } + }, + "cwes": [ + { + "cwe_id": "CWE-290", + "name": "Authentication Bypass by Spoofing" + } + ], + "credits": [ + { + "user": { + "login": "mel-mason", + "id": 19391457, + "node_id": "MDQ6VXNlcjE5MzkxNDU3", + "avatar_url": "https://avatars.githubusercontent.com/u/19391457?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/mel-mason", + "html_url": "https://github.com/mel-mason", + "followers_url": "https://api.github.com/users/mel-mason/followers", + "following_url": "https://api.github.com/users/mel-mason/following{/other_user}", + "gists_url": "https://api.github.com/users/mel-mason/gists{/gist_id}", + "starred_url": "https://api.github.com/users/mel-mason/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/mel-mason/subscriptions", + "organizations_url": "https://api.github.com/users/mel-mason/orgs", + "repos_url": "https://api.github.com/users/mel-mason/repos", + "events_url": "https://api.github.com/users/mel-mason/events{/privacy}", + "received_events_url": "https://api.github.com/users/mel-mason/received_events", + "type": "User", + "user_view_type": "public", + "site_admin": false + }, + "type": "reporter" + }, + { + "user": { + "login": "vanya909", + "id": 53380238, + "node_id": "MDQ6VXNlcjUzMzgwMjM4", + "avatar_url": "https://avatars.githubusercontent.com/u/53380238?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/vanya909", + "html_url": "https://github.com/vanya909", + "followers_url": "https://api.github.com/users/vanya909/followers", + "following_url": "https://api.github.com/users/vanya909/following{/other_user}", + "gists_url": "https://api.github.com/users/vanya909/gists{/gist_id}", + "starred_url": "https://api.github.com/users/vanya909/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/vanya909/subscriptions", + "organizations_url": "https://api.github.com/users/vanya909/orgs", + "repos_url": "https://api.github.com/users/vanya909/repos", + "events_url": "https://api.github.com/users/vanya909/events{/privacy}", + "received_events_url": "https://api.github.com/users/vanya909/received_events", + "type": "User", + "user_view_type": "public", + "site_admin": false + }, + "type": "reporter" + }, + { + "user": { + "login": "nijel", + "id": 212189, + "node_id": "MDQ6VXNlcjIxMjE4OQ==", + "avatar_url": "https://avatars.githubusercontent.com/u/212189?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/nijel", + "html_url": "https://github.com/nijel", + "followers_url": "https://api.github.com/users/nijel/followers", + "following_url": "https://api.github.com/users/nijel/following{/other_user}", + "gists_url": "https://api.github.com/users/nijel/gists{/gist_id}", + "starred_url": "https://api.github.com/users/nijel/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/nijel/subscriptions", + "organizations_url": "https://api.github.com/users/nijel/orgs", + "repos_url": "https://api.github.com/users/nijel/repos", + "events_url": "https://api.github.com/users/nijel/events{/privacy}", + "received_events_url": "https://api.github.com/users/nijel/received_events", + "type": "User", + "user_view_type": "public", + "site_admin": false + }, + "type": "remediation_developer" + } + ], + "cvss": { + "vector_string": null, + "score": null + } + }, + { + "ghsa_id": "GHSA-cjjf-27cc-pvmv", + "cve_id": "CVE-2025-61773", + "url": "https://api.github.com/advisories/GHSA-cjjf-27cc-pvmv", + "html_url": "https://github.com/advisories/GHSA-cjjf-27cc-pvmv", + "summary": "pyLoad CNL and captcha handlers allow Code Injection via unsanitized parameters", + "description": "### Summary\npyLoad web interface contained insufficient input validation in both the Captcha script endpoint and the Click\u0027N\u0027Load (CNL) Blueprint. This flaw allowed untrusted user input to be processed unsafely, which could be exploited by an attacker to inject arbitrary content into the web UI or manipulate request handling. The vulnerability could lead to client-side code execution (XSS) or other unintended behaviors when a malicious payload is submitted.\n\nuser-supplied parameters from HTTP requests were not adequately validated or sanitized before being passed into the application logic and response generation. This allowed crafted input to alter the expected execution flow.\n CNL (Click\u0027N\u0027Load) blueprint exposed unsafe handling of untrusted parameters in HTTP requests. The application did not consistently enforce input validation or encoding, making it possible for an attacker to craft malicious requests.\n\n### PoC\n\n1. Run a vulnerable version of pyLoad prior to commit [\u0060f9d27f2\u0060](https://github.com/pyload/pyload/pull/4624).\n2. Start the web UI and access the Captcha or CNL endpoints.\n3. Submit a crafted request containing malicious JavaScript payloads in unvalidated parameters (\u0060/flash/addcrypted2?jk=function(){alert(1)}\u0026crypted=12345\u0060).\n4. Observe that the payload is reflected and executed in the client\u2019s browser, demonstrating cross-site scripting (XSS).\n\nExample request:\n\n\u0060\u0060\u0060http\nGET /flash/addcrypted2?jk=function(){alert(1)}\u0026crypted=12345 HTTP/1.1\nHost: 127.0.0.1:8000\nContent-Type: application/x-www-form-urlencoded\nContent-Length: 107\n\u0060\u0060\u0060\n\n### Impact\n\nExploiting this vulnerability allows an attacker to inject and execute arbitrary JavaScript within the browser session of a user accessing the pyLoad Web UI. In practice, this means an attacker could impersonate an administrator, steal authentication cookies or tokens, and perform unauthorized actions on behalf of the victim. Because the affected endpoints are part of the core interface, a successful attack undermines the trust and security of the entire application, potentially leading to a full compromise of the management interface and the data it controls. The impact is particularly severe in cases where the Web UI is exposed over a network without additional access restrictions, as it enables remote attackers to directly target users with crafted links or requests that trigger the vulnerability.", + "type": "reviewed", + "severity": "high", + "repository_advisory_url": "https://api.github.com/repos/pyload/pyload/security-advisories/GHSA-cjjf-27cc-pvmv", + "source_code_location": "https://github.com/pyload/pyload", + "identifiers": [ + { + "value": "GHSA-cjjf-27cc-pvmv", + "type": "GHSA" + }, + { + "value": "CVE-2025-61773", + "type": "CVE" + } + ], + "references": [ + "https://github.com/pyload/pyload/security/advisories/GHSA-cjjf-27cc-pvmv", + "https://github.com/pyload/pyload/pull/4624", + "https://github.com/pyload/pyload/commit/5823327d0b797161c7195a1f660266d30a69f0ca", + "https://github.com/advisories/GHSA-cjjf-27cc-pvmv" + ], + "published_at": "2025-10-09T15:19:48Z", + "updated_at": "2025-10-09T15:19:48Z", + "github_reviewed_at": "2025-10-09T15:19:48Z", + "nvd_published_at": null, + "withdrawn_at": null, + "vulnerabilities": [ + { + "package": { + "ecosystem": "pip", + "name": "pyload-ng" + }, + "vulnerable_version_range": "\u003C 0.5.0b3.dev91", + "first_patched_version": "0.5.0b3.dev91", + "vulnerable_functions": [] + } + ], + "cvss_severities": { + "cvss_v3": { + "vector_string": "CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:N", + "score": 8.1 + }, + "cvss_v4": { + "vector_string": null, + "score": 0.0 + } + }, + "cwes": [ + { + "cwe_id": "CWE-74", + "name": "Improper Neutralization of Special Elements in Output Used by a Downstream Component (\u0027Injection\u0027)" + }, + { + "cwe_id": "CWE-79", + "name": "Improper Neutralization of Input During Web Page Generation (\u0027Cross-site Scripting\u0027)" + }, + { + "cwe_id": "CWE-94", + "name": "Improper Control of Generation of Code (\u0027Code Injection\u0027)" + }, + { + "cwe_id": "CWE-116", + "name": "Improper Encoding or Escaping of Output" + } + ], + "credits": [ + { + "user": { + "login": "odaysec", + "id": 47859767, + "node_id": "MDQ6VXNlcjQ3ODU5NzY3", + "avatar_url": "https://avatars.githubusercontent.com/u/47859767?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/odaysec", + "html_url": "https://github.com/odaysec", + "followers_url": "https://api.github.com/users/odaysec/followers", + "following_url": "https://api.github.com/users/odaysec/following{/other_user}", + "gists_url": "https://api.github.com/users/odaysec/gists{/gist_id}", + "starred_url": "https://api.github.com/users/odaysec/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/odaysec/subscriptions", + "organizations_url": "https://api.github.com/users/odaysec/orgs", + "repos_url": "https://api.github.com/users/odaysec/repos", + "events_url": "https://api.github.com/users/odaysec/events{/privacy}", + "received_events_url": "https://api.github.com/users/odaysec/received_events", + "type": "User", + "user_view_type": "public", + "site_admin": false + }, + "type": "reporter" + } + ], + "cvss": { + "vector_string": "CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:N", + "score": 8.1 + } + }, + { + "ghsa_id": "GHSA-77vh-xpmg-72qh", + "cve_id": null, + "url": "https://api.github.com/advisories/GHSA-77vh-xpmg-72qh", + "html_url": "https://github.com/advisories/GHSA-77vh-xpmg-72qh", + "summary": "Clarify \u0060mediaType\u0060 handling", + "description": "### Impact\nIn the OCI Image Specification version 1.0.1 and prior, manifest and index documents are not self-describing and documents with a single digest could be interpreted as either a manifest or an index.\n\n### Patches\nThe Image Specification will be updated to recommend that both manifest and index documents contain a \u0060mediaType\u0060 field to identify the type of document.\nRelease [v1.0.2](https://github.com/opencontainers/image-spec/releases/tag/v1.0.2) includes these updates.\n\n### Workarounds\nSoftware attempting to deserialize an ambiguous document may reject the document if it contains both \u201Cmanifests\u201D and \u201Clayers\u201D fields or \u201Cmanifests\u201D and \u201Cconfig\u201D fields.\n\n### References\nhttps://github.com/opencontainers/distribution-spec/security/advisories/GHSA-mc8v-mgrf-8f4m\n\n### For more information\nIf you have any questions or comments about this advisory:\n* Open an issue in https://github.com/opencontainers/image-spec\n* Email us at [security@opencontainers.org](mailto:security@opencontainers.org)\n* https://github.com/opencontainers/image-spec/commits/v1.0.2\n", + "type": "reviewed", + "severity": "low", + "repository_advisory_url": "https://api.github.com/repos/opencontainers/image-spec/security-advisories/GHSA-77vh-xpmg-72qh", + "source_code_location": "https://github.com/opencontainers/image-spec", + "identifiers": [ + { + "value": "GHSA-77vh-xpmg-72qh", + "type": "GHSA" + } + ], + "references": [ + "https://github.com/opencontainers/distribution-spec/security/advisories/GHSA-mc8v-mgrf-8f4m", + "https://github.com/opencontainers/image-spec/security/advisories/GHSA-77vh-xpmg-72qh", + "https://github.com/opencontainers/image-spec/commit/693428a734f5bab1a84bd2f990d92ef1111cd60c", + "https://github.com/opencontainers/image-spec/releases/tag/v1.0.2", + "https://github.com/advisories/GHSA-77vh-xpmg-72qh" + ], + "published_at": "2021-11-18T16:02:41Z", + "updated_at": "2023-01-09T05:05:32Z", + "github_reviewed_at": "2021-11-17T23:13:41Z", + "nvd_published_at": null, + "withdrawn_at": null, + "vulnerabilities": [ + { + "package": { + "ecosystem": "go", + "name": "github.com/opencontainers/image-spec" + }, + "vulnerable_version_range": "\u003C 1.0.2", + "first_patched_version": "1.0.2", + "vulnerable_functions": [] + } + ], + "cvss_severities": { + "cvss_v3": { + "vector_string": "CVSS:3.1/AV:N/AC:H/PR:L/UI:R/S:C/C:N/I:L/A:N", + "score": 3.0 + }, + "cvss_v4": { + "vector_string": null, + "score": 0.0 + } + }, + "cwes": [ + { + "cwe_id": "CWE-843", + "name": "Access of Resource Using Incompatible Type (\u0027Type Confusion\u0027)" + } + ], + "credits": [], + "cvss": { + "vector_string": "CVSS:3.1/AV:N/AC:H/PR:L/UI:R/S:C/C:N/I:L/A:N", + "score": 3.0 + } + }, + { + "ghsa_id": "GHSA-7rjr-3q55-vv33", + "cve_id": "CVE-2021-45046", + "url": "https://api.github.com/advisories/GHSA-7rjr-3q55-vv33", + "html_url": "https://github.com/advisories/GHSA-7rjr-3q55-vv33", + "summary": "Incomplete fix for Apache Log4j vulnerability", + "description": "# Impact\n\nThe fix to address [CVE-2021-44228](https://nvd.nist.gov/vuln/detail/CVE-2021-44228) in Apache Log4j 2.15.0 was incomplete in certain non-default configurations. This could allow attackers with control over Thread Context Map (MDC) input data when the logging configuration uses a non-default Pattern Layout with either a Context Lookup (for example, $${ctx:loginId}) or a Thread Context Map pattern (%X, %mdc, or %MDC) to craft malicious input data using a JNDI Lookup pattern resulting in a remote code execution (RCE) attack. \n\n## Affected packages\nOnly the \u0060org.apache.logging.log4j:log4j-core\u0060 package is directly affected by this vulnerability. The \u0060org.apache.logging.log4j:log4j-api\u0060 should be kept at the same version as the \u0060org.apache.logging.log4j:log4j-core\u0060 package to ensure compatability if in use.\n\n# Mitigation\n\nLog4j 2.16.0 fixes this issue by removing support for message lookup patterns and disabling JNDI functionality by default. This issue can be mitigated in prior releases (\u003C 2.16.0) by removing the JndiLookup class from the classpath (example: zip -q -d log4j-core-*.jar org/apache/logging/log4j/core/lookup/JndiLookup.class).\n\nLog4j 2.15.0 restricts JNDI LDAP lookups to localhost by default. Note that previous mitigations involving configuration such as to set the system property \u0060log4j2.formatMsgNoLookups\u0060 to \u0060true\u0060 do NOT mitigate this specific vulnerability.", + "type": "reviewed", + "severity": "critical", + "repository_advisory_url": null, + "source_code_location": "", + "identifiers": [ + { + "value": "GHSA-7rjr-3q55-vv33", + "type": "GHSA" + }, + { + "value": "CVE-2021-45046", + "type": "CVE" + } + ], + "references": [ + "https://nvd.nist.gov/vuln/detail/CVE-2021-45046", + "https://github.com/advisories/GHSA-jfh8-c2jp-5v3q", + "https://logging.apache.org/log4j/2.x/security.html", + "https://www.openwall.com/lists/oss-security/2021/12/14/4", + "https://www.cve.org/CVERecord?id=CVE-2021-44228", + "http://www.openwall.com/lists/oss-security/2021/12/14/4", + "https://www.intel.com/content/www/us/en/security-center/advisory/intel-sa-00646.html", + "http://www.openwall.com/lists/oss-security/2021/12/15/3", + "https://cert-portal.siemens.com/productcert/pdf/ssa-661247.pdf", + "https://cert-portal.siemens.com/productcert/pdf/ssa-714170.pdf", + "https://www.kb.cert.org/vuls/id/930724", + "https://www.debian.org/security/2021/dsa-5022", + "https://psirt.global.sonicwall.com/vuln-detail/SNWLID-2021-0032", + "https://www.oracle.com/security-alerts/alert-cve-2021-44228.html", + "http://www.openwall.com/lists/oss-security/2021/12/18/1", + "https://cert-portal.siemens.com/productcert/pdf/ssa-397453.pdf", + "https://cert-portal.siemens.com/productcert/pdf/ssa-479842.pdf", + "https://www.oracle.com/security-alerts/cpujan2022.html", + "https://www.oracle.com/security-alerts/cpuapr2022.html", + "https://www.oracle.com/security-alerts/cpujul2022.html", + "https://security.gentoo.org/glsa/202310-16", + "https://lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/SIG7FZULMNK2XF6FZRU4VWYDQXNMUGAJ", + "https://lists.fedoraproject.org/archives/list/package-announce@lists.fedoraproject.org/message/EOKPQGV24RRBBI4TBZUDQMM4MEH7MXCY", + "https://sec.cloudapps.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-apache-log4j-qRuKNEbd", + "https://github.com/advisories/GHSA-7rjr-3q55-vv33" + ], + "published_at": "2021-12-14T18:01:28Z", + "updated_at": "2025-05-09T12:28:41Z", + "github_reviewed_at": "2021-12-14T17:55:00Z", + "nvd_published_at": "2021-12-14T19:15:00Z", + "withdrawn_at": null, + "vulnerabilities": [ + { + "package": { + "ecosystem": "maven", + "name": "org.apache.logging.log4j:log4j-core" + }, + "vulnerable_version_range": "\u003E= 2.13.0, \u003C 2.16.0", + "first_patched_version": "2.16.0", + "vulnerable_functions": [] + }, + { + "package": { + "ecosystem": "maven", + "name": "org.apache.logging.log4j:log4j-core" + }, + "vulnerable_version_range": "\u003C 2.12.2", + "first_patched_version": "2.12.2", + "vulnerable_functions": [] + }, + { + "package": { + "ecosystem": "maven", + "name": "org.ops4j.pax.logging:pax-logging-log4j2" + }, + "vulnerable_version_range": "\u003E= 1.8.0, \u003C 1.9.2", + "first_patched_version": "1.9.2", + "vulnerable_functions": [] + }, + { + "package": { + "ecosystem": "maven", + "name": "org.ops4j.pax.logging:pax-logging-log4j2" + }, + "vulnerable_version_range": "\u003E= 1.10.0, \u003C 1.10.8", + "first_patched_version": "1.10.8", + "vulnerable_functions": [] + }, + { + "package": { + "ecosystem": "maven", + "name": "org.ops4j.pax.logging:pax-logging-log4j2" + }, + "vulnerable_version_range": "\u003E= 1.11.0, \u003C 1.11.11", + "first_patched_version": "1.11.11", + "vulnerable_functions": [] + }, + { + "package": { + "ecosystem": "maven", + "name": "org.ops4j.pax.logging:pax-logging-log4j2" + }, + "vulnerable_version_range": "\u003E= 2.0.0, \u003C 2.0.12", + "first_patched_version": "2.0.12", + "vulnerable_functions": [] + } + ], + "cvss_severities": { + "cvss_v3": { + "vector_string": "CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:C/C:H/I:H/A:H", + "score": 9.1 + }, + "cvss_v4": { + "vector_string": null, + "score": 0.0 + } + }, + "cwes": [ + { + "cwe_id": "CWE-502", + "name": "Deserialization of Untrusted Data" + }, + { + "cwe_id": "CWE-917", + "name": "Improper Neutralization of Special Elements used in an Expression Language Statement (\u0027Expression Language Injection\u0027)" + } + ], + "credits": [ + { + "user": { + "login": "mrjonstrong", + "id": 42520909, + "node_id": "MDQ6VXNlcjQyNTIwOTA5", + "avatar_url": "https://avatars.githubusercontent.com/u/42520909?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/mrjonstrong", + "html_url": "https://github.com/mrjonstrong", + "followers_url": "https://api.github.com/users/mrjonstrong/followers", + "following_url": "https://api.github.com/users/mrjonstrong/following{/other_user}", + "gists_url": "https://api.github.com/users/mrjonstrong/gists{/gist_id}", + "starred_url": "https://api.github.com/users/mrjonstrong/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/mrjonstrong/subscriptions", + "organizations_url": "https://api.github.com/users/mrjonstrong/orgs", + "repos_url": "https://api.github.com/users/mrjonstrong/repos", + "events_url": "https://api.github.com/users/mrjonstrong/events{/privacy}", + "received_events_url": "https://api.github.com/users/mrjonstrong/received_events", + "type": "User", + "user_view_type": "public", + "site_admin": false + }, + "type": "analyst" + }, + { + "user": { + "login": "afdesk", + "id": 19297627, + "node_id": "MDQ6VXNlcjE5Mjk3NjI3", + "avatar_url": "https://avatars.githubusercontent.com/u/19297627?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/afdesk", + "html_url": "https://github.com/afdesk", + "followers_url": "https://api.github.com/users/afdesk/followers", + "following_url": "https://api.github.com/users/afdesk/following{/other_user}", + "gists_url": "https://api.github.com/users/afdesk/gists{/gist_id}", + "starred_url": "https://api.github.com/users/afdesk/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/afdesk/subscriptions", + "organizations_url": "https://api.github.com/users/afdesk/orgs", + "repos_url": "https://api.github.com/users/afdesk/repos", + "events_url": "https://api.github.com/users/afdesk/events{/privacy}", + "received_events_url": "https://api.github.com/users/afdesk/received_events", + "type": "User", + "user_view_type": "public", + "site_admin": false + }, + "type": "analyst" + }, + { + "user": { + "login": "ppkarwasz", + "id": 12533274, + "node_id": "MDQ6VXNlcjEyNTMzMjc0", + "avatar_url": "https://avatars.githubusercontent.com/u/12533274?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/ppkarwasz", + "html_url": "https://github.com/ppkarwasz", + "followers_url": "https://api.github.com/users/ppkarwasz/followers", + "following_url": "https://api.github.com/users/ppkarwasz/following{/other_user}", + "gists_url": "https://api.github.com/users/ppkarwasz/gists{/gist_id}", + "starred_url": "https://api.github.com/users/ppkarwasz/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/ppkarwasz/subscriptions", + "organizations_url": "https://api.github.com/users/ppkarwasz/orgs", + "repos_url": "https://api.github.com/users/ppkarwasz/repos", + "events_url": "https://api.github.com/users/ppkarwasz/events{/privacy}", + "received_events_url": "https://api.github.com/users/ppkarwasz/received_events", + "type": "User", + "user_view_type": "public", + "site_admin": false + }, + "type": "analyst" + } + ], + "cvss": { + "vector_string": "CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:C/C:H/I:H/A:H", + "score": 9.1 + }, + "epss": { + "percentage": 0.9434, + "percentile": 0.9995 + } + } ] \ No newline at end of file diff --git a/src/Concelier/__Tests/StellaOps.Concelier.Connector.Osv.Tests/Osv/OsvGhsaParityRegressionTests.cs b/src/Concelier/__Tests/StellaOps.Concelier.Connector.Osv.Tests/Osv/OsvGhsaParityRegressionTests.cs index c6873c347..499eb8c71 100644 --- a/src/Concelier/__Tests/StellaOps.Concelier.Connector.Osv.Tests/Osv/OsvGhsaParityRegressionTests.cs +++ b/src/Concelier/__Tests/StellaOps.Concelier.Connector.Osv.Tests/Osv/OsvGhsaParityRegressionTests.cs @@ -548,12 +548,20 @@ public sealed class OsvGhsaParityRegressionTests } private static string ResolveFixturePath(string filename) - => Path.Combine(ProjectFixtureDirectory, filename); + { + if (IsGhsaFixture(filename)) + { + return Path.Combine(GhsaFixtureDirectory, filename); + } + + return Path.Combine(ProjectFixtureDirectory, filename); + } private static string NormalizeRecordedAt(string input) => RecordedAtRegex.Replace(input, "\"recordedAt\": \"#normalized#\""); private static string ProjectFixtureDirectory { get; } = Path.GetFullPath(Path.Combine(AppContext.BaseDirectory, "..", "..", "..", "Fixtures")); + private static string GhsaFixtureDirectory { get; } = Path.GetFullPath(Path.Combine(ProjectFixtureDirectory, "..", "..", "StellaOps.Concelier.Connector.Ghsa.Tests", "Fixtures")); private static string RebuildSentinelPath => Path.Combine(ProjectFixtureDirectory, ".rebuild"); @@ -568,6 +576,10 @@ public sealed class OsvGhsaParityRegressionTests private static string? NullIfWhitespace(string? value) => string.IsNullOrWhiteSpace(value) ? null : value.Trim(); + private static bool IsGhsaFixture(string filename) + => filename.Contains("raw-ghsa", StringComparison.OrdinalIgnoreCase) + || filename.Contains(".ghsa.", StringComparison.OrdinalIgnoreCase); + private sealed record MeasurementRecord(string Instrument, long Value, IReadOnlyDictionary Tags); } diff --git a/src/Scheduler/Tools/Scheduler.Backfill/BackfillApp.cs b/src/Scheduler/Tools/Scheduler.Backfill/BackfillApp.cs new file mode 100644 index 000000000..5a3020e30 --- /dev/null +++ b/src/Scheduler/Tools/Scheduler.Backfill/BackfillApp.cs @@ -0,0 +1,83 @@ +using System.CommandLine; + +namespace Scheduler.Backfill; + +public static class BackfillApp +{ + public static async Task RunAsync(string[] args) + { + var pgOption = new Option("--pg") + { + Description = "PostgreSQL connection string (falls back to POSTGRES_CONNECTION_STRING)." + }; + + var batchOption = new Option("--batch") + { + Description = "Batch size for inserts (min 50).", + DefaultValueFactory = _ => 500 + }; + + var sourceOption = new Option("--source") + { + Description = "Path to NDJSON file containing GraphBuildJob payloads.", + Required = true + }; + + var dryRunOption = new Option("--dry-run") + { + Description = "Validate and report without inserting rows." + }; + + var timeoutOption = new Option("--timeout-seconds") + { + Description = "Cancel the backfill after the given number of seconds (0 disables).", + DefaultValueFactory = _ => 0 + }; + + var command = new RootCommand("Scheduler graph job backfill tool"); + command.Add(pgOption); + command.Add(batchOption); + command.Add(sourceOption); + command.Add(dryRunOption); + command.Add(timeoutOption); + + command.SetAction(async (parseResult, cancellationToken) => + { + try + { + var pg = parseResult.GetValue(pgOption); + var batch = parseResult.GetValue(batchOption); + var source = parseResult.GetValue(sourceOption); + var dryRun = parseResult.GetValue(dryRunOption); + var timeoutSeconds = parseResult.GetValue(timeoutOption); + + if (source is null) + { + Console.Error.WriteLine("[FAIL] --source is required."); + return 1; + } + + var options = BackfillOptions.From(pg, batch, dryRun, source.FullName, timeoutSeconds); + var runner = new BackfillRunner(options, Console.WriteLine); + + if (options.Timeout is null) + { + await runner.RunAsync(cancellationToken).ConfigureAwait(false); + return 0; + } + + using var cts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken); + cts.CancelAfter(options.Timeout.Value); + await runner.RunAsync(cts.Token).ConfigureAwait(false); + return 0; + } + catch (Exception ex) + { + Console.Error.WriteLine($"[FAIL] {ex.Message}"); + return 1; + } + }); + + return await command.Parse(args).InvokeAsync().ConfigureAwait(false); + } +} diff --git a/src/Scheduler/Tools/Scheduler.Backfill/BackfillRunner.cs b/src/Scheduler/Tools/Scheduler.Backfill/BackfillRunner.cs new file mode 100644 index 000000000..587e4fc70 --- /dev/null +++ b/src/Scheduler/Tools/Scheduler.Backfill/BackfillRunner.cs @@ -0,0 +1,148 @@ +using System.Text.Json; +using Microsoft.Extensions.Logging.Abstractions; +using Microsoft.Extensions.Options; +using StellaOps.Infrastructure.Postgres.Options; +using StellaOps.Scheduler.Models; +using StellaOps.Scheduler.Persistence.Postgres; +using StellaOps.Scheduler.Persistence.Postgres.Repositories; + +namespace Scheduler.Backfill; + +public sealed record BackfillOptions( + string PostgresConnectionString, + int BatchSize, + bool DryRun, + string SourcePath, + TimeSpan? Timeout) +{ + public static BackfillOptions From(string? pgConn, int batchSize, bool dryRun, string sourcePath, int timeoutSeconds) + { + var pg = string.IsNullOrWhiteSpace(pgConn) + ? Environment.GetEnvironmentVariable("POSTGRES_CONNECTION_STRING") + : pgConn; + + if (string.IsNullOrWhiteSpace(pg)) + { + throw new ArgumentException("PostgreSQL connection string is required (--pg or POSTGRES_CONNECTION_STRING)"); + } + + if (string.IsNullOrWhiteSpace(sourcePath)) + { + throw new ArgumentException("Source file path is required (--source)"); + } + + var normalizedBatch = Math.Max(50, batchSize); + var timeout = timeoutSeconds > 0 ? TimeSpan.FromSeconds(timeoutSeconds) : (TimeSpan?)null; + + return new BackfillOptions(pg, normalizedBatch, dryRun, sourcePath, timeout); + } +} + +public sealed class BackfillRunner +{ + private readonly BackfillOptions _options; + private readonly Action _log; + private readonly SchedulerDataSource _dataSource; + private readonly IGraphJobRepository _graphJobRepository; + + public BackfillRunner(BackfillOptions options, Action? log = null) + { + _options = options; + _log = log ?? (_ => { }); + + _dataSource = new SchedulerDataSource(Options.Create(new PostgresOptions + { + ConnectionString = options.PostgresConnectionString, + SchemaName = "scheduler", + CommandTimeoutSeconds = 30, + AutoMigrate = false + }), NullLogger.Instance); + _graphJobRepository = new GraphJobRepository(_dataSource); + } + + public async Task RunAsync(CancellationToken cancellationToken) + { + if (!File.Exists(_options.SourcePath)) + { + throw new FileNotFoundException($"Source file '{_options.SourcePath}' does not exist.", _options.SourcePath); + } + + _log($"Graph job backfill starting (dry-run={_options.DryRun}, batch={_options.BatchSize})."); + + var batch = new List(_options.BatchSize); + var total = 0; + var inserted = 0; + + await foreach (var job in ReadJobsAsync(_options.SourcePath, cancellationToken)) + { + batch.Add(job); + total++; + + if (batch.Count >= _options.BatchSize) + { + inserted += await ProcessBatchAsync(batch, cancellationToken).ConfigureAwait(false); + batch.Clear(); + } + } + + if (batch.Count > 0) + { + inserted += await ProcessBatchAsync(batch, cancellationToken).ConfigureAwait(false); + } + + _log($"Backfill completed. Jobs processed: {total}. Jobs inserted: {inserted}."); + } + + private async Task ProcessBatchAsync(List batch, CancellationToken cancellationToken) + { + if (_options.DryRun) + { + _log($"Dry run: would insert {batch.Count} jobs."); + return 0; + } + + foreach (var job in batch) + { + await _graphJobRepository.InsertAsync(job, cancellationToken).ConfigureAwait(false); + } + + _log($"Inserted {batch.Count} jobs."); + return batch.Count; + } + + private static async IAsyncEnumerable ReadJobsAsync(string path, [System.Runtime.CompilerServices.EnumeratorCancellation] CancellationToken cancellationToken) + { + using var stream = File.OpenRead(path); + using var reader = new StreamReader(stream); + var lineNumber = 0; + + while (true) + { + cancellationToken.ThrowIfCancellationRequested(); + var line = await reader.ReadLineAsync(cancellationToken).ConfigureAwait(false); + if (line is null) + { + break; + } + + lineNumber++; + + if (string.IsNullOrWhiteSpace(line)) + { + continue; + } + + GraphBuildJob job; + try + { + job = CanonicalJsonSerializer.Deserialize(line); + } + catch (JsonException ex) + { + throw new InvalidOperationException($"Failed to parse GraphBuildJob on line {lineNumber}: {ex.Message}"); + } + + yield return job; + } + } +} diff --git a/src/Scheduler/Tools/Scheduler.Backfill/Program.cs b/src/Scheduler/Tools/Scheduler.Backfill/Program.cs index ffe71deb0..6fdc6cddb 100644 --- a/src/Scheduler/Tools/Scheduler.Backfill/Program.cs +++ b/src/Scheduler/Tools/Scheduler.Backfill/Program.cs @@ -1,130 +1,3 @@ - -using Microsoft.Extensions.Logging.Abstractions; -using Microsoft.Extensions.Options; -using Npgsql; using Scheduler.Backfill; -using StellaOps.Scheduler.Models; -using StellaOps.Scheduler.Persistence.Postgres; -using StellaOps.Scheduler.Persistence.Postgres.Repositories; -using StellaOps.Infrastructure.Postgres.Options; -var parsed = ParseArgs(args); -var options = BackfillOptions.From(parsed.PostgresConnection, parsed.BatchSize, parsed.DryRun); - -var runner = new BackfillRunner(options); -await runner.RunAsync(); -return 0; - -static BackfillCliOptions ParseArgs(string[] args) -{ - string? pg = null; - int batch = 500; - bool dryRun = false; - - for (var i = 0; i < args.Length; i++) - { - switch (args[i]) - { - case "--pg" or "-p": - pg = NextValue(args, ref i); - break; - case "--batch": - batch = int.TryParse(NextValue(args, ref i), out var b) ? b : 500; - break; - case "--dry-run": - dryRun = true; - break; - default: - break; - } - } - - return new BackfillCliOptions(pg, batch, dryRun); -} - -static string NextValue(string[] args, ref int index) -{ - if (index + 1 >= args.Length) - { - return string.Empty; - } - index++; - return args[index]; -} - -internal sealed record BackfillCliOptions( - string? PostgresConnection, - int BatchSize, - bool DryRun); - -internal sealed record BackfillOptions( - string PostgresConnectionString, - int BatchSize, - bool DryRun) -{ - public static BackfillOptions From(string? pgConn, int batchSize, bool dryRun) - { - var pg = string.IsNullOrWhiteSpace(pgConn) - ? Environment.GetEnvironmentVariable("POSTGRES_CONNECTION_STRING") - : pgConn; - - if (string.IsNullOrWhiteSpace(pg)) - { - throw new ArgumentException("PostgreSQL connection string is required (--pg or POSTGRES_CONNECTION_STRING)"); - } - - return new BackfillOptions(pg!, Math.Max(50, batchSize), dryRun); - } -} - -internal sealed class BackfillRunner -{ - private readonly BackfillOptions _options; - private readonly NpgsqlDataSource _pg; - private readonly SchedulerDataSource _dataSource; - private readonly IGraphJobRepository _graphJobRepository; - - public BackfillRunner(BackfillOptions options) - { - _options = options; - _pg = NpgsqlDataSource.Create(options.PostgresConnectionString); - _dataSource = new SchedulerDataSource(Options.Create(new PostgresOptions - { - ConnectionString = options.PostgresConnectionString, - SchemaName = "scheduler", - CommandTimeoutSeconds = 30, - AutoMigrate = false - }), NullLogger.Instance); - _graphJobRepository = new GraphJobRepository(_dataSource); - } - - public async Task RunAsync() - { - Console.WriteLine($"Postgres graph job backfill starting (dry-run={_options.DryRun})"); - - // Placeholder: actual copy logic would map legacy export to new Postgres graph_jobs rows. - if (_options.DryRun) - { - Console.WriteLine("Dry run: no changes applied."); - return; - } - - await using var conn = await _dataSource.OpenSystemConnectionAsync(CancellationToken.None); - await using var tx = await conn.BeginTransactionAsync(); - - // Example: seed an empty job to validate wiring - var sample = new GraphBuildJob( - id: Guid.NewGuid().ToString(), - tenantId: "tenant", - sbomId: "sbom", - sbomVersionId: "sbom-ver", - sbomDigest: "sha256:dummy", - status: GraphJobStatus.Pending, - trigger: GraphBuildJobTrigger.Manual, - createdAt: DateTimeOffset.UtcNow); - - await _graphJobRepository.InsertAsync(sample, CancellationToken.None); - await tx.CommitAsync(); - Console.WriteLine("Backfill completed (sample insert)."); - } -} +return await BackfillApp.RunAsync(args); diff --git a/src/Scheduler/Tools/Scheduler.Backfill/Scheduler.Backfill.csproj b/src/Scheduler/Tools/Scheduler.Backfill/Scheduler.Backfill.csproj index a4e2de1e1..97a59df37 100644 --- a/src/Scheduler/Tools/Scheduler.Backfill/Scheduler.Backfill.csproj +++ b/src/Scheduler/Tools/Scheduler.Backfill/Scheduler.Backfill.csproj @@ -14,7 +14,7 @@ - + diff --git a/src/Scheduler/__Tests/StellaOps.Scheduler.Backfill.Tests/BackfillOptionsTests.cs b/src/Scheduler/__Tests/StellaOps.Scheduler.Backfill.Tests/BackfillOptionsTests.cs new file mode 100644 index 000000000..cfe416d22 --- /dev/null +++ b/src/Scheduler/__Tests/StellaOps.Scheduler.Backfill.Tests/BackfillOptionsTests.cs @@ -0,0 +1,61 @@ +using System; +using System.IO; +using System.Threading.Tasks; +using FluentAssertions; +using Scheduler.Backfill; +using StellaOps.Scheduler.Models; +using Xunit; + +namespace StellaOps.Scheduler.Backfill.Tests; + +public sealed class BackfillOptionsTests +{ + [Fact] + public void From_ClampsBatchSize() + { + var options = BackfillOptions.From( + pgConn: "Host=localhost;Username=stella;Password=secret;Database=scheduler", + batchSize: 10, + dryRun: true, + sourcePath: "jobs.ndjson", + timeoutSeconds: 0); + + options.BatchSize.Should().Be(50); + } + + [Fact] + public async Task Runner_DryRun_ParsesNdjson() + { + var job = new GraphBuildJob( + id: "job-1", + tenantId: "tenant", + sbomId: "sbom", + sbomVersionId: "sbom-ver", + sbomDigest: "sha256:abc", + status: GraphJobStatus.Pending, + trigger: GraphBuildJobTrigger.Manual, + createdAt: new DateTimeOffset(2025, 1, 1, 0, 0, 0, TimeSpan.Zero)); + + var json = CanonicalJsonSerializer.Serialize(job); + + var tempPath = Path.GetTempFileName(); + await File.WriteAllTextAsync(tempPath, json + Environment.NewLine); + + try + { + var options = new BackfillOptions( + PostgresConnectionString: "Host=localhost;Username=stella;Password=secret;Database=scheduler", + BatchSize: 50, + DryRun: true, + SourcePath: tempPath, + Timeout: null); + + var runner = new BackfillRunner(options); + await runner.RunAsync(default); + } + finally + { + File.Delete(tempPath); + } + } +} diff --git a/src/Tools/FixtureUpdater/FixtureUpdater.csproj b/src/Tools/FixtureUpdater/FixtureUpdater.csproj index 0de8f24fa..f27309ede 100644 --- a/src/Tools/FixtureUpdater/FixtureUpdater.csproj +++ b/src/Tools/FixtureUpdater/FixtureUpdater.csproj @@ -8,6 +8,7 @@ + diff --git a/src/Tools/FixtureUpdater/FixtureUpdaterApp.cs b/src/Tools/FixtureUpdater/FixtureUpdaterApp.cs new file mode 100644 index 000000000..47f60bba6 --- /dev/null +++ b/src/Tools/FixtureUpdater/FixtureUpdaterApp.cs @@ -0,0 +1,96 @@ +using System.CommandLine; + +namespace StellaOps.Tools.FixtureUpdater; + +public static class FixtureUpdaterApp +{ + public static async Task RunAsync(string[] args) + { + var repoRootOption = new Option("--repo-root") + { + Description = "Repository root used to resolve default fixture paths." + }; + + var osvFixturesOption = new Option("--osv-fixtures") + { + Description = "Directory containing OSV fixtures (raw and snapshot outputs)." + }; + + var ghsaFixturesOption = new Option("--ghsa-fixtures") + { + Description = "Directory containing GHSA fixtures (raw and snapshot outputs)." + }; + + var nvdFixturesOption = new Option("--nvd-fixtures") + { + Description = "Directory containing NVD fixtures (snapshot outputs)." + }; + + var fixedTimeOption = new Option("--fixed-time") + { + Description = "Fixed timestamp used for deterministic fixture generation.", + DefaultValueFactory = _ => FixtureUpdaterDefaults.DefaultFixedTime + }; + + var command = new RootCommand("Rewrites Concelier OSV/GHSA/NVD fixtures deterministically."); + command.Add(repoRootOption); + command.Add(osvFixturesOption); + command.Add(ghsaFixturesOption); + command.Add(nvdFixturesOption); + command.Add(fixedTimeOption); + + command.SetAction((parseResult, _) => + { + var repoRoot = parseResult.GetValue(repoRootOption); + var osvFixtures = parseResult.GetValue(osvFixturesOption); + var ghsaFixtures = parseResult.GetValue(ghsaFixturesOption); + var nvdFixtures = parseResult.GetValue(nvdFixturesOption); + var fixedTime = parseResult.GetValue(fixedTimeOption); + + var resolvedRepoRoot = RepoRootLocator.TryResolve(repoRoot?.FullName); + if (resolvedRepoRoot is null && (osvFixtures is null || ghsaFixtures is null || nvdFixtures is null)) + { + Console.Error.WriteLine("[FixtureUpdater] Unable to resolve repo root. Provide --repo-root or explicit fixture paths."); + return Task.FromResult(2); + } + + var resolvedOsv = ResolvePath(osvFixtures?.FullName, resolvedRepoRoot, FixtureUpdaterDefaults.OsvFixturesRelative); + var resolvedGhsa = ResolvePath(ghsaFixtures?.FullName, resolvedRepoRoot, FixtureUpdaterDefaults.GhsaFixturesRelative); + var resolvedNvd = ResolvePath(nvdFixtures?.FullName, resolvedRepoRoot, FixtureUpdaterDefaults.NvdFixturesRelative); + + if (resolvedOsv is null || resolvedGhsa is null || resolvedNvd is null) + { + Console.Error.WriteLine("[FixtureUpdater] Fixture paths could not be resolved. Provide --osv-fixtures, --ghsa-fixtures, and --nvd-fixtures explicitly."); + return Task.FromResult(2); + } + + var options = new FixtureUpdaterOptions( + resolvedRepoRoot, + resolvedOsv, + resolvedGhsa, + resolvedNvd, + fixedTime); + + var runner = new FixtureUpdaterRunner(options, Console.WriteLine, Console.Error.WriteLine); + var result = runner.Run(); + return Task.FromResult(result.ErrorCount == 0 ? 0 : 1); + }); + + return await command.Parse(args).InvokeAsync().ConfigureAwait(false); + } + + private static string? ResolvePath(string? overridePath, string? repoRoot, string relativePath) + { + if (!string.IsNullOrWhiteSpace(overridePath)) + { + return Path.GetFullPath(overridePath); + } + + if (string.IsNullOrWhiteSpace(repoRoot)) + { + return null; + } + + return Path.GetFullPath(Path.Combine(repoRoot, relativePath)); + } +} diff --git a/src/Tools/FixtureUpdater/FixtureUpdaterRunner.cs b/src/Tools/FixtureUpdater/FixtureUpdaterRunner.cs new file mode 100644 index 000000000..f6bc2ae13 --- /dev/null +++ b/src/Tools/FixtureUpdater/FixtureUpdaterRunner.cs @@ -0,0 +1,532 @@ +using System.Security.Cryptography; +using System.Text; +using System.Text.Json; +using System.Text.Json.Serialization; +using StellaOps.Concelier.Connector.Common; +using StellaOps.Concelier.Connector.Ghsa; +using StellaOps.Concelier.Connector.Ghsa.Internal; +using StellaOps.Concelier.Connector.Nvd; +using StellaOps.Concelier.Connector.Osv; +using StellaOps.Concelier.Connector.Osv.Internal; +using StellaOps.Concelier.Documents; +using StellaOps.Concelier.Models; +using StellaOps.Concelier.Storage; + +namespace StellaOps.Tools.FixtureUpdater; + +public sealed record FixtureUpdaterOptions( + string? RepoRoot, + string OsvFixturesPath, + string GhsaFixturesPath, + string NvdFixturesPath, + DateTimeOffset FixedTime); + +public readonly record struct FixtureUpdateResult(int ErrorCount); + +public sealed class FixtureUpdaterRunner +{ + private readonly FixtureUpdaterOptions _options; + private readonly Action _info; + private readonly Action _error; + private readonly FixtureDeterminism _determinism; + private readonly JsonSerializerOptions _serializerOptions; + private int _errors; + + public FixtureUpdaterRunner(FixtureUpdaterOptions options, Action? info = null, Action? error = null) + { + _options = options; + _info = info ?? (_ => { }); + _error = error ?? (_ => { }); + _determinism = new FixtureDeterminism(options.FixedTime); + _serializerOptions = new JsonSerializerOptions(JsonSerializerDefaults.Web) + { + DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull + }; + } + + public FixtureUpdateResult Run() + { + _errors = 0; + + Directory.CreateDirectory(_options.OsvFixturesPath); + Directory.CreateDirectory(_options.GhsaFixturesPath); + Directory.CreateDirectory(_options.NvdFixturesPath); + + RewriteOsvFixtures(_options.OsvFixturesPath); + RewriteSnapshotFixtures(_options.OsvFixturesPath); + RewriteGhsaFixtures(_options.GhsaFixturesPath); + RewriteCreditParityFixtures(_options.GhsaFixturesPath, _options.NvdFixturesPath); + + return new FixtureUpdateResult(_errors); + } + + private void RewriteOsvFixtures(string fixturesPath) + { + var rawPath = Path.Combine(fixturesPath, "osv-ghsa.raw-osv.json"); + if (!File.Exists(rawPath)) + { + ReportError($"[FixtureUpdater] OSV raw fixture missing: {rawPath}"); + return; + } + + JsonDocument document; + try + { + document = JsonDocument.Parse(File.ReadAllText(rawPath)); + } + catch (JsonException ex) + { + ReportError($"[FixtureUpdater] Failed to parse OSV raw fixture '{rawPath}': {ex.Message}"); + return; + } + + using (document) + { + if (document.RootElement.ValueKind != JsonValueKind.Array) + { + ReportError($"[FixtureUpdater] OSV raw fixture '{rawPath}' is not a JSON array."); + return; + } + + var advisories = new List(); + var index = 0; + foreach (var element in document.RootElement.EnumerateArray()) + { + index++; + OsvVulnerabilityDto? dto; + try + { + dto = JsonSerializer.Deserialize(element.GetRawText(), _serializerOptions); + } + catch (JsonException ex) + { + ReportError($"[FixtureUpdater] OSV entry {index} parse failed in '{rawPath}': {ex.Message}"); + continue; + } + + if (dto is null) + { + ReportError($"[FixtureUpdater] OSV entry {index} was empty in '{rawPath}'."); + continue; + } + + var identifier = dto.Id ?? $"osv-entry-{index}"; + var ecosystem = dto.Affected?.FirstOrDefault()?.Package?.Ecosystem ?? "unknown"; + var capturedAt = dto.Modified ?? dto.Published ?? _determinism.UtcNow; + var uri = new Uri($"https://osv.dev/vulnerability/{identifier}"); + + var documentRecord = new DocumentRecord( + _determinism.CreateGuid("osv-document", identifier), + OsvConnectorPlugin.SourceName, + uri.ToString(), + capturedAt, + "fixture-sha", + DocumentStatuses.PendingMap, + "application/json", + null, + new Dictionary(StringComparer.Ordinal) + { + ["osv.ecosystem"] = ecosystem, + }, + null, + capturedAt, + null, + null); + + var payload = DocumentObject.Parse(element.GetRawText()); + var dtoRecord = new DtoRecord( + _determinism.CreateGuid("osv-dto", identifier), + documentRecord.Id, + OsvConnectorPlugin.SourceName, + "osv.v1", + payload, + capturedAt); + + var advisory = OsvMapper.Map(dto, documentRecord, dtoRecord, ecosystem); + advisories.Add(advisory); + } + + advisories.Sort((left, right) => string.Compare(left.AdvisoryKey, right.AdvisoryKey, StringComparison.Ordinal)); + var snapshot = SnapshotSerializer.ToSnapshot(advisories); + var outputPath = Path.Combine(fixturesPath, "osv-ghsa.osv.json"); + File.WriteAllText(outputPath, snapshot); + _info($"[FixtureUpdater] Updated {outputPath}"); + } + } + + private void RewriteSnapshotFixtures(string fixturesPath) + { + var baselinePublished = new DateTimeOffset(2025, 1, 5, 12, 0, 0, TimeSpan.Zero); + var baselineModified = new DateTimeOffset(2025, 1, 8, 6, 30, 0, TimeSpan.Zero); + var baselineFetched = new DateTimeOffset(2025, 1, 8, 7, 0, 0, TimeSpan.Zero); + + var cases = new (string Ecosystem, string Purl, string PackageName, string SnapshotFile)[] + { + ("npm", "pkg:npm/%40scope%2Fleft-pad", "@scope/left-pad", "osv-npm.snapshot.json"), + ("PyPI", "pkg:pypi/requests", "requests", "osv-pypi.snapshot.json"), + }; + + foreach (var (ecosystem, purl, packageName, snapshotFile) in cases) + { + var dto = new OsvVulnerabilityDto + { + Id = $"OSV-2025-{ecosystem}-0001", + Summary = $"{ecosystem} package vulnerability", + Details = $"Detailed description for {ecosystem} package {packageName}.", + Published = baselinePublished, + Modified = baselineModified, + Aliases = new[] { $"CVE-2025-11{ecosystem.Length}", $"GHSA-{ecosystem.Length}abc-{ecosystem.Length}def-{ecosystem.Length}ghi" }, + Related = new[] { $"OSV-RELATED-{ecosystem}-42" }, + References = new[] + { + new OsvReferenceDto { Url = $"https://example.com/{ecosystem}/advisory", Type = "ADVISORY" }, + new OsvReferenceDto { Url = $"https://example.com/{ecosystem}/fix", Type = "FIX" }, + }, + Severity = new[] + { + new OsvSeverityDto { Type = "CVSS_V3", Score = "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H" }, + }, + Affected = new[] + { + new OsvAffectedPackageDto + { + Package = new OsvPackageDto + { + Ecosystem = ecosystem, + Name = packageName, + Purl = purl, + }, + Ranges = new[] + { + new OsvRangeDto + { + Type = "SEMVER", + Events = new[] + { + new OsvEventDto { Introduced = "0" }, + new OsvEventDto { Fixed = "2.0.0" }, + }, + }, + }, + Versions = new[] { "1.0.0", "1.5.0" }, + EcosystemSpecific = JsonDocument.Parse("{\"severity\":\"high\"}").RootElement.Clone(), + }, + }, + DatabaseSpecific = JsonDocument.Parse("{\"source\":\"osv.dev\"}").RootElement.Clone(), + }; + + var identifier = dto.Id ?? $"snapshot-{ecosystem}"; + var document = new DocumentRecord( + _determinism.CreateGuid("osv-snapshot-document", identifier), + OsvConnectorPlugin.SourceName, + $"https://osv.dev/vulnerability/{dto.Id}", + baselineFetched, + "fixture-sha", + DocumentStatuses.PendingParse, + "application/json", + null, + new Dictionary(StringComparer.Ordinal) { ["osv.ecosystem"] = ecosystem }, + null, + baselineModified, + null); + + var payload = DocumentObject.Parse(JsonSerializer.Serialize(dto, _serializerOptions)); + var dtoRecord = new DtoRecord( + _determinism.CreateGuid("osv-snapshot-dto", identifier), + document.Id, + OsvConnectorPlugin.SourceName, + "osv.v1", + payload, + baselineModified); + + var advisory = OsvMapper.Map(dto, document, dtoRecord, ecosystem); + var snapshot = SnapshotSerializer.ToSnapshot(advisory); + var outputPath = Path.Combine(fixturesPath, snapshotFile); + File.WriteAllText(outputPath, snapshot); + _info($"[FixtureUpdater] Updated {outputPath}"); + } + } + + private void RewriteGhsaFixtures(string fixturesPath) + { + var rawPath = Path.Combine(fixturesPath, "osv-ghsa.raw-ghsa.json"); + if (!File.Exists(rawPath)) + { + ReportError($"[FixtureUpdater] GHSA raw fixture missing: {rawPath}"); + return; + } + + JsonDocument document; + try + { + document = JsonDocument.Parse(File.ReadAllText(rawPath)); + } + catch (JsonException ex) + { + ReportError($"[FixtureUpdater] Failed to parse GHSA raw fixture '{rawPath}': {ex.Message}"); + return; + } + + using (document) + { + if (document.RootElement.ValueKind != JsonValueKind.Array) + { + ReportError($"[FixtureUpdater] GHSA raw fixture '{rawPath}' is not a JSON array."); + return; + } + + var advisories = new List(); + var index = 0; + foreach (var element in document.RootElement.EnumerateArray()) + { + index++; + GhsaRecordDto dto; + try + { + dto = GhsaRecordParser.Parse(Encoding.UTF8.GetBytes(element.GetRawText())); + } + catch (JsonException ex) + { + ReportError($"[FixtureUpdater] GHSA entry {index} parse failed in '{rawPath}': {ex.Message}"); + continue; + } + + var identifier = string.IsNullOrWhiteSpace(dto.GhsaId) ? $"ghsa-entry-{index}" : dto.GhsaId; + var capturedAt = _determinism.UtcNow; + var uri = new Uri($"https://github.com/advisories/{identifier}"); + + var documentRecord = new DocumentRecord( + _determinism.CreateGuid("ghsa-document", identifier), + GhsaConnectorPlugin.SourceName, + uri.ToString(), + capturedAt, + "fixture-sha", + DocumentStatuses.PendingMap, + "application/json", + null, + new Dictionary(StringComparer.Ordinal), + null, + capturedAt, + null, + null); + + var advisory = GhsaMapper.Map(dto, documentRecord, capturedAt); + advisories.Add(advisory); + } + + advisories.Sort((left, right) => string.Compare(left.AdvisoryKey, right.AdvisoryKey, StringComparison.Ordinal)); + var snapshot = SnapshotSerializer.ToSnapshot(advisories); + var outputPath = Path.Combine(fixturesPath, "osv-ghsa.ghsa.json"); + File.WriteAllText(outputPath, snapshot); + _info($"[FixtureUpdater] Updated {outputPath}"); + } + } + + private void RewriteCreditParityFixtures(string ghsaFixturesPath, string nvdFixturesPath) + { + Directory.CreateDirectory(ghsaFixturesPath); + Directory.CreateDirectory(nvdFixturesPath); + + var advisoryKeyGhsa = "GHSA-credit-parity"; + var advisoryKeyNvd = "CVE-2025-5555"; + var recordedAt = new DateTimeOffset(2025, 10, 10, 15, 0, 0, TimeSpan.Zero); + var published = new DateTimeOffset(2025, 10, 9, 18, 30, 0, TimeSpan.Zero); + var modified = new DateTimeOffset(2025, 10, 10, 12, 0, 0, TimeSpan.Zero); + + AdvisoryCredit[] CreateCredits(string source) => + [ + CreateCredit("Alice Researcher", "reporter", new[] { "mailto:alice.researcher@example.com" }, source), + CreateCredit("Bob Maintainer", "remediation_developer", new[] { "https://github.com/acme/bob-maintainer" }, source) + ]; + + AdvisoryCredit CreateCredit(string displayName, string role, IReadOnlyList contacts, string source) + { + var provenance = new AdvisoryProvenance( + source, + "credit", + $"{source}:{displayName.ToLowerInvariant().Replace(' ', '-')}", + recordedAt, + new[] { ProvenanceFieldMasks.Credits }); + + return new AdvisoryCredit(displayName, role, contacts, provenance); + } + + AdvisoryReference[] CreateReferences(string sourceName, params (string Url, string Kind)[] entries) + { + if (entries is null || entries.Length == 0) + { + return Array.Empty(); + } + + var references = new List(entries.Length); + foreach (var entry in entries) + { + var provenance = new AdvisoryProvenance( + sourceName, + "reference", + entry.Url, + recordedAt, + new[] { ProvenanceFieldMasks.References }); + + references.Add(new AdvisoryReference( + entry.Url, + entry.Kind, + sourceTag: null, + summary: null, + provenance)); + } + + return references.ToArray(); + } + + Advisory CreateAdvisory( + string sourceName, + string advisoryKey, + IEnumerable aliases, + AdvisoryCredit[] credits, + AdvisoryReference[] references, + string documentValue) + { + var documentProvenance = new AdvisoryProvenance( + sourceName, + "document", + documentValue, + recordedAt, + new[] { ProvenanceFieldMasks.Advisory }); + var mappingProvenance = new AdvisoryProvenance( + sourceName, + "mapping", + advisoryKey, + recordedAt, + new[] { ProvenanceFieldMasks.Advisory }); + + return new Advisory( + advisoryKey, + "Credit parity regression fixture", + "Credit parity regression fixture", + "en", + published, + modified, + "moderate", + exploitKnown: false, + aliases, + credits, + references, + Array.Empty(), + Array.Empty(), + new[] { documentProvenance, mappingProvenance }); + } + + var ghsa = CreateAdvisory( + "ghsa", + advisoryKeyGhsa, + new[] { advisoryKeyGhsa, advisoryKeyNvd }, + CreateCredits("ghsa"), + CreateReferences( + "ghsa", + ($"https://github.com/advisories/{advisoryKeyGhsa}", "advisory"), + ("https://example.com/ghsa/patch", "patch")), + $"security/advisories/{advisoryKeyGhsa}"); + + var osv = CreateAdvisory( + OsvConnectorPlugin.SourceName, + advisoryKeyGhsa, + new[] { advisoryKeyGhsa, advisoryKeyNvd }, + CreateCredits(OsvConnectorPlugin.SourceName), + CreateReferences( + OsvConnectorPlugin.SourceName, + ($"https://github.com/advisories/{advisoryKeyGhsa}", "advisory"), + ($"https://osv.dev/vulnerability/{advisoryKeyGhsa}", "advisory")), + $"https://osv.dev/vulnerability/{advisoryKeyGhsa}"); + + var nvd = CreateAdvisory( + NvdConnectorPlugin.SourceName, + advisoryKeyNvd, + new[] { advisoryKeyNvd, advisoryKeyGhsa }, + CreateCredits(NvdConnectorPlugin.SourceName), + CreateReferences( + NvdConnectorPlugin.SourceName, + ($"https://services.nvd.nist.gov/vuln/detail/{advisoryKeyNvd}", "advisory"), + ("https://example.com/nvd/reference", "report")), + $"https://services.nvd.nist.gov/vuln/detail/{advisoryKeyNvd}"); + + var ghsaSnapshot = SnapshotSerializer.ToSnapshot(ghsa); + var osvSnapshot = SnapshotSerializer.ToSnapshot(osv); + var nvdSnapshot = SnapshotSerializer.ToSnapshot(nvd); + + File.WriteAllText(Path.Combine(ghsaFixturesPath, "credit-parity.ghsa.json"), ghsaSnapshot); + File.WriteAllText(Path.Combine(ghsaFixturesPath, "credit-parity.osv.json"), osvSnapshot); + File.WriteAllText(Path.Combine(ghsaFixturesPath, "credit-parity.nvd.json"), nvdSnapshot); + + File.WriteAllText(Path.Combine(nvdFixturesPath, "credit-parity.ghsa.json"), ghsaSnapshot); + File.WriteAllText(Path.Combine(nvdFixturesPath, "credit-parity.osv.json"), osvSnapshot); + File.WriteAllText(Path.Combine(nvdFixturesPath, "credit-parity.nvd.json"), nvdSnapshot); + + _info($"[FixtureUpdater] Updated credit parity fixtures under {ghsaFixturesPath} and {nvdFixturesPath}"); + } + + private void ReportError(string message) + { + _errors++; + _error(message); + } +} + +internal sealed class FixtureDeterminism +{ + private readonly DateTimeOffset _fixedTime; + + public FixtureDeterminism(DateTimeOffset fixedTime) + { + _fixedTime = fixedTime; + } + + public DateTimeOffset UtcNow => _fixedTime; + + public Guid CreateGuid(string scope, string key) + => CreateDeterministicGuid($"{scope}:{key}"); + + private static Guid CreateDeterministicGuid(string value) + { + using var sha = SHA256.Create(); + var hash = sha.ComputeHash(Encoding.UTF8.GetBytes(value)); + Span bytes = stackalloc byte[16]; + hash.AsSpan(0, 16).CopyTo(bytes); + bytes[6] = (byte)((bytes[6] & 0x0F) | 0x50); + bytes[8] = (byte)((bytes[8] & 0x3F) | 0x80); + return new Guid(bytes); + } +} + +internal static class RepoRootLocator +{ + public static string? TryResolve(string? repoRoot) + { + if (!string.IsNullOrWhiteSpace(repoRoot)) + { + return Path.GetFullPath(repoRoot); + } + + var current = new DirectoryInfo(Directory.GetCurrentDirectory()); + while (current is not null) + { + var solutionPath = Path.Combine(current.FullName, "src", "StellaOps.sln"); + if (File.Exists(solutionPath)) + { + return current.FullName; + } + + current = current.Parent; + } + + return null; + } +} + +internal static class FixtureUpdaterDefaults +{ + public static readonly DateTimeOffset DefaultFixedTime = new(2025, 1, 5, 0, 0, 0, TimeSpan.Zero); + public static readonly string OsvFixturesRelative = Path.Combine("src", "Concelier", "__Tests", "StellaOps.Concelier.Connector.Osv.Tests", "Fixtures"); + public static readonly string GhsaFixturesRelative = Path.Combine("src", "Concelier", "__Tests", "StellaOps.Concelier.Connector.Ghsa.Tests", "Fixtures"); + public static readonly string NvdFixturesRelative = Path.Combine("src", "Concelier", "__Tests", "StellaOps.Concelier.Connector.Nvd.Tests", "Nvd", "Fixtures"); +} diff --git a/src/Tools/FixtureUpdater/Program.cs b/src/Tools/FixtureUpdater/Program.cs index 785e3ab35..c0e777f4f 100644 --- a/src/Tools/FixtureUpdater/Program.cs +++ b/src/Tools/FixtureUpdater/Program.cs @@ -1,377 +1,3 @@ -using System.Linq; -using System.Text; -using System.Text.Json; -using System.Text.Json.Serialization; -using StellaOps.Concelier.Models; -using StellaOps.Concelier.Connector.Ghsa; -using StellaOps.Concelier.Connector.Common; -using StellaOps.Concelier.Connector.Ghsa.Internal; -using StellaOps.Concelier.Connector.Osv.Internal; -using StellaOps.Concelier.Connector.Osv; -using StellaOps.Concelier.Connector.Nvd; -using StellaOps.Concelier.Storage; -using StellaOps.Concelier.Documents; +using StellaOps.Tools.FixtureUpdater; -var serializerOptions = new JsonSerializerOptions(JsonSerializerDefaults.Web) -{ - DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull, -}; - -var projectRoot = Path.GetFullPath(Path.Combine(AppContext.BaseDirectory, "..", "..", "..", "..", "..")); - -var osvFixturesPath = Path.Combine(projectRoot, "src", "StellaOps.Concelier.Connector.Osv.Tests", "Fixtures"); -var ghsaFixturesPath = Path.Combine(projectRoot, "src", "StellaOps.Concelier.Connector.Ghsa.Tests", "Fixtures"); -var nvdFixturesPath = Path.Combine(projectRoot, "src", "StellaOps.Concelier.Connector.Nvd.Tests", "Nvd", "Fixtures"); - -RewriteOsvFixtures(osvFixturesPath); -RewriteSnapshotFixtures(osvFixturesPath); -RewriteGhsaFixtures(osvFixturesPath); -RewriteCreditParityFixtures(ghsaFixturesPath, nvdFixturesPath); -return; - -void RewriteOsvFixtures(string fixturesPath) -{ - var rawPath = Path.Combine(fixturesPath, "osv-ghsa.raw-osv.json"); - if (!File.Exists(rawPath)) - { - Console.WriteLine($"[FixtureUpdater] OSV raw fixture missing: {rawPath}"); - return; - } - - using var document = JsonDocument.Parse(File.ReadAllText(rawPath)); - var advisories = new List(); - foreach (var element in document.RootElement.EnumerateArray()) - { - var dto = JsonSerializer.Deserialize(element.GetRawText(), serializerOptions); - if (dto is null) - { - continue; - } - - var ecosystem = dto.Affected?.FirstOrDefault()?.Package?.Ecosystem ?? "unknown"; - var uri = new Uri($"https://osv.dev/vulnerability/{dto.Id}"); - var documentRecord = new DocumentRecord( - Guid.NewGuid(), - OsvConnectorPlugin.SourceName, - uri.ToString(), - DateTimeOffset.UtcNow, - "fixture-sha", - DocumentStatuses.PendingMap, - "application/json", - null, - new Dictionary(StringComparer.Ordinal) - { - ["osv.ecosystem"] = ecosystem, - }, - null, - DateTimeOffset.UtcNow, - null, - null); - - var payload = DocumentObject.Parse(element.GetRawText()); - var dtoRecord = new DtoRecord( - Guid.NewGuid(), - documentRecord.Id, - OsvConnectorPlugin.SourceName, - "osv.v1", - payload, - DateTimeOffset.UtcNow); - - var advisory = OsvMapper.Map(dto, documentRecord, dtoRecord, ecosystem); - advisories.Add(advisory); - } - - advisories.Sort((left, right) => string.Compare(left.AdvisoryKey, right.AdvisoryKey, StringComparison.Ordinal)); - var snapshot = SnapshotSerializer.ToSnapshot(advisories); - File.WriteAllText(Path.Combine(fixturesPath, "osv-ghsa.osv.json"), snapshot); - Console.WriteLine($"[FixtureUpdater] Updated {Path.Combine(fixturesPath, "osv-ghsa.osv.json")}"); -} - -void RewriteSnapshotFixtures(string fixturesPath) -{ - var baselinePublished = new DateTimeOffset(2025, 1, 5, 12, 0, 0, TimeSpan.Zero); - var baselineModified = new DateTimeOffset(2025, 1, 8, 6, 30, 0, TimeSpan.Zero); - var baselineFetched = new DateTimeOffset(2025, 1, 8, 7, 0, 0, TimeSpan.Zero); - - var cases = new (string Ecosystem, string Purl, string PackageName, string SnapshotFile)[] - { - ("npm", "pkg:npm/%40scope%2Fleft-pad", "@scope/left-pad", "osv-npm.snapshot.json"), - ("PyPI", "pkg:pypi/requests", "requests", "osv-pypi.snapshot.json"), - }; - - foreach (var (ecosystem, purl, packageName, snapshotFile) in cases) - { - var dto = new OsvVulnerabilityDto - { - Id = $"OSV-2025-{ecosystem}-0001", - Summary = $"{ecosystem} package vulnerability", - Details = $"Detailed description for {ecosystem} package {packageName}.", - Published = baselinePublished, - Modified = baselineModified, - Aliases = new[] { $"CVE-2025-11{ecosystem.Length}", $"GHSA-{ecosystem.Length}abc-{ecosystem.Length}def-{ecosystem.Length}ghi" }, - Related = new[] { $"OSV-RELATED-{ecosystem}-42" }, - References = new[] - { - new OsvReferenceDto { Url = $"https://example.com/{ecosystem}/advisory", Type = "ADVISORY" }, - new OsvReferenceDto { Url = $"https://example.com/{ecosystem}/fix", Type = "FIX" }, - }, - Severity = new[] - { - new OsvSeverityDto { Type = "CVSS_V3", Score = "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H" }, - }, - Affected = new[] - { - new OsvAffectedPackageDto - { - Package = new OsvPackageDto - { - Ecosystem = ecosystem, - Name = packageName, - Purl = purl, - }, - Ranges = new[] - { - new OsvRangeDto - { - Type = "SEMVER", - Events = new[] - { - new OsvEventDto { Introduced = "0" }, - new OsvEventDto { Fixed = "2.0.0" }, - }, - }, - }, - Versions = new[] { "1.0.0", "1.5.0" }, - EcosystemSpecific = JsonDocument.Parse("{\"severity\":\"high\"}").RootElement.Clone(), - }, - }, - DatabaseSpecific = JsonDocument.Parse("{\"source\":\"osv.dev\"}").RootElement.Clone(), - }; - - var document = new DocumentRecord( - Guid.NewGuid(), - OsvConnectorPlugin.SourceName, - $"https://osv.dev/vulnerability/{dto.Id}", - baselineFetched, - "fixture-sha", - DocumentStatuses.PendingParse, - "application/json", - null, - new Dictionary(StringComparer.Ordinal) { ["osv.ecosystem"] = ecosystem }, - null, - baselineModified, - null); - - var payload = DocumentObject.Parse(JsonSerializer.Serialize(dto, serializerOptions)); - var dtoRecord = new DtoRecord(Guid.NewGuid(), document.Id, OsvConnectorPlugin.SourceName, "osv.v1", payload, baselineModified); - - var advisory = OsvMapper.Map(dto, document, dtoRecord, ecosystem); - var snapshot = SnapshotSerializer.ToSnapshot(advisory); - File.WriteAllText(Path.Combine(fixturesPath, snapshotFile), snapshot); - Console.WriteLine($"[FixtureUpdater] Updated {Path.Combine(fixturesPath, snapshotFile)}"); - } -} - -void RewriteGhsaFixtures(string fixturesPath) -{ - var rawPath = Path.Combine(fixturesPath, "osv-ghsa.raw-ghsa.json"); - if (!File.Exists(rawPath)) - { - Console.WriteLine($"[FixtureUpdater] GHSA raw fixture missing: {rawPath}"); - return; - } - - JsonDocument document; - try - { - document = JsonDocument.Parse(File.ReadAllText(rawPath)); - } - catch (JsonException ex) - { - Console.WriteLine($"[FixtureUpdater] Failed to parse GHSA raw fixture '{rawPath}': {ex.Message}"); - return; - } - using (document) - { - var advisories = new List(); - foreach (var element in document.RootElement.EnumerateArray()) - { - GhsaRecordDto dto; - try - { - dto = GhsaRecordParser.Parse(Encoding.UTF8.GetBytes(element.GetRawText())); - } - catch (JsonException) - { - continue; - } - - var uri = new Uri($"https://github.com/advisories/{dto.GhsaId}"); - var documentRecord = new DocumentRecord( - Guid.NewGuid(), - GhsaConnectorPlugin.SourceName, - uri.ToString(), - DateTimeOffset.UtcNow, - "fixture-sha", - DocumentStatuses.PendingMap, - "application/json", - null, - new Dictionary(StringComparer.Ordinal), - null, - DateTimeOffset.UtcNow, - null, - null); - - var advisory = GhsaMapper.Map(dto, documentRecord, DateTimeOffset.UtcNow); - advisories.Add(advisory); - } - - advisories.Sort((left, right) => string.Compare(left.AdvisoryKey, right.AdvisoryKey, StringComparison.Ordinal)); - var snapshot = SnapshotSerializer.ToSnapshot(advisories); - File.WriteAllText(Path.Combine(fixturesPath, "osv-ghsa.ghsa.json"), snapshot); - Console.WriteLine($"[FixtureUpdater] Updated {Path.Combine(fixturesPath, "osv-ghsa.ghsa.json")}"); - } -} - -void RewriteCreditParityFixtures(string ghsaFixturesPath, string nvdFixturesPath) -{ - Directory.CreateDirectory(ghsaFixturesPath); - Directory.CreateDirectory(nvdFixturesPath); - - var advisoryKeyGhsa = "GHSA-credit-parity"; - var advisoryKeyNvd = "CVE-2025-5555"; - var recordedAt = new DateTimeOffset(2025, 10, 10, 15, 0, 0, TimeSpan.Zero); - var published = new DateTimeOffset(2025, 10, 9, 18, 30, 0, TimeSpan.Zero); - var modified = new DateTimeOffset(2025, 10, 10, 12, 0, 0, TimeSpan.Zero); - - AdvisoryCredit[] CreateCredits(string source) => - [ - CreateCredit("Alice Researcher", "reporter", new[] { "mailto:alice.researcher@example.com" }, source), - CreateCredit("Bob Maintainer", "remediation_developer", new[] { "https://github.com/acme/bob-maintainer" }, source) - ]; - - AdvisoryCredit CreateCredit(string displayName, string role, IReadOnlyList contacts, string source) - { - var provenance = new AdvisoryProvenance( - source, - "credit", - $"{source}:{displayName.ToLowerInvariant().Replace(' ', '-')}", - recordedAt, - new[] { ProvenanceFieldMasks.Credits }); - - return new AdvisoryCredit(displayName, role, contacts, provenance); - } - - AdvisoryReference[] CreateReferences(string sourceName, params (string Url, string Kind)[] entries) - { - if (entries is null || entries.Length == 0) - { - return Array.Empty(); - } - - var references = new List(entries.Length); - foreach (var entry in entries) - { - var provenance = new AdvisoryProvenance( - sourceName, - "reference", - entry.Url, - recordedAt, - new[] { ProvenanceFieldMasks.References }); - - references.Add(new AdvisoryReference( - entry.Url, - entry.Kind, - sourceTag: null, - summary: null, - provenance)); - } - - return references.ToArray(); - } - - Advisory CreateAdvisory( - string sourceName, - string advisoryKey, - IEnumerable aliases, - AdvisoryCredit[] credits, - AdvisoryReference[] references, - string documentValue) - { - var documentProvenance = new AdvisoryProvenance( - sourceName, - "document", - documentValue, - recordedAt, - new[] { ProvenanceFieldMasks.Advisory }); - var mappingProvenance = new AdvisoryProvenance( - sourceName, - "mapping", - advisoryKey, - recordedAt, - new[] { ProvenanceFieldMasks.Advisory }); - - return new Advisory( - advisoryKey, - "Credit parity regression fixture", - "Credit parity regression fixture", - "en", - published, - modified, - "moderate", - exploitKnown: false, - aliases, - credits, - references, - Array.Empty(), - Array.Empty(), - new[] { documentProvenance, mappingProvenance }); - } - - var ghsa = CreateAdvisory( - "ghsa", - advisoryKeyGhsa, - new[] { advisoryKeyGhsa, advisoryKeyNvd }, - CreateCredits("ghsa"), - CreateReferences( - "ghsa", - ( $"https://github.com/advisories/{advisoryKeyGhsa}", "advisory"), - ( "https://example.com/ghsa/patch", "patch")), - $"security/advisories/{advisoryKeyGhsa}"); - - var osv = CreateAdvisory( - OsvConnectorPlugin.SourceName, - advisoryKeyGhsa, - new[] { advisoryKeyGhsa, advisoryKeyNvd }, - CreateCredits(OsvConnectorPlugin.SourceName), - CreateReferences( - OsvConnectorPlugin.SourceName, - ( $"https://github.com/advisories/{advisoryKeyGhsa}", "advisory"), - ( $"https://osv.dev/vulnerability/{advisoryKeyGhsa}", "advisory")), - $"https://osv.dev/vulnerability/{advisoryKeyGhsa}"); - - var nvd = CreateAdvisory( - NvdConnectorPlugin.SourceName, - advisoryKeyNvd, - new[] { advisoryKeyNvd, advisoryKeyGhsa }, - CreateCredits(NvdConnectorPlugin.SourceName), - CreateReferences( - NvdConnectorPlugin.SourceName, - ( $"https://services.nvd.nist.gov/vuln/detail/{advisoryKeyNvd}", "advisory"), - ( "https://example.com/nvd/reference", "report")), - $"https://services.nvd.nist.gov/vuln/detail/{advisoryKeyNvd}"); - - var ghsaSnapshot = SnapshotSerializer.ToSnapshot(ghsa); - var osvSnapshot = SnapshotSerializer.ToSnapshot(osv); - var nvdSnapshot = SnapshotSerializer.ToSnapshot(nvd); - - File.WriteAllText(Path.Combine(ghsaFixturesPath, "credit-parity.ghsa.json"), ghsaSnapshot); - File.WriteAllText(Path.Combine(ghsaFixturesPath, "credit-parity.osv.json"), osvSnapshot); - File.WriteAllText(Path.Combine(ghsaFixturesPath, "credit-parity.nvd.json"), nvdSnapshot); - - File.WriteAllText(Path.Combine(nvdFixturesPath, "credit-parity.ghsa.json"), ghsaSnapshot); - File.WriteAllText(Path.Combine(nvdFixturesPath, "credit-parity.osv.json"), osvSnapshot); - File.WriteAllText(Path.Combine(nvdFixturesPath, "credit-parity.nvd.json"), nvdSnapshot); - - Console.WriteLine($"[FixtureUpdater] Updated credit parity fixtures under {ghsaFixturesPath} and {nvdFixturesPath}"); -} +return await FixtureUpdaterApp.RunAsync(args); diff --git a/src/Tools/LanguageAnalyzerSmoke/InternalsVisibleTo.cs b/src/Tools/LanguageAnalyzerSmoke/InternalsVisibleTo.cs new file mode 100644 index 000000000..e4c3e64bc --- /dev/null +++ b/src/Tools/LanguageAnalyzerSmoke/InternalsVisibleTo.cs @@ -0,0 +1,3 @@ +using System.Runtime.CompilerServices; + +[assembly: InternalsVisibleTo("LanguageAnalyzerSmoke.Tests")] diff --git a/src/Tools/LanguageAnalyzerSmoke/LanguageAnalyzerSmoke.csproj b/src/Tools/LanguageAnalyzerSmoke/LanguageAnalyzerSmoke.csproj index ac7d454b5..c73a8c720 100644 --- a/src/Tools/LanguageAnalyzerSmoke/LanguageAnalyzerSmoke.csproj +++ b/src/Tools/LanguageAnalyzerSmoke/LanguageAnalyzerSmoke.csproj @@ -10,6 +10,7 @@ + diff --git a/src/Tools/LanguageAnalyzerSmoke/LanguageAnalyzerSmokeApp.cs b/src/Tools/LanguageAnalyzerSmoke/LanguageAnalyzerSmokeApp.cs new file mode 100644 index 000000000..e4e8738c2 --- /dev/null +++ b/src/Tools/LanguageAnalyzerSmoke/LanguageAnalyzerSmokeApp.cs @@ -0,0 +1,113 @@ +using System.CommandLine; + +namespace StellaOps.Tools.LanguageAnalyzerSmoke; + +public static class LanguageAnalyzerSmokeApp +{ + private static readonly DateTimeOffset DefaultFixedTime = new(2025, 1, 1, 0, 0, 0, TimeSpan.Zero); + + public static async Task RunAsync(string[] args) + { + var repoRootOption = new Option("--repo-root") + { + Description = "Repository root (defaults to nearest folder containing src/StellaOps.sln)." + }; + + var analyzerOption = new Option("--analyzer") + { + Description = "Analyzer to exercise (python, rust).", + DefaultValueFactory = _ => "python" + }; + + var pluginDirectoryOption = new Option("--plugin-directory") + { + Description = "Analyzer plug-in directory under plugins/scanner/analyzers/lang." + }; + + var fixturePathOption = new Option("--fixture-path") + { + Description = "Relative path to fixtures root." + }; + + var allowGoldenDriftOption = new Option("--allow-golden-drift") + { + Description = "Allow golden snapshot drift without failing the run." + }; + + var fixedTimeOption = new Option("--fixed-time") + { + Description = "Fixed UTC time used by analyzers for deterministic output.", + DefaultValueFactory = _ => DefaultFixedTime + }; + + var useSystemTimeOption = new Option("--use-system-time") + { + Description = "Use system clock instead of fixed time." + }; + + var timeoutSecondsOption = new Option("--timeout-seconds") + { + Description = "Timeout per scenario in seconds (0 disables timeout).", + DefaultValueFactory = _ => 120 + }; + + var command = new RootCommand("Language analyzer smoke harness"); + command.Add(repoRootOption); + command.Add(analyzerOption); + command.Add(pluginDirectoryOption); + command.Add(fixturePathOption); + command.Add(allowGoldenDriftOption); + command.Add(fixedTimeOption); + command.Add(useSystemTimeOption); + command.Add(timeoutSecondsOption); + + command.SetAction(async (parseResult, cancellationToken) => + { + var repoRoot = parseResult.GetValue(repoRootOption); + var analyzer = parseResult.GetValue(analyzerOption) ?? "python"; + var pluginDirectory = parseResult.GetValue(pluginDirectoryOption); + var fixturePath = parseResult.GetValue(fixturePathOption); + var allowGoldenDrift = parseResult.GetValue(allowGoldenDriftOption); + var fixedTime = parseResult.GetValue(fixedTimeOption); + var useSystemTime = parseResult.GetValue(useSystemTimeOption); + var timeoutSeconds = parseResult.GetValue(timeoutSecondsOption); + + var resolvedRepoRoot = RepoRootLocator.TryResolve(repoRoot?.FullName); + if (resolvedRepoRoot is null) + { + Console.Error.WriteLine("[FAIL] Unable to resolve repo root. Provide --repo-root explicitly."); + return 2; + } + + var options = SmokeOptions.Resolve( + repoRoot: resolvedRepoRoot, + analyzerId: analyzer, + pluginDirectoryName: pluginDirectory, + fixtureRelativePath: fixturePath, + allowGoldenDrift: allowGoldenDrift, + fixedTime: fixedTime, + useSystemTime: useSystemTime, + timeoutSeconds: timeoutSeconds); + + var runner = new LanguageAnalyzerSmokeRunner(Console.WriteLine, Console.Error.WriteLine); + try + { + var profile = await runner.RunAsync(options, cancellationToken).ConfigureAwait(false); + Console.WriteLine($"[OK] {profile.DisplayName} analyzer smoke checks passed"); + return 0; + } + catch (OperationCanceledException ex) + { + Console.Error.WriteLine($"[FAIL] Smoke run canceled: {ex.Message}"); + return 1; + } + catch (Exception ex) + { + Console.Error.WriteLine($"[FAIL] {ex.Message}"); + return 1; + } + }); + + return await command.Parse(args).InvokeAsync().ConfigureAwait(false); + } +} diff --git a/src/Tools/LanguageAnalyzerSmoke/LanguageAnalyzerSmokeRunner.cs b/src/Tools/LanguageAnalyzerSmoke/LanguageAnalyzerSmokeRunner.cs new file mode 100644 index 000000000..0f0e839fd --- /dev/null +++ b/src/Tools/LanguageAnalyzerSmoke/LanguageAnalyzerSmokeRunner.cs @@ -0,0 +1,450 @@ +using System.Collections.Immutable; +using System.Diagnostics; +using System.Security.Cryptography; +using System.Text; +using System.Text.Json; +using System.Text.Json.Serialization; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging.Abstractions; +using StellaOps.Scanner.Analyzers.Lang; +using StellaOps.Scanner.Analyzers.Lang.Plugin; +using StellaOps.Scanner.Core.Security; + +namespace StellaOps.Tools.LanguageAnalyzerSmoke; + +public sealed record SmokeScenario(string Name, string[] UsageHintRelatives) +{ + public IReadOnlyList ResolveUsageHints(string scenarioRoot) + => UsageHintRelatives.Select(relative => Path.GetFullPath(Path.Combine(scenarioRoot, relative))).ToArray(); +} + +public sealed record AnalyzerProfile( + string DisplayName, + string AnalyzerId, + string PluginDirectory, + string FixtureRelativePath, + string ExpectedPluginId, + string ExpectedEntryPointType, + IReadOnlyList RequiredCapabilities, + SmokeScenario[] Scenarios); + +public static class AnalyzerProfileCatalog +{ + private static readonly SmokeScenario[] PythonScenarios = + [ + new("simple-venv", new[] { Path.Combine("bin", "simple-tool") }), + new("pip-cache", new[] { Path.Combine("lib", "python3.11", "site-packages", "cache_pkg-1.2.3.data", "scripts", "cache-tool") }), + new("layered-editable", new[] { Path.Combine("layer1", "usr", "bin", "layered-cli") }), + ]; + + private static readonly SmokeScenario[] RustScenarios = + [ + new("simple", new[] { Path.Combine("usr", "local", "bin", "my_app") }), + new("heuristics", new[] { Path.Combine("usr", "local", "bin", "heuristic_app") }), + new("fallback", new[] { Path.Combine("usr", "local", "bin", "opaque_bin") }), + ]; + + public static readonly IReadOnlyDictionary Profiles = + new Dictionary(StringComparer.OrdinalIgnoreCase) + { + ["python"] = new AnalyzerProfile( + DisplayName: "Python", + AnalyzerId: "python", + PluginDirectory: "StellaOps.Scanner.Analyzers.Lang.Python", + FixtureRelativePath: Path.Combine("src", "Scanner", "__Tests", "StellaOps.Scanner.Analyzers.Lang.Python.Tests", "Fixtures", "lang", "python"), + ExpectedPluginId: "stellaops.analyzer.lang.python", + ExpectedEntryPointType: "StellaOps.Scanner.Analyzers.Lang.Python.PythonAnalyzerPlugin", + RequiredCapabilities: new[] { "python" }, + Scenarios: PythonScenarios), + ["rust"] = new AnalyzerProfile( + DisplayName: "Rust", + AnalyzerId: "rust", + PluginDirectory: "StellaOps.Scanner.Analyzers.Lang.Rust", + FixtureRelativePath: Path.Combine("src", "Scanner", "__Tests", "StellaOps.Scanner.Analyzers.Lang.Tests", "Fixtures", "lang", "rust"), + ExpectedPluginId: "stellaops.analyzer.lang.rust", + ExpectedEntryPointType: "StellaOps.Scanner.Analyzers.Lang.Rust.RustAnalyzerPlugin", + RequiredCapabilities: new[] { "rust", "cargo" }, + Scenarios: RustScenarios), + }; + + public static AnalyzerProfile GetProfile(string analyzerId) + { + if (!Profiles.TryGetValue(analyzerId, out var profile)) + { + throw new ArgumentException($"Unsupported analyzer '{analyzerId}'.", nameof(analyzerId)); + } + + return profile; + } +} + +public sealed record SmokeOptions( + string RepoRoot, + string AnalyzerId, + string PluginDirectoryName, + string FixtureRelativePath, + bool AllowGoldenDrift, + DateTimeOffset FixedTime, + bool UseSystemTime, + TimeSpan? Timeout) +{ + public static SmokeOptions Resolve( + string repoRoot, + string analyzerId, + string? pluginDirectoryName, + string? fixtureRelativePath, + bool allowGoldenDrift, + DateTimeOffset fixedTime, + bool useSystemTime, + int timeoutSeconds) + { + var profile = AnalyzerProfileCatalog.GetProfile(analyzerId); + var resolvedPluginDirectory = string.IsNullOrWhiteSpace(pluginDirectoryName) + ? profile.PluginDirectory + : pluginDirectoryName; + var resolvedFixturePath = string.IsNullOrWhiteSpace(fixtureRelativePath) + ? profile.FixtureRelativePath + : fixtureRelativePath; + + var timeout = timeoutSeconds <= 0 ? (TimeSpan?)null : TimeSpan.FromSeconds(timeoutSeconds); + + return new SmokeOptions( + RepoRoot: Path.GetFullPath(repoRoot), + AnalyzerId: profile.AnalyzerId, + PluginDirectoryName: resolvedPluginDirectory, + FixtureRelativePath: resolvedFixturePath, + AllowGoldenDrift: allowGoldenDrift, + FixedTime: fixedTime, + UseSystemTime: useSystemTime, + Timeout: timeout); + } +} + +public sealed record PluginManifest +{ + [JsonPropertyName("schemaVersion")] + public string SchemaVersion { get; init; } = string.Empty; + + [JsonPropertyName("id")] + public string Id { get; init; } = string.Empty; + + [JsonPropertyName("displayName")] + public string DisplayName { get; init; } = string.Empty; + + [JsonPropertyName("version")] + public string Version { get; init; } = string.Empty; + + [JsonPropertyName("requiresRestart")] + public bool RequiresRestart { get; init; } + + [JsonPropertyName("entryPoint")] + public PluginEntryPoint EntryPoint { get; init; } = new(); + + [JsonPropertyName("capabilities")] + public IReadOnlyList Capabilities { get; init; } = Array.Empty(); + + [JsonPropertyName("metadata")] + public IReadOnlyDictionary Metadata { get; init; } = ImmutableDictionary.Empty; +} + +public sealed record PluginEntryPoint +{ + [JsonPropertyName("type")] + public string Type { get; init; } = string.Empty; + + [JsonPropertyName("assembly")] + public string Assembly { get; init; } = string.Empty; + + [JsonPropertyName("typeName")] + public string TypeName { get; init; } = string.Empty; +} + +public sealed class LanguageAnalyzerSmokeRunner +{ + private readonly Action _info; + private readonly Action _error; + + public LanguageAnalyzerSmokeRunner(Action? info = null, Action? error = null) + { + _info = info ?? (_ => { }); + _error = error ?? (_ => { }); + } + + public async Task RunAsync(SmokeOptions options, CancellationToken cancellationToken) + { + var profile = AnalyzerProfileCatalog.GetProfile(options.AnalyzerId); + ValidateOptions(options); + + var pluginRoot = Path.Combine(options.RepoRoot, "plugins", "scanner", "analyzers", "lang", options.PluginDirectoryName); + var manifestPath = Path.Combine(pluginRoot, "manifest.json"); + if (!File.Exists(manifestPath)) + { + throw new FileNotFoundException($"Plug-in manifest not found at '{manifestPath}'.", manifestPath); + } + + using var manifestStream = File.OpenRead(manifestPath); + var manifest = JsonSerializer.Deserialize(manifestStream, new JsonSerializerOptions + { + PropertyNameCaseInsensitive = true, + ReadCommentHandling = JsonCommentHandling.Skip + }) ?? throw new InvalidOperationException($"Unable to parse manifest '{manifestPath}'."); + + ValidateManifest(manifest, profile, options.PluginDirectoryName); + + var pluginAssemblyPath = Path.Combine(pluginRoot, manifest.EntryPoint.Assembly); + if (!File.Exists(pluginAssemblyPath)) + { + throw new FileNotFoundException($"Plug-in assembly '{manifest.EntryPoint.Assembly}' not found under '{pluginRoot}'.", pluginAssemblyPath); + } + + var sha256 = ComputeSha256(pluginAssemblyPath); + _info($"-> Plug-in assembly SHA-256: {sha256}"); + + using var serviceProvider = BuildServiceProvider(); + var catalog = new LanguageAnalyzerPluginCatalog(new RestartOnlyPluginGuard(), NullLogger.Instance); + catalog.LoadFromDirectory(pluginRoot, seal: true); + + if (catalog.Plugins.Count == 0) + { + throw new InvalidOperationException($"No analyzer plug-ins were loaded from '{pluginRoot}'."); + } + + var analyzerSet = catalog.CreateAnalyzers(serviceProvider); + if (analyzerSet.Count == 0) + { + throw new InvalidOperationException("Language analyzer plug-ins reported no analyzers."); + } + + var analyzerIds = analyzerSet.Select(analyzer => analyzer.Id).ToArray(); + _info($"-> Loaded analyzers: {string.Join(", ", analyzerIds)}"); + + if (!analyzerIds.Contains(profile.AnalyzerId, StringComparer.OrdinalIgnoreCase)) + { + throw new InvalidOperationException($"{profile.DisplayName} analyzer was not created by the plug-in."); + } + + var fixtureRoot = Path.GetFullPath(Path.Combine(options.RepoRoot, options.FixtureRelativePath)); + if (!Directory.Exists(fixtureRoot)) + { + throw new DirectoryNotFoundException($"Fixture directory '{fixtureRoot}' does not exist."); + } + + var timeProvider = options.UseSystemTime ? TimeProvider.System : new FixedTimeProvider(options.FixedTime); + + foreach (var scenario in profile.Scenarios) + { + await RunScenarioAsync(scenario, fixtureRoot, catalog, serviceProvider, options, timeProvider, cancellationToken).ConfigureAwait(false); + } + + return profile; + } + + internal static void ValidateManifest(PluginManifest manifest, AnalyzerProfile profile, string pluginDirectoryName) + { + if (!string.Equals(manifest.SchemaVersion, "1.0", StringComparison.Ordinal)) + { + throw new InvalidOperationException($"Unexpected manifest schema version '{manifest.SchemaVersion}'."); + } + + if (!manifest.RequiresRestart) + { + throw new InvalidOperationException("Language analyzer plug-in must be marked as restart-only."); + } + + if (!string.Equals(manifest.EntryPoint.Type, "dotnet", StringComparison.OrdinalIgnoreCase)) + { + throw new InvalidOperationException($"Unsupported entry point type '{manifest.EntryPoint.Type}'."); + } + + foreach (var capability in profile.RequiredCapabilities) + { + if (!manifest.Capabilities.Contains(capability, StringComparer.OrdinalIgnoreCase)) + { + throw new InvalidOperationException($"Manifest capabilities do not include required capability '{capability}'."); + } + } + + if (!string.Equals(manifest.EntryPoint.TypeName, profile.ExpectedEntryPointType, StringComparison.Ordinal)) + { + throw new InvalidOperationException($"Unexpected entry point type name '{manifest.EntryPoint.TypeName}'."); + } + + if (!string.Equals(manifest.Id, profile.ExpectedPluginId, StringComparison.OrdinalIgnoreCase)) + { + throw new InvalidOperationException($"Manifest id '{manifest.Id}' does not match expected plug-in id for directory '{pluginDirectoryName}'."); + } + } + + internal static void CompareGoldenSnapshot(string scenarioName, string actualJson, string? goldenNormalized, bool allowGoldenDrift, Action info) + { + if (goldenNormalized is null) + { + return; + } + + if (!string.Equals(actualJson, goldenNormalized, StringComparison.Ordinal)) + { + if (allowGoldenDrift) + { + info($"[WARN] Scenario '{scenarioName}' output deviates from repository golden snapshot."); + return; + } + + throw new InvalidOperationException($"Scenario '{scenarioName}' output deviates from repository golden snapshot."); + } + } + + private async Task RunScenarioAsync( + SmokeScenario scenario, + string fixtureRoot, + ILanguageAnalyzerPluginCatalog catalog, + IServiceProvider services, + SmokeOptions options, + TimeProvider timeProvider, + CancellationToken cancellationToken) + { + var scenarioRoot = Path.Combine(fixtureRoot, scenario.Name); + if (!Directory.Exists(scenarioRoot)) + { + throw new DirectoryNotFoundException($"Scenario '{scenario.Name}' directory missing at '{scenarioRoot}'."); + } + + var goldenPath = Path.Combine(scenarioRoot, "expected.json"); + string? goldenNormalized = null; + if (File.Exists(goldenPath)) + { + goldenNormalized = NormalizeJson(await File.ReadAllTextAsync(goldenPath, cancellationToken).ConfigureAwait(false)); + } + + var usageHints = new LanguageUsageHints(scenario.ResolveUsageHints(scenarioRoot)); + var context = new LanguageAnalyzerContext(scenarioRoot, timeProvider, usageHints, services); + + var coldEngine = new LanguageAnalyzerEngine(catalog.CreateAnalyzers(services)); + var coldStopwatch = Stopwatch.StartNew(); + var coldResult = await RunWithTimeoutAsync(token => coldEngine.AnalyzeAsync(context, token), options.Timeout, cancellationToken).ConfigureAwait(false); + coldStopwatch.Stop(); + + if (coldResult.Components.Count == 0) + { + throw new InvalidOperationException($"Scenario '{scenario.Name}' produced no components during cold run."); + } + + var coldJson = NormalizeJson(coldResult.ToJson(indent: true)); + CompareGoldenSnapshot(scenario.Name, coldJson, goldenNormalized, options.AllowGoldenDrift, _info); + + var warmEngine = new LanguageAnalyzerEngine(catalog.CreateAnalyzers(services)); + var warmStopwatch = Stopwatch.StartNew(); + var warmResult = await RunWithTimeoutAsync(token => warmEngine.AnalyzeAsync(context, token), options.Timeout, cancellationToken).ConfigureAwait(false); + warmStopwatch.Stop(); + + var warmJson = NormalizeJson(warmResult.ToJson(indent: true)); + if (!string.Equals(coldJson, warmJson, StringComparison.Ordinal)) + { + throw new InvalidOperationException($"Scenario '{scenario.Name}' produced different outputs between cold and warm runs."); + } + + EnsureDurationWithinBudget(scenario.Name, coldStopwatch.Elapsed, warmStopwatch.Elapsed); + + _info($"[OK] Scenario '{scenario.Name}' - components {coldResult.Components.Count}, cold {coldStopwatch.Elapsed.TotalMilliseconds:F1} ms, warm {warmStopwatch.Elapsed.TotalMilliseconds:F1} ms"); + } + + private static async Task RunWithTimeoutAsync(Func> action, TimeSpan? timeout, CancellationToken cancellationToken) + { + if (timeout is null) + { + return await action(cancellationToken).ConfigureAwait(false); + } + + using var cts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken); + cts.CancelAfter(timeout.Value); + return await action(cts.Token).ConfigureAwait(false); + } + + private static ServiceProvider BuildServiceProvider() + { + var services = new ServiceCollection(); + services.AddLogging(); + return services.BuildServiceProvider(); + } + + private static void EnsureDurationWithinBudget(string scenarioName, TimeSpan coldDuration, TimeSpan warmDuration) + { + var coldBudget = TimeSpan.FromSeconds(30); + var warmBudget = TimeSpan.FromSeconds(5); + + if (coldDuration > coldBudget) + { + throw new InvalidOperationException($"Scenario '{scenarioName}' cold run exceeded budget ({coldDuration.TotalSeconds:F2}s > {coldBudget.TotalSeconds:F2}s)." ); + } + + if (warmDuration > warmBudget) + { + throw new InvalidOperationException($"Scenario '{scenarioName}' warm run exceeded budget ({warmDuration.TotalSeconds:F2}s > {warmBudget.TotalSeconds:F2}s)." ); + } + } + + private static string NormalizeJson(string json) + => json.Replace("\r\n", "\n", StringComparison.Ordinal).TrimEnd(); + + private static void ValidateOptions(SmokeOptions options) + { + if (!Directory.Exists(options.RepoRoot)) + { + throw new DirectoryNotFoundException($"Repository root '{options.RepoRoot}' does not exist."); + } + } + + private static string ComputeSha256(string path) + { + using var hash = SHA256.Create(); + using var stream = File.OpenRead(path); + var digest = hash.ComputeHash(stream); + var builder = new StringBuilder(digest.Length * 2); + foreach (var b in digest) + { + builder.Append(b.ToString("x2")); + } + return builder.ToString(); + } +} + +internal sealed class FixedTimeProvider : TimeProvider +{ + private readonly DateTimeOffset _fixedTime; + private readonly long _timestamp; + + public FixedTimeProvider(DateTimeOffset fixedTime) + { + _fixedTime = fixedTime; + _timestamp = fixedTime.UtcTicks; + } + + public override DateTimeOffset GetUtcNow() => _fixedTime; + + public override long GetTimestamp() => _timestamp; +} + +internal static class RepoRootLocator +{ + public static string? TryResolve(string? repoRoot) + { + if (!string.IsNullOrWhiteSpace(repoRoot)) + { + return Path.GetFullPath(repoRoot); + } + + var current = new DirectoryInfo(Directory.GetCurrentDirectory()); + while (current is not null) + { + var solutionPath = Path.Combine(current.FullName, "src", "StellaOps.sln"); + if (File.Exists(solutionPath)) + { + return current.FullName; + } + + current = current.Parent; + } + + return null; + } +} diff --git a/src/Tools/LanguageAnalyzerSmoke/Program.cs b/src/Tools/LanguageAnalyzerSmoke/Program.cs index 9238245fb..b47ca847a 100644 --- a/src/Tools/LanguageAnalyzerSmoke/Program.cs +++ b/src/Tools/LanguageAnalyzerSmoke/Program.cs @@ -1,434 +1,3 @@ -using System.Collections.Immutable; -using System.Diagnostics; -using System.Reflection; -using System.Security.Cryptography; -using System.Text; -using System.Text.Json; -using System.Text.Json.Serialization; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Logging.Abstractions; -using StellaOps.Scanner.Analyzers.Lang; -using StellaOps.Scanner.Analyzers.Lang.Plugin; -using StellaOps.Scanner.Core.Security; +using StellaOps.Tools.LanguageAnalyzerSmoke; -internal sealed record SmokeScenario(string Name, string[] UsageHintRelatives) -{ - public IReadOnlyList ResolveUsageHints(string scenarioRoot) - => UsageHintRelatives.Select(relative => Path.GetFullPath(Path.Combine(scenarioRoot, relative))).ToArray(); -} - -internal sealed record AnalyzerProfile( - string DisplayName, - string AnalyzerId, - string PluginDirectory, - string FixtureRelativePath, - string ExpectedPluginId, - string ExpectedEntryPointType, - IReadOnlyList RequiredCapabilities, - SmokeScenario[] Scenarios); - -internal static class AnalyzerProfileCatalog -{ - private static readonly SmokeScenario[] PythonScenarios = - { - new("simple-venv", new[] { Path.Combine("bin", "simple-tool") }), - new("pip-cache", new[] { Path.Combine("lib", "python3.11", "site-packages", "cache_pkg-1.2.3.data", "scripts", "cache-tool") }), - new("layered-editable", new[] { Path.Combine("layer1", "usr", "bin", "layered-cli") }), - }; - - private static readonly SmokeScenario[] RustScenarios = - { - new("simple", new[] { Path.Combine("usr", "local", "bin", "my_app") }), - new("heuristics", new[] { Path.Combine("usr", "local", "bin", "heuristic_app") }), - new("fallback", new[] { Path.Combine("usr", "local", "bin", "opaque_bin") }), - }; - - public static readonly IReadOnlyDictionary Profiles = - new Dictionary(StringComparer.OrdinalIgnoreCase) - { - ["python"] = new AnalyzerProfile( - DisplayName: "Python", - AnalyzerId: "python", - PluginDirectory: "StellaOps.Scanner.Analyzers.Lang.Python", - FixtureRelativePath: Path.Combine("src", "Scanner", "__Tests", "StellaOps.Scanner.Analyzers.Lang.Python.Tests", "Fixtures", "lang", "python"), - ExpectedPluginId: "stellaops.analyzer.lang.python", - ExpectedEntryPointType: "StellaOps.Scanner.Analyzers.Lang.Python.PythonAnalyzerPlugin", - RequiredCapabilities: new[] { "python" }, - Scenarios: PythonScenarios), - ["rust"] = new AnalyzerProfile( - DisplayName: "Rust", - AnalyzerId: "rust", - PluginDirectory: "StellaOps.Scanner.Analyzers.Lang.Rust", - FixtureRelativePath: Path.Combine("src", "Scanner", "__Tests", "StellaOps.Scanner.Analyzers.Lang.Tests", "Fixtures", "lang", "rust"), - ExpectedPluginId: "stellaops.analyzer.lang.rust", - ExpectedEntryPointType: "StellaOps.Scanner.Analyzers.Lang.Rust.RustAnalyzerPlugin", - RequiredCapabilities: new[] { "rust", "cargo" }, - Scenarios: RustScenarios), - }; -} - -internal sealed class SmokeOptions -{ - public string RepoRoot { get; set; } = Directory.GetCurrentDirectory(); - public string AnalyzerId { get; set; } = "python"; - public string PluginDirectoryName { get; set; } = "StellaOps.Scanner.Analyzers.Lang.Python"; - public string FixtureRelativePath { get; set; } = Path.Combine("src", "Scanner", "__Tests", "StellaOps.Scanner.Analyzers.Lang.Python.Tests", "Fixtures", "lang", "python"); - public bool PluginDirectoryExplicit { get; private set; } - public bool FixturePathExplicit { get; private set; } - - public static SmokeOptions Parse(string[] args) - { - var options = new SmokeOptions(); - - for (var index = 0; index < args.Length; index++) - { - var current = args[index]; - switch (current) - { - case "--repo-root": - case "-r": - options.RepoRoot = RequireValue(args, ref index, current); - break; - case "--plugin-directory": - case "-p": - options.PluginDirectoryName = RequireValue(args, ref index, current); - options.PluginDirectoryExplicit = true; - break; - case "--fixture-path": - case "-f": - options.FixtureRelativePath = RequireValue(args, ref index, current); - options.FixturePathExplicit = true; - break; - case "--analyzer": - case "-a": - options.AnalyzerId = RequireValue(args, ref index, current); - break; - case "--help": - case "-h": - PrintUsage(); - Environment.Exit(0); - break; - default: - throw new ArgumentException($"Unknown argument '{current}'. Use --help for usage."); - } - } - - options.RepoRoot = Path.GetFullPath(options.RepoRoot); - - if (!AnalyzerProfileCatalog.Profiles.TryGetValue(options.AnalyzerId, out var profile)) - { - throw new ArgumentException($"Unsupported analyzer '{options.AnalyzerId}'."); - } - - if (!options.PluginDirectoryExplicit) - { - options.PluginDirectoryName = profile.PluginDirectory; - } - - if (!options.FixturePathExplicit) - { - options.FixtureRelativePath = profile.FixtureRelativePath; - } - - return options; - } - - private static string RequireValue(string[] args, ref int index, string switchName) - { - if (index + 1 >= args.Length) - { - throw new ArgumentException($"Missing value for '{switchName}'."); - } - - index++; - var value = args[index]; - if (string.IsNullOrWhiteSpace(value)) - { - throw new ArgumentException($"Value for '{switchName}' cannot be empty."); - } - - return value; - } - - private static void PrintUsage() - { - Console.WriteLine("Language Analyzer Smoke Harness"); - Console.WriteLine("Usage: dotnet run --project src/Tools/LanguageAnalyzerSmoke -- [options]"); - Console.WriteLine(); - Console.WriteLine("Options:"); - Console.WriteLine(" -a, --analyzer Analyzer to exercise (python, rust). Defaults to python."); - Console.WriteLine(" -r, --repo-root Repository root (defaults to current working directory)"); - Console.WriteLine(" -p, --plugin-directory Analyzer plug-in directory under plugins/scanner/analyzers/lang (defaults to StellaOps.Scanner.Analyzers.Lang.Python)"); - Console.WriteLine(" -f, --fixture-path Relative path to fixtures root (defaults to src/Scanner/__Tests/StellaOps.Scanner.Analyzers.Lang.Python.Tests/Fixtures/lang/python)"); - Console.WriteLine(" -h, --help Show usage information"); - } -} - -internal sealed record PluginManifest -{ - [JsonPropertyName("schemaVersion")] - public string SchemaVersion { get; init; } = string.Empty; - - [JsonPropertyName("id")] - public string Id { get; init; } = string.Empty; - - [JsonPropertyName("displayName")] - public string DisplayName { get; init; } = string.Empty; - - [JsonPropertyName("version")] - public string Version { get; init; } = string.Empty; - - [JsonPropertyName("requiresRestart")] - public bool RequiresRestart { get; init; } - - [JsonPropertyName("entryPoint")] - public PluginEntryPoint EntryPoint { get; init; } = new(); - - [JsonPropertyName("capabilities")] - public IReadOnlyList Capabilities { get; init; } = Array.Empty(); - - [JsonPropertyName("metadata")] - public IReadOnlyDictionary Metadata { get; init; } = ImmutableDictionary.Empty; -} - -internal sealed record PluginEntryPoint -{ - [JsonPropertyName("type")] - public string Type { get; init; } = string.Empty; - - [JsonPropertyName("assembly")] - public string Assembly { get; init; } = string.Empty; - - [JsonPropertyName("typeName")] - public string TypeName { get; init; } = string.Empty; -} - -file static class Program -{ - private static readonly SmokeScenario[] PythonScenarios = - { - new("simple-venv", new[] { Path.Combine("bin", "simple-tool") }), - new("pip-cache", new[] { Path.Combine("lib", "python3.11", "site-packages", "cache_pkg-1.2.3.data", "scripts", "cache-tool") }), - new("layered-editable", new[] { Path.Combine("layer1", "usr", "bin", "layered-cli") }) - }; - - public static async Task Main(string[] args) - { - try - { - var options = SmokeOptions.Parse(args); - var profile = await RunAsync(options).ConfigureAwait(false); - Console.WriteLine($"✅ {profile.DisplayName} analyzer smoke checks passed"); - return 0; - } - catch (Exception ex) - { - Console.Error.WriteLine($"❌ {ex.Message}"); - return 1; - } - } - - private static async Task RunAsync(SmokeOptions options) - { - if (!AnalyzerProfileCatalog.Profiles.TryGetValue(options.AnalyzerId, out var profile)) - { - throw new ArgumentException($"Analyzer '{options.AnalyzerId}' is not supported."); - } - - ValidateOptions(options); - - var pluginRoot = Path.Combine(options.RepoRoot, "plugins", "scanner", "analyzers", "lang", options.PluginDirectoryName); - var manifestPath = Path.Combine(pluginRoot, "manifest.json"); - if (!File.Exists(manifestPath)) - { - throw new FileNotFoundException($"Plug-in manifest not found at '{manifestPath}'.", manifestPath); - } - - using var manifestStream = File.OpenRead(manifestPath); - var manifest = JsonSerializer.Deserialize(manifestStream, new JsonSerializerOptions - { - PropertyNameCaseInsensitive = true, - ReadCommentHandling = JsonCommentHandling.Skip - }) ?? throw new InvalidOperationException($"Unable to parse manifest '{manifestPath}'."); - - ValidateManifest(manifest, profile, options.PluginDirectoryName); - - var pluginAssemblyPath = Path.Combine(pluginRoot, manifest.EntryPoint.Assembly); - if (!File.Exists(pluginAssemblyPath)) - { - throw new FileNotFoundException($"Plug-in assembly '{manifest.EntryPoint.Assembly}' not found under '{pluginRoot}'.", pluginAssemblyPath); - } - - var sha256 = ComputeSha256(pluginAssemblyPath); - Console.WriteLine($"→ Plug-in assembly SHA-256: {sha256}"); - - using var serviceProvider = BuildServiceProvider(); - var catalog = new LanguageAnalyzerPluginCatalog(new RestartOnlyPluginGuard(), NullLogger.Instance); - catalog.LoadFromDirectory(pluginRoot, seal: true); - - if (catalog.Plugins.Count == 0) - { - throw new InvalidOperationException($"No analyzer plug-ins were loaded from '{pluginRoot}'."); - } - - var analyzerSet = catalog.CreateAnalyzers(serviceProvider); - if (analyzerSet.Count == 0) - { - throw new InvalidOperationException("Language analyzer plug-ins reported no analyzers."); - } - - var analyzerIds = analyzerSet.Select(analyzer => analyzer.Id).ToArray(); - Console.WriteLine($"→ Loaded analyzers: {string.Join(", ", analyzerIds)}"); - - if (!analyzerIds.Contains(profile.AnalyzerId, StringComparer.OrdinalIgnoreCase)) - { - throw new InvalidOperationException($"{profile.DisplayName} analyzer was not created by the plug-in."); - } - - var fixtureRoot = Path.GetFullPath(Path.Combine(options.RepoRoot, options.FixtureRelativePath)); - if (!Directory.Exists(fixtureRoot)) - { - throw new DirectoryNotFoundException($"Fixture directory '{fixtureRoot}' does not exist."); - } - - foreach (var scenario in profile.Scenarios) - { - await RunScenarioAsync(scenario, fixtureRoot, catalog, serviceProvider).ConfigureAwait(false); - } - - return profile; - } - - private static ServiceProvider BuildServiceProvider() - { - var services = new ServiceCollection(); - services.AddLogging(); - return services.BuildServiceProvider(); - } - - private static async Task RunScenarioAsync(SmokeScenario scenario, string fixtureRoot, ILanguageAnalyzerPluginCatalog catalog, IServiceProvider services) - { - var scenarioRoot = Path.Combine(fixtureRoot, scenario.Name); - if (!Directory.Exists(scenarioRoot)) - { - throw new DirectoryNotFoundException($"Scenario '{scenario.Name}' directory missing at '{scenarioRoot}'."); - } - - var goldenPath = Path.Combine(scenarioRoot, "expected.json"); - string? goldenNormalized = null; - if (File.Exists(goldenPath)) - { - goldenNormalized = NormalizeJson(await File.ReadAllTextAsync(goldenPath).ConfigureAwait(false)); - } - - var usageHints = new LanguageUsageHints(scenario.ResolveUsageHints(scenarioRoot)); - var context = new LanguageAnalyzerContext(scenarioRoot, TimeProvider.System, usageHints, services); - - var coldEngine = new LanguageAnalyzerEngine(catalog.CreateAnalyzers(services)); - var coldStopwatch = Stopwatch.StartNew(); - var coldResult = await coldEngine.AnalyzeAsync(context, CancellationToken.None).ConfigureAwait(false); - coldStopwatch.Stop(); - - if (coldResult.Components.Count == 0) - { - throw new InvalidOperationException($"Scenario '{scenario.Name}' produced no components during cold run."); - } - - var coldJson = NormalizeJson(coldResult.ToJson(indent: true)); - if (goldenNormalized is string expected && !string.Equals(coldJson, expected, StringComparison.Ordinal)) - { - Console.WriteLine($"⚠️ Scenario '{scenario.Name}' output deviates from repository golden snapshot."); - } - - var warmEngine = new LanguageAnalyzerEngine(catalog.CreateAnalyzers(services)); - var warmStopwatch = Stopwatch.StartNew(); - var warmResult = await warmEngine.AnalyzeAsync(context, CancellationToken.None).ConfigureAwait(false); - warmStopwatch.Stop(); - - var warmJson = NormalizeJson(warmResult.ToJson(indent: true)); - if (!string.Equals(coldJson, warmJson, StringComparison.Ordinal)) - { - throw new InvalidOperationException($"Scenario '{scenario.Name}' produced different outputs between cold and warm runs."); - } - - EnsureDurationWithinBudget(scenario.Name, coldStopwatch.Elapsed, warmStopwatch.Elapsed); - - Console.WriteLine($"✓ Scenario '{scenario.Name}' — components {coldResult.Components.Count}, cold {coldStopwatch.Elapsed.TotalMilliseconds:F1} ms, warm {warmStopwatch.Elapsed.TotalMilliseconds:F1} ms"); - } - - private static void EnsureDurationWithinBudget(string scenarioName, TimeSpan coldDuration, TimeSpan warmDuration) - { - var coldBudget = TimeSpan.FromSeconds(30); - var warmBudget = TimeSpan.FromSeconds(5); - - if (coldDuration > coldBudget) - { - throw new InvalidOperationException($"Scenario '{scenarioName}' cold run exceeded budget ({coldDuration.TotalSeconds:F2}s > {coldBudget.TotalSeconds:F2}s)."); - } - - if (warmDuration > warmBudget) - { - throw new InvalidOperationException($"Scenario '{scenarioName}' warm run exceeded budget ({warmDuration.TotalSeconds:F2}s > {warmBudget.TotalSeconds:F2}s)."); - } - } - - private static string NormalizeJson(string json) - => json.Replace("\r\n", "\n", StringComparison.Ordinal).TrimEnd(); - - private static void ValidateOptions(SmokeOptions options) - { - if (!Directory.Exists(options.RepoRoot)) - { - throw new DirectoryNotFoundException($"Repository root '{options.RepoRoot}' does not exist."); - } - } - - private static void ValidateManifest(PluginManifest manifest, AnalyzerProfile profile, string pluginDirectoryName) - { - if (!string.Equals(manifest.SchemaVersion, "1.0", StringComparison.Ordinal)) - { - throw new InvalidOperationException($"Unexpected manifest schema version '{manifest.SchemaVersion}'."); - } - - if (!manifest.RequiresRestart) - { - throw new InvalidOperationException("Language analyzer plug-in must be marked as restart-only."); - } - - if (!string.Equals(manifest.EntryPoint.Type, "dotnet", StringComparison.OrdinalIgnoreCase)) - { - throw new InvalidOperationException($"Unsupported entry point type '{manifest.EntryPoint.Type}'."); - } - - foreach (var capability in profile.RequiredCapabilities) - { - if (!manifest.Capabilities.Contains(capability, StringComparer.OrdinalIgnoreCase)) - { - throw new InvalidOperationException($"Manifest capabilities do not include required capability '{capability}'."); - } - } - - if (!string.Equals(manifest.EntryPoint.TypeName, profile.ExpectedEntryPointType, StringComparison.Ordinal)) - { - throw new InvalidOperationException($"Unexpected entry point type name '{manifest.EntryPoint.TypeName}'."); - } - - if (!string.Equals(manifest.Id, profile.ExpectedPluginId, StringComparison.OrdinalIgnoreCase)) - { - throw new InvalidOperationException($"Manifest id '{manifest.Id}' does not match expected plug-in id for directory '{pluginDirectoryName}'."); - } - } - - private static string ComputeSha256(string path) - { - using var hash = SHA256.Create(); - using var stream = File.OpenRead(path); - var digest = hash.ComputeHash(stream); - var builder = new StringBuilder(digest.Length * 2); - foreach (var b in digest) - { - builder.Append(b.ToString("x2")); - } - return builder.ToString(); - } -} +return await LanguageAnalyzerSmokeApp.RunAsync(args); diff --git a/src/Tools/NotifySmokeCheck/InternalsVisibleTo.cs b/src/Tools/NotifySmokeCheck/InternalsVisibleTo.cs new file mode 100644 index 000000000..b49791ad0 --- /dev/null +++ b/src/Tools/NotifySmokeCheck/InternalsVisibleTo.cs @@ -0,0 +1,3 @@ +using System.Runtime.CompilerServices; + +[assembly: InternalsVisibleTo("NotifySmokeCheck.Tests")] diff --git a/src/Tools/NotifySmokeCheck/NotifySmokeCheckApp.cs b/src/Tools/NotifySmokeCheck/NotifySmokeCheckApp.cs new file mode 100644 index 000000000..54943675c --- /dev/null +++ b/src/Tools/NotifySmokeCheck/NotifySmokeCheckApp.cs @@ -0,0 +1,21 @@ +namespace StellaOps.Tools.NotifySmokeCheck; + +public static class NotifySmokeCheckApp +{ + public static async Task RunAsync(string[] args) + { + try + { + var options = NotifySmokeOptions.FromEnvironment(Environment.GetEnvironmentVariable); + var runner = new NotifySmokeCheckRunner(options, Console.WriteLine, Console.Error.WriteLine); + await runner.RunAsync(CancellationToken.None).ConfigureAwait(false); + Console.WriteLine("[OK] Notify smoke validation completed successfully."); + return 0; + } + catch (Exception ex) + { + Console.Error.WriteLine($"[FAIL] {ex.Message}"); + return 1; + } + } +} diff --git a/src/Tools/NotifySmokeCheck/NotifySmokeCheckRunner.cs b/src/Tools/NotifySmokeCheck/NotifySmokeCheckRunner.cs new file mode 100644 index 000000000..c0bd65f37 --- /dev/null +++ b/src/Tools/NotifySmokeCheck/NotifySmokeCheckRunner.cs @@ -0,0 +1,482 @@ +using System.Globalization; +using System.Net; +using System.Net.Http.Headers; +using System.Text.Json; +using StackExchange.Redis; + +namespace StellaOps.Tools.NotifySmokeCheck; + +public sealed record NotifyDeliveryOptions( + Uri BaseUri, + string Token, + string Tenant, + string TenantHeader, + TimeSpan Timeout, + int Limit); + +public sealed record NotifySmokeOptions( + string RedisDsn, + string RedisStream, + IReadOnlyList ExpectedKinds, + TimeSpan Lookback, + int StreamPageSize, + int StreamMaxEntries, + int RetryAttempts, + TimeSpan RetryDelay, + NotifyDeliveryOptions Delivery, + TimeProvider TimeProvider) +{ + public static NotifySmokeOptions FromEnvironment(Func getEnv) + { + string RequireEnv(string name) + { + var value = getEnv(name); + if (string.IsNullOrWhiteSpace(value)) + { + throw new InvalidOperationException($"Environment variable '{name}' is required for Notify smoke validation."); + } + + return value; + } + + var redisDsn = RequireEnv("NOTIFY_SMOKE_REDIS_DSN"); + var redisStream = getEnv("NOTIFY_SMOKE_STREAM"); + if (string.IsNullOrWhiteSpace(redisStream)) + { + redisStream = "stella.events"; + } + + var expectedKindsEnv = RequireEnv("NOTIFY_SMOKE_EXPECT_KINDS"); + var expectedKinds = expectedKindsEnv + .Split(',', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries) + .Select(kind => kind.ToLowerInvariant()) + .Distinct(StringComparer.Ordinal) + .ToArray(); + if (expectedKinds.Length == 0) + { + throw new InvalidOperationException("Expected at least one event kind in NOTIFY_SMOKE_EXPECT_KINDS."); + } + + var lookbackMinutesEnv = RequireEnv("NOTIFY_SMOKE_LOOKBACK_MINUTES"); + if (!double.TryParse(lookbackMinutesEnv, NumberStyles.Any, CultureInfo.InvariantCulture, out var lookbackMinutes)) + { + throw new InvalidOperationException("NOTIFY_SMOKE_LOOKBACK_MINUTES must be numeric."); + } + + if (lookbackMinutes <= 0) + { + throw new InvalidOperationException("NOTIFY_SMOKE_LOOKBACK_MINUTES must be greater than zero."); + } + + var streamPageSize = ParseInt(getEnv("NOTIFY_SMOKE_STREAM_PAGE_SIZE"), 500, min: 50); + var streamMaxEntries = ParseInt(getEnv("NOTIFY_SMOKE_STREAM_MAX_ENTRIES"), 2000, min: streamPageSize); + if (streamMaxEntries < streamPageSize) + { + streamMaxEntries = streamPageSize; + } + + var retryAttempts = ParseInt(getEnv("NOTIFY_SMOKE_RETRY_ATTEMPTS"), 3, min: 1, max: 10); + var retryDelayMs = ParseInt(getEnv("NOTIFY_SMOKE_RETRY_DELAY_MS"), 250, min: 50, max: 2000); + + var baseUrlRaw = RequireEnv("NOTIFY_SMOKE_NOTIFY_BASEURL").TrimEnd('/'); + if (!Uri.TryCreate(baseUrlRaw, UriKind.Absolute, out var baseUri)) + { + throw new InvalidOperationException("NOTIFY_SMOKE_NOTIFY_BASEURL must be an absolute URL."); + } + + var deliveryToken = RequireEnv("NOTIFY_SMOKE_NOTIFY_TOKEN"); + var deliveryTenant = RequireEnv("NOTIFY_SMOKE_NOTIFY_TENANT"); + var tenantHeader = getEnv("NOTIFY_SMOKE_NOTIFY_TENANT_HEADER"); + if (string.IsNullOrWhiteSpace(tenantHeader)) + { + tenantHeader = "X-StellaOps-Tenant"; + } + + var timeoutSeconds = ParseInt(getEnv("NOTIFY_SMOKE_NOTIFY_TIMEOUT_SECONDS"), 30, min: 5, max: 120); + var limit = ParseInt(getEnv("NOTIFY_SMOKE_NOTIFY_LIMIT"), 200, min: 50, max: 2000); + + var fixedTimeEnv = getEnv("NOTIFY_SMOKE_FIXED_TIME"); + var timeProvider = ResolveTimeProvider(fixedTimeEnv); + + return new NotifySmokeOptions( + RedisDsn: redisDsn, + RedisStream: redisStream, + ExpectedKinds: expectedKinds, + Lookback: TimeSpan.FromMinutes(lookbackMinutes), + StreamPageSize: streamPageSize, + StreamMaxEntries: streamMaxEntries, + RetryAttempts: retryAttempts, + RetryDelay: TimeSpan.FromMilliseconds(retryDelayMs), + Delivery: new NotifyDeliveryOptions( + BaseUri: baseUri, + Token: deliveryToken, + Tenant: deliveryTenant, + TenantHeader: tenantHeader, + Timeout: TimeSpan.FromSeconds(timeoutSeconds), + Limit: limit), + TimeProvider: timeProvider); + } + + private static int ParseInt(string? value, int fallback, int min = 0, int max = int.MaxValue) + { + if (string.IsNullOrWhiteSpace(value)) + { + return fallback; + } + + if (!int.TryParse(value, NumberStyles.Integer, CultureInfo.InvariantCulture, out var parsed)) + { + return fallback; + } + + if (parsed < min) + { + return min; + } + + return parsed > max ? max : parsed; + } + + private static TimeProvider ResolveTimeProvider(string? fixedTimeEnv) + { + if (string.IsNullOrWhiteSpace(fixedTimeEnv)) + { + return TimeProvider.System; + } + + if (!DateTimeOffset.TryParse(fixedTimeEnv, CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal | DateTimeStyles.AdjustToUniversal, out var fixedTime)) + { + throw new InvalidOperationException("NOTIFY_SMOKE_FIXED_TIME must be an ISO-8601 timestamp."); + } + + return new FixedTimeProvider(fixedTime); + } +} + +public sealed record NotifyDeliveryRecord(string Kind, string? Status); + +public sealed class NotifySmokeCheckRunner +{ + private readonly NotifySmokeOptions _options; + private readonly Action _info; + private readonly Action _error; + + public NotifySmokeCheckRunner(NotifySmokeOptions options, Action? info = null, Action? error = null) + { + _options = options; + _info = info ?? (_ => { }); + _error = error ?? (_ => { }); + } + + public async Task RunAsync(CancellationToken cancellationToken) + { + var now = _options.TimeProvider.GetUtcNow(); + var sinceThreshold = now - _options.Lookback; + + _info($"[INFO] Checking Redis stream '{_options.RedisStream}' for kinds [{string.Join(", ", _options.ExpectedKinds)}] within the last {_options.Lookback.TotalMinutes:F1} minutes."); + + var redisConfig = ConfigurationOptions.Parse(_options.RedisDsn); + redisConfig.AbortOnConnectFail = false; + + await using var redisConnection = await ConnectWithRetriesAsync(redisConfig, cancellationToken).ConfigureAwait(false); + var database = redisConnection.GetDatabase(); + + var recentEntries = await ReadRecentStreamEntriesAsync(database, _options.RedisStream, sinceThreshold, cancellationToken).ConfigureAwait(false); + Ensure(recentEntries.Count > 0, $"No Redis events newer than {sinceThreshold:u} located in stream '{_options.RedisStream}'."); + + var missingKinds = FindMissingKinds(recentEntries, _options.ExpectedKinds); + Ensure(missingKinds.Count == 0, $"Missing expected Redis events for kinds: {string.Join(", ", missingKinds)}"); + + _info("[INFO] Redis event stream contains the expected scanner events."); + + var deliveriesUrl = BuildDeliveriesUrl(_options.Delivery.BaseUri, sinceThreshold, _options.Delivery.Limit); + _info($"[INFO] Querying Notify deliveries via {deliveriesUrl}."); + + using var httpClient = BuildHttpClient(_options.Delivery); + using var response = await GetWithRetriesAsync(httpClient, deliveriesUrl, cancellationToken).ConfigureAwait(false); + + if (!response.IsSuccessStatusCode) + { + var body = await response.Content.ReadAsStringAsync(cancellationToken).ConfigureAwait(false); + throw new InvalidOperationException($"Notify deliveries request failed with {(int)response.StatusCode} {response.ReasonPhrase}: {body}"); + } + + var json = await response.Content.ReadAsStringAsync(cancellationToken).ConfigureAwait(false); + Ensure(!string.IsNullOrWhiteSpace(json), "Notify deliveries response body was empty."); + + var deliveries = ParseDeliveries(json); + Ensure(deliveries.Count > 0, "Notify deliveries response did not return any records."); + + var missingDeliveryKinds = FindMissingDeliveryKinds(deliveries, _options.ExpectedKinds); + Ensure(missingDeliveryKinds.Count == 0, $"Notify deliveries missing successful records for kinds: {string.Join(", ", missingDeliveryKinds)}"); + + _info("[INFO] Notify deliveries include the expected scanner events."); + } + + internal static IReadOnlyList ParseDeliveries(string json) + { + using var document = JsonDocument.Parse(json); + var root = document.RootElement; + + IEnumerable EnumerateDeliveries(JsonElement element) + { + return element.ValueKind switch + { + JsonValueKind.Array => element.EnumerateArray(), + JsonValueKind.Object when element.TryGetProperty("items", out var items) && items.ValueKind == JsonValueKind.Array => items.EnumerateArray(), + _ => throw new InvalidOperationException("Notify deliveries response was not an array or did not contain an 'items' collection.") + }; + } + + var deliveries = new List(); + foreach (var delivery in EnumerateDeliveries(root)) + { + var kind = delivery.TryGetProperty("kind", out var kindProperty) ? kindProperty.GetString() : null; + if (string.IsNullOrWhiteSpace(kind)) + { + continue; + } + + var status = delivery.TryGetProperty("status", out var statusProperty) ? statusProperty.GetString() : null; + deliveries.Add(new NotifyDeliveryRecord(kind, status)); + } + + return deliveries; + } + + internal static IReadOnlyList FindMissingDeliveryKinds(IReadOnlyList deliveries, IReadOnlyList expectedKinds) + { + var missingKinds = new List(); + foreach (var kind in expectedKinds) + { + var found = deliveries.Any(delivery => + string.Equals(delivery.Kind, kind, StringComparison.OrdinalIgnoreCase) && + !string.Equals(delivery.Status, "failed", StringComparison.OrdinalIgnoreCase)); + + if (!found) + { + missingKinds.Add(kind); + } + } + + return missingKinds; + } + + internal static IReadOnlyList FindMissingKinds(IReadOnlyList entries, IReadOnlyList expectedKinds) + { + var missingKinds = new List(); + foreach (var kind in expectedKinds) + { + var match = entries.FirstOrDefault(entry => + { + var entryKind = GetField(entry, "kind"); + return entryKind is not null && string.Equals(entryKind, kind, StringComparison.OrdinalIgnoreCase); + }); + + if (match.Equals(default(StreamEntry))) + { + missingKinds.Add(kind); + } + } + + return missingKinds; + } + + private async Task> ReadRecentStreamEntriesAsync(IDatabase database, string stream, DateTimeOffset sinceThreshold, CancellationToken cancellationToken) + { + var recentEntries = new List(); + var scannedEntries = 0; + RedisValue maxId = "+"; + var reachedThreshold = false; + + while (scannedEntries < _options.StreamMaxEntries && !reachedThreshold) + { + cancellationToken.ThrowIfCancellationRequested(); + + var batchSize = Math.Min(_options.StreamPageSize, _options.StreamMaxEntries - scannedEntries); + var batch = await ReadStreamBatchAsync(database, stream, maxId, batchSize, cancellationToken).ConfigureAwait(false); + if (batch.Length == 0) + { + break; + } + + foreach (var entry in batch) + { + scannedEntries++; + if (TryGetStreamTimestamp(entry, out var entryTimestamp)) + { + if (entryTimestamp >= sinceThreshold) + { + recentEntries.Add(entry); + } + else + { + reachedThreshold = true; + break; + } + } + else + { + _error($"[WARN] Unable to parse stream entry id '{entry.Id}'."); + } + } + + maxId = $"({batch[^1].Id}"; + } + + if (scannedEntries >= _options.StreamMaxEntries && !reachedThreshold) + { + _error($"[WARN] Reached stream scan limit ({_options.StreamMaxEntries}) before lookback threshold {sinceThreshold:u}."); + } + + return recentEntries; + } + + private async Task ReadStreamBatchAsync(IDatabase database, string stream, RedisValue maxId, int batchSize, CancellationToken cancellationToken) + { + for (var attempt = 1; attempt <= _options.RetryAttempts; attempt++) + { + cancellationToken.ThrowIfCancellationRequested(); + + try + { + return await database.StreamRangeAsync(stream, "-", maxId, batchSize, Order.Descending).ConfigureAwait(false); + } + catch (Exception ex) when (attempt < _options.RetryAttempts) + { + _error($"[WARN] Redis stream range attempt {attempt} failed: {ex.Message}"); + await Task.Delay(_options.RetryDelay, cancellationToken).ConfigureAwait(false); + } + } + + return await database.StreamRangeAsync(stream, "-", maxId, batchSize, Order.Descending).ConfigureAwait(false); + } + + internal static bool TryGetStreamTimestamp(StreamEntry entry, out DateTimeOffset timestamp) + { + var id = entry.Id.ToString(); + var dash = id.IndexOf('-', StringComparison.Ordinal); + if (dash <= 0) + { + timestamp = default; + return false; + } + + if (!long.TryParse(id[..dash], NumberStyles.Integer, CultureInfo.InvariantCulture, out var millis)) + { + timestamp = default; + return false; + } + + timestamp = DateTimeOffset.FromUnixTimeMilliseconds(millis); + return true; + } + + private static string? GetField(StreamEntry entry, string fieldName) + { + foreach (var pair in entry.Values) + { + if (string.Equals(pair.Name, fieldName, StringComparison.OrdinalIgnoreCase)) + { + return pair.Value.ToString(); + } + } + + return null; + } + + private async Task ConnectWithRetriesAsync(ConfigurationOptions options, CancellationToken cancellationToken) + { + for (var attempt = 1; attempt <= _options.RetryAttempts; attempt++) + { + cancellationToken.ThrowIfCancellationRequested(); + + try + { + return await ConnectionMultiplexer.ConnectAsync(options).ConfigureAwait(false); + } + catch (Exception ex) when (attempt < _options.RetryAttempts) + { + _error($"[WARN] Redis connection attempt {attempt} failed: {ex.Message}"); + await Task.Delay(_options.RetryDelay, cancellationToken).ConfigureAwait(false); + } + } + + return await ConnectionMultiplexer.ConnectAsync(options).ConfigureAwait(false); + } + + private HttpClient BuildHttpClient(NotifyDeliveryOptions delivery) + { + var httpClient = new HttpClient + { + Timeout = delivery.Timeout, + }; + + httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", delivery.Token); + httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); + httpClient.DefaultRequestHeaders.Add(delivery.TenantHeader, delivery.Tenant); + + return httpClient; + } + + private async Task GetWithRetriesAsync(HttpClient httpClient, Uri url, CancellationToken cancellationToken) + { + for (var attempt = 1; attempt <= _options.RetryAttempts; attempt++) + { + cancellationToken.ThrowIfCancellationRequested(); + + var response = await httpClient.GetAsync(url, cancellationToken).ConfigureAwait(false); + if (!ShouldRetry(response.StatusCode) || attempt == _options.RetryAttempts) + { + return response; + } + + _error($"[WARN] Notify deliveries attempt {attempt} returned {(int)response.StatusCode}. Retrying after {_options.RetryDelay.TotalMilliseconds:F0} ms."); + response.Dispose(); + await Task.Delay(_options.RetryDelay, cancellationToken).ConfigureAwait(false); + } + + return await httpClient.GetAsync(url, cancellationToken).ConfigureAwait(false); + } + + private static bool ShouldRetry(HttpStatusCode statusCode) + => statusCode == HttpStatusCode.RequestTimeout + || statusCode == (HttpStatusCode)429 + || (int)statusCode >= 500; + + private static Uri BuildDeliveriesUrl(Uri baseUri, DateTimeOffset sinceThreshold, int limit) + { + var sinceQuery = Uri.EscapeDataString(sinceThreshold.ToString("O", CultureInfo.InvariantCulture)); + var builder = new UriBuilder(baseUri) + { + Path = "/api/v1/deliveries", + Query = $"since={sinceQuery}&limit={limit}" + }; + + return builder.Uri; + } + + private static void Ensure(bool condition, string message) + { + if (!condition) + { + throw new InvalidOperationException(message); + } + } +} + +internal sealed class FixedTimeProvider : TimeProvider +{ + private readonly DateTimeOffset _fixedTime; + private readonly long _timestamp; + + public FixedTimeProvider(DateTimeOffset fixedTime) + { + _fixedTime = fixedTime; + _timestamp = fixedTime.UtcTicks; + } + + public override DateTimeOffset GetUtcNow() => _fixedTime; + + public override long GetTimestamp() => _timestamp; +} diff --git a/src/Tools/NotifySmokeCheck/Program.cs b/src/Tools/NotifySmokeCheck/Program.cs index 6e04b797d..e409d0a57 100644 --- a/src/Tools/NotifySmokeCheck/Program.cs +++ b/src/Tools/NotifySmokeCheck/Program.cs @@ -1,198 +1,3 @@ -using System.Globalization; -using System.Net.Http.Headers; -using System.Linq; -using System.Text.Json; -using StackExchange.Redis; +using StellaOps.Tools.NotifySmokeCheck; -static string RequireEnv(string name) -{ - var value = Environment.GetEnvironmentVariable(name); - if (string.IsNullOrWhiteSpace(value)) - { - throw new InvalidOperationException($"Environment variable '{name}' is required for Notify smoke validation."); - } - - return value; -} - -static string? GetField(StreamEntry entry, string fieldName) -{ - foreach (var pair in entry.Values) - { - if (string.Equals(pair.Name, fieldName, StringComparison.OrdinalIgnoreCase)) - { - return pair.Value.ToString(); - } - } - - return null; -} - -static void Ensure(bool condition, string message) -{ - if (!condition) - { - throw new InvalidOperationException(message); - } -} - -var redisDsn = RequireEnv("NOTIFY_SMOKE_REDIS_DSN"); -var redisStream = Environment.GetEnvironmentVariable("NOTIFY_SMOKE_STREAM"); -if (string.IsNullOrWhiteSpace(redisStream)) -{ - redisStream = "stella.events"; -} - -var expectedKindsEnv = RequireEnv("NOTIFY_SMOKE_EXPECT_KINDS"); - -var expectedKinds = expectedKindsEnv - .Split(',', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries) - .Select(kind => kind.ToLowerInvariant()) - .Distinct() - .ToArray(); -Ensure(expectedKinds.Length > 0, "Expected at least one event kind in NOTIFY_SMOKE_EXPECT_KINDS."); - -var lookbackMinutesEnv = RequireEnv("NOTIFY_SMOKE_LOOKBACK_MINUTES"); -if (!double.TryParse(lookbackMinutesEnv, NumberStyles.Any, CultureInfo.InvariantCulture, out var lookbackMinutes)) -{ - throw new InvalidOperationException("NOTIFY_SMOKE_LOOKBACK_MINUTES must be numeric."); -} -Ensure(lookbackMinutes > 0, "NOTIFY_SMOKE_LOOKBACK_MINUTES must be greater than zero."); - -var now = DateTimeOffset.UtcNow; -var sinceThreshold = now - TimeSpan.FromMinutes(Math.Max(1, lookbackMinutes)); - -Console.WriteLine($"ℹ️ Checking Redis stream '{redisStream}' for kinds [{string.Join(", ", expectedKinds)}] within the last {lookbackMinutes:F1} minutes."); - -var redisConfig = ConfigurationOptions.Parse(redisDsn); -redisConfig.AbortOnConnectFail = false; - -await using var redisConnection = await ConnectionMultiplexer.ConnectAsync(redisConfig); -var database = redisConnection.GetDatabase(); - -var streamEntries = await database.StreamRangeAsync(redisStream, "-", "+", count: 200); -if (streamEntries.Length > 1) -{ - Array.Reverse(streamEntries); -} -Ensure(streamEntries.Length > 0, $"Redis stream '{redisStream}' is empty."); - -var recentEntries = new List(); -foreach (var entry in streamEntries) -{ - var timestampText = GetField(entry, "ts"); - if (timestampText is null) - { - continue; - } - - if (!DateTimeOffset.TryParse(timestampText, CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal | DateTimeStyles.AdjustToUniversal, out var entryTimestamp)) - { - continue; - } - - if (entryTimestamp >= sinceThreshold) - { - recentEntries.Add(entry); - } -} - -Ensure(recentEntries.Count > 0, $"No Redis events newer than {sinceThreshold:u} located in stream '{redisStream}'."); - -var missingKinds = new List(); -foreach (var kind in expectedKinds) -{ - var match = recentEntries.FirstOrDefault(entry => - { - var entryKind = GetField(entry, "kind")?.ToLowerInvariant(); - return entryKind == kind; - }); - - if (match.Equals(default(StreamEntry))) - { - missingKinds.Add(kind); - } -} - -Ensure(missingKinds.Count == 0, $"Missing expected Redis events for kinds: {string.Join(", ", missingKinds)}"); - -Console.WriteLine("✅ Redis event stream contains the expected scanner events."); - -var notifyBaseUrl = RequireEnv("NOTIFY_SMOKE_NOTIFY_BASEURL").TrimEnd('/'); -var notifyToken = RequireEnv("NOTIFY_SMOKE_NOTIFY_TOKEN"); -var notifyTenant = RequireEnv("NOTIFY_SMOKE_NOTIFY_TENANT"); -var notifyTenantHeader = Environment.GetEnvironmentVariable("NOTIFY_SMOKE_NOTIFY_TENANT_HEADER"); -if (string.IsNullOrWhiteSpace(notifyTenantHeader)) -{ - notifyTenantHeader = "X-StellaOps-Tenant"; -} - -var notifyTimeoutSeconds = 30; -var notifyTimeoutEnv = Environment.GetEnvironmentVariable("NOTIFY_SMOKE_NOTIFY_TIMEOUT_SECONDS"); -if (!string.IsNullOrWhiteSpace(notifyTimeoutEnv) && int.TryParse(notifyTimeoutEnv, NumberStyles.Integer, CultureInfo.InvariantCulture, out var parsedTimeout)) -{ - notifyTimeoutSeconds = Math.Max(5, parsedTimeout); -} - -using var httpClient = new HttpClient -{ - Timeout = TimeSpan.FromSeconds(notifyTimeoutSeconds), -}; - -httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", notifyToken); -httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); -httpClient.DefaultRequestHeaders.Add(notifyTenantHeader, notifyTenant); - -var sinceQuery = Uri.EscapeDataString(sinceThreshold.ToString("O", CultureInfo.InvariantCulture)); -var deliveriesUrl = $"{notifyBaseUrl}/api/v1/deliveries?since={sinceQuery}&limit=200"; - -Console.WriteLine($"ℹ️ Querying Notify deliveries via {deliveriesUrl}."); - -using var response = await httpClient.GetAsync(deliveriesUrl); -if (!response.IsSuccessStatusCode) -{ - var body = await response.Content.ReadAsStringAsync(); - throw new InvalidOperationException($"Notify deliveries request failed with {(int)response.StatusCode} {response.ReasonPhrase}: {body}"); -} - -var json = await response.Content.ReadAsStringAsync(); -if (string.IsNullOrWhiteSpace(json)) -{ - throw new InvalidOperationException("Notify deliveries response body was empty."); -} - -using var document = JsonDocument.Parse(json); -var root = document.RootElement; - -IEnumerable EnumerateDeliveries(JsonElement element) -{ - return element.ValueKind switch - { - JsonValueKind.Array => element.EnumerateArray(), - JsonValueKind.Object when element.TryGetProperty("items", out var items) && items.ValueKind == JsonValueKind.Array => items.EnumerateArray(), - _ => throw new InvalidOperationException("Notify deliveries response was not an array or did not contain an 'items' collection.") - }; -} - -var deliveries = EnumerateDeliveries(root).ToArray(); -Ensure(deliveries.Length > 0, "Notify deliveries response did not return any records."); - -var missingDeliveryKinds = new List(); -foreach (var kind in expectedKinds) -{ - var found = deliveries.Any(delivery => - delivery.TryGetProperty("kind", out var kindProperty) && - kindProperty.GetString()?.Equals(kind, StringComparison.OrdinalIgnoreCase) == true && - delivery.TryGetProperty("status", out var statusProperty) && - !string.Equals(statusProperty.GetString(), "failed", StringComparison.OrdinalIgnoreCase)); - - if (!found) - { - missingDeliveryKinds.Add(kind); - } -} - -Ensure(missingDeliveryKinds.Count == 0, $"Notify deliveries missing successful records for kinds: {string.Join(", ", missingDeliveryKinds)}"); - -Console.WriteLine("✅ Notify deliveries include the expected scanner events."); -Console.WriteLine("🎉 Notify smoke validation completed successfully."); +return await NotifySmokeCheckApp.RunAsync(args); diff --git a/src/Tools/PolicyDslValidator/PolicyDslValidator.csproj b/src/Tools/PolicyDslValidator/PolicyDslValidator.csproj index f61565206..9372dda21 100644 --- a/src/Tools/PolicyDslValidator/PolicyDslValidator.csproj +++ b/src/Tools/PolicyDslValidator/PolicyDslValidator.csproj @@ -8,7 +8,7 @@ - + diff --git a/src/Tools/PolicyDslValidator/Program.cs b/src/Tools/PolicyDslValidator/Program.cs index a1420e6e8..adfb53c8d 100644 --- a/src/Tools/PolicyDslValidator/Program.cs +++ b/src/Tools/PolicyDslValidator/Program.cs @@ -1,56 +1,3 @@ -using StellaOps.Policy; +using StellaOps.Policy.Tools; -if (args.Length == 0) -{ - Console.Error.WriteLine("Usage: policy-dsl-validator [--strict] [--json] [ ...]"); - Console.Error.WriteLine("Example: policy-dsl-validator --strict docs/examples/policies"); - return 64; // EX_USAGE -} - -var inputs = new List(); -var strict = false; -var outputJson = false; - -foreach (var arg in args) -{ - switch (arg) - { - case "--strict": - case "-s": - strict = true; - break; - - case "--json": - case "-j": - outputJson = true; - break; - - case "--help": - case "-h": - case "-?": - Console.WriteLine("Usage: policy-dsl-validator [--strict] [--json] [ ...]"); - Console.WriteLine("Example: policy-dsl-validator --strict docs/examples/policies"); - return 0; - - default: - inputs.Add(arg); - break; - } -} - -if (inputs.Count == 0) -{ - Console.Error.WriteLine("No input files or directories provided."); - return 64; // EX_USAGE -} - -var options = new PolicyValidationCliOptions -{ - Inputs = inputs, - Strict = strict, - OutputJson = outputJson, -}; - -var cli = new PolicyValidationCli(); -var exitCode = await cli.RunAsync(options, CancellationToken.None); -return exitCode; +return await PolicyDslValidatorApp.RunAsync(args); diff --git a/src/Tools/PolicySchemaExporter/PolicySchemaExporter.csproj b/src/Tools/PolicySchemaExporter/PolicySchemaExporter.csproj index b081d60db..af80ad9fd 100644 --- a/src/Tools/PolicySchemaExporter/PolicySchemaExporter.csproj +++ b/src/Tools/PolicySchemaExporter/PolicySchemaExporter.csproj @@ -9,14 +9,7 @@ - - - - - - - - + diff --git a/src/Tools/PolicySchemaExporter/Program.cs b/src/Tools/PolicySchemaExporter/Program.cs index 65a776e31..3f46e0bfd 100644 --- a/src/Tools/PolicySchemaExporter/Program.cs +++ b/src/Tools/PolicySchemaExporter/Program.cs @@ -1,47 +1,3 @@ -using System.Collections.Immutable; -using System.Text.Json; -using System.Text.Json.Serialization; -using NJsonSchema; -using NJsonSchema.Generation; -using Newtonsoft.Json; -using StellaOps.Scheduler.Models; +using StellaOps.Policy.Tools; -var output = args.Length switch -{ - 0 => Path.GetFullPath(Path.Combine(AppContext.BaseDirectory, "..", "..", "..", "docs", "schemas")), - 1 => Path.GetFullPath(args[0]), - _ => throw new ArgumentException("Usage: dotnet run --project src/Tools/PolicySchemaExporter -- [outputDirectory]") -}; - -Directory.CreateDirectory(output); - -var generatorSettings = new NJsonSchema.NewtonsoftJson.Generation.NewtonsoftJsonSchemaGeneratorSettings -{ - SchemaType = SchemaType.JsonSchema, - DefaultReferenceTypeNullHandling = ReferenceTypeNullHandling.NotNull, - SerializerSettings = new JsonSerializerSettings - { - ContractResolver = new Newtonsoft.Json.Serialization.CamelCasePropertyNamesContractResolver(), - NullValueHandling = NullValueHandling.Ignore, - }, -}; - -var generator = new JsonSchemaGenerator(generatorSettings); - -var exports = ImmutableArray.Create( - (FileName: "policy-run-request.schema.json", Type: typeof(PolicyRunRequest)), - (FileName: "policy-run-status.schema.json", Type: typeof(PolicyRunStatus)), - (FileName: "policy-diff-summary.schema.json", Type: typeof(PolicyDiffSummary)), - (FileName: "policy-explain-trace.schema.json", Type: typeof(PolicyExplainTrace)) -); - -foreach (var export in exports) -{ - var schema = generator.Generate(export.Type); - schema.Title = export.Type.Name; - schema.AllowAdditionalProperties = false; - - var outputPath = Path.Combine(output, export.FileName); - await File.WriteAllTextAsync(outputPath, schema.ToJson(Formatting.Indented) + Environment.NewLine); - Console.WriteLine($"Wrote {outputPath}"); -} +return await PolicySchemaExporterApp.RunAsync(args); diff --git a/src/Tools/PolicySimulationSmoke/PolicySimulationSmoke.csproj b/src/Tools/PolicySimulationSmoke/PolicySimulationSmoke.csproj index c52f0216f..9fedd5291 100644 --- a/src/Tools/PolicySimulationSmoke/PolicySimulationSmoke.csproj +++ b/src/Tools/PolicySimulationSmoke/PolicySimulationSmoke.csproj @@ -8,9 +8,7 @@ - - - + diff --git a/src/Tools/PolicySimulationSmoke/Program.cs b/src/Tools/PolicySimulationSmoke/Program.cs index 8c537e63c..25e73626d 100644 --- a/src/Tools/PolicySimulationSmoke/Program.cs +++ b/src/Tools/PolicySimulationSmoke/Program.cs @@ -1,291 +1,3 @@ -using System.Collections.Immutable; -using System.Text.Json; -using Microsoft.Extensions.Logging; -using Microsoft.Extensions.Logging.Abstractions; -using StellaOps.Policy; +using StellaOps.Policy.Tools; -var scenarioRoot = "samples/policy/simulations"; -string? outputDir = null; - -for (var i = 0; i < args.Length; i++) -{ - var arg = args[i]; - switch (arg) - { - case "--scenario-root": - case "-r": - if (i + 1 >= args.Length) - { - Console.Error.WriteLine("Missing value for --scenario-root."); - return 64; - } - scenarioRoot = args[++i]; - break; - case "--output": - case "-o": - if (i + 1 >= args.Length) - { - Console.Error.WriteLine("Missing value for --output."); - return 64; - } - outputDir = args[++i]; - break; - case "--help": - case "-h": - case "-?": - PrintUsage(); - return 0; - default: - Console.Error.WriteLine($"Unknown argument '{arg}'."); - PrintUsage(); - return 64; - } -} - -if (!Directory.Exists(scenarioRoot)) -{ - Console.Error.WriteLine($"Scenario root '{scenarioRoot}' does not exist."); - return 66; -} - -var scenarioFiles = Directory.GetFiles(scenarioRoot, "scenario.json", SearchOption.AllDirectories); -if (scenarioFiles.Length == 0) -{ - Console.Error.WriteLine($"No scenario.json files found under '{scenarioRoot}'."); - return 0; -} - -var loggerFactory = NullLoggerFactory.Instance; -var snapshotStore = new PolicySnapshotStore( - new NullPolicySnapshotRepository(), - new NullPolicyAuditRepository(), - TimeProvider.System, - loggerFactory.CreateLogger()); -var previewService = new PolicyPreviewService(snapshotStore, loggerFactory.CreateLogger()); - -var serializerOptions = new JsonSerializerOptions(JsonSerializerDefaults.Web) -{ - PropertyNameCaseInsensitive = true, - ReadCommentHandling = JsonCommentHandling.Skip, -}; - -var summary = new List(); -var success = true; - -foreach (var scenarioFile in scenarioFiles.OrderBy(static f => f, StringComparer.OrdinalIgnoreCase)) -{ - var scenarioText = await File.ReadAllTextAsync(scenarioFile); - var scenario = JsonSerializer.Deserialize(scenarioText, serializerOptions); - if (scenario is null) - { - Console.Error.WriteLine($"Failed to deserialize scenario '{scenarioFile}'."); - success = false; - continue; - } - - var repoRoot = Directory.GetCurrentDirectory(); - var policyPath = Path.Combine(repoRoot, scenario.PolicyPath); - if (!File.Exists(policyPath)) - { - Console.Error.WriteLine($"Policy file '{scenario.PolicyPath}' referenced by scenario '{scenario.Name}' does not exist."); - success = false; - continue; - } - - var policyContent = await File.ReadAllTextAsync(policyPath); - var policyFormat = PolicySchema.DetectFormat(policyPath); - var findings = scenario.Findings.Select(ToPolicyFinding).ToImmutableArray(); - var baseline = scenario.Baseline?.Select(ToPolicyVerdict).ToImmutableArray() ?? ImmutableArray.Empty; - - var request = new PolicyPreviewRequest( - ImageDigest: $"sha256:simulation-{scenario.Name}", - Findings: findings, - BaselineVerdicts: baseline, - SnapshotOverride: null, - ProposedPolicy: new PolicySnapshotContent( - Content: policyContent, - Format: policyFormat, - Actor: "ci", - Source: "ci/simulation-smoke", - Description: $"CI simulation for scenario '{scenario.Name}'")); - - var response = await previewService.PreviewAsync(request, CancellationToken.None); - var scenarioResult = EvaluateScenario(scenario, response); - summary.Add(scenarioResult); - - if (!scenarioResult.Success) - { - success = false; - } -} - -if (outputDir is not null) -{ - Directory.CreateDirectory(outputDir); - var summaryPath = Path.Combine(outputDir, "policy-simulation-summary.json"); - await File.WriteAllTextAsync(summaryPath, JsonSerializer.Serialize(summary, new JsonSerializerOptions { WriteIndented = true })); -} - -return success ? 0 : 1; - -static void PrintUsage() -{ - Console.WriteLine("Usage: policy-simulation-smoke [--scenario-root ] [--output ]"); - Console.WriteLine("Example: policy-simulation-smoke --scenario-root samples/policy/simulations --output artifacts/policy-simulations"); -} - -static PolicyFinding ToPolicyFinding(ScenarioFinding finding) -{ - var tags = finding.Tags is null ? ImmutableArray.Empty : ImmutableArray.CreateRange(finding.Tags); - var severity = Enum.Parse(finding.Severity, ignoreCase: true); - return new PolicyFinding( - finding.FindingId, - severity, - finding.Environment, - finding.Source, - finding.Vendor, - finding.License, - finding.Image, - finding.Repository, - finding.Package, - finding.Purl, - finding.Cve, - finding.Path, - finding.LayerDigest, - tags); -} - -static PolicyVerdict ToPolicyVerdict(ScenarioBaseline baseline) -{ - var status = Enum.Parse(baseline.Status, ignoreCase: true); - var inputs = baseline.Inputs?.ToImmutableDictionary(StringComparer.OrdinalIgnoreCase) ?? ImmutableDictionary.Empty; - return new PolicyVerdict( - baseline.FindingId, - status, - RuleName: baseline.RuleName, - RuleAction: baseline.RuleAction, - Notes: baseline.Notes, - Score: baseline.Score, - ConfigVersion: baseline.ConfigVersion ?? PolicyScoringConfig.Default.Version, - Inputs: inputs, - QuietedBy: null, - Quiet: false, - UnknownConfidence: null, - ConfidenceBand: null, - UnknownAgeDays: null, - SourceTrust: null, - Reachability: null); -} - -static ScenarioResult EvaluateScenario(PolicySimulationScenario scenario, PolicyPreviewResponse response) -{ - var result = new ScenarioResult(scenario.Name); - if (!response.Success) - { - result.Failures.Add("Preview failed."); - return result with { Success = false, ChangedCount = response.ChangedCount }; - } - - var diffs = response.Diffs.ToDictionary(diff => diff.Projected.FindingId, StringComparer.OrdinalIgnoreCase); - foreach (var expected in scenario.ExpectedDiffs) - { - if (!diffs.TryGetValue(expected.FindingId, out var diff)) - { - result.Failures.Add($"Expected finding '{expected.FindingId}' missing from diff."); - continue; - } - - var projectedStatus = diff.Projected.Status.ToString(); - result.ActualStatuses[expected.FindingId] = projectedStatus; - if (!string.Equals(projectedStatus, expected.Status, StringComparison.OrdinalIgnoreCase)) - { - result.Failures.Add($"Finding '{expected.FindingId}' expected status '{expected.Status}' but was '{projectedStatus}'."); - } - } - - foreach (var diff in diffs.Values) - { - if (!result.ActualStatuses.ContainsKey(diff.Projected.FindingId)) - { - result.ActualStatuses[diff.Projected.FindingId] = diff.Projected.Status.ToString(); - } - } - - var success = result.Failures.Count == 0; - return result with - { - Success = success, - ChangedCount = response.ChangedCount - }; -} - -internal sealed record PolicySimulationScenario -{ - public string Name { get; init; } = "scenario"; - public string PolicyPath { get; init; } = string.Empty; - public List Findings { get; init; } = new(); - public List ExpectedDiffs { get; init; } = new(); - public List? Baseline { get; init; } -} - -internal sealed record ScenarioFinding -{ - public string FindingId { get; init; } = string.Empty; - public string Severity { get; init; } = "Low"; - public string? Environment { get; init; } - public string? Source { get; init; } - public string? Vendor { get; init; } - public string? License { get; init; } - public string? Image { get; init; } - public string? Repository { get; init; } - public string? Package { get; init; } - public string? Purl { get; init; } - public string? Cve { get; init; } - public string? Path { get; init; } - public string? LayerDigest { get; init; } - public string[]? Tags { get; init; } -} - -internal sealed record ScenarioExpectedDiff -{ - public string FindingId { get; init; } = string.Empty; - public string Status { get; init; } = "Pass"; -} - -internal sealed record ScenarioBaseline -{ - public string FindingId { get; init; } = string.Empty; - public string Status { get; init; } = "Pass"; - public string? RuleName { get; init; } - public string? RuleAction { get; init; } - public string? Notes { get; init; } - public double Score { get; init; } - public string? ConfigVersion { get; init; } - public Dictionary? Inputs { get; init; } -} - -internal sealed record ScenarioResult(string ScenarioName) -{ - public bool Success { get; init; } = true; - public int ChangedCount { get; init; } - public List Failures { get; } = new(); - public Dictionary ActualStatuses { get; } = new(StringComparer.OrdinalIgnoreCase); -} - -internal sealed class NullPolicySnapshotRepository : IPolicySnapshotRepository -{ - public Task AddAsync(PolicySnapshot snapshot, CancellationToken cancellationToken = default) => Task.CompletedTask; - - public Task GetLatestAsync(CancellationToken cancellationToken = default) => Task.FromResult(null); - - public Task> ListAsync(int limit, CancellationToken cancellationToken = default) - => Task.FromResult>(Array.Empty()); -} - -internal sealed class NullPolicyAuditRepository : IPolicyAuditRepository -{ - public Task AddAsync(PolicyAuditEntry entry, CancellationToken cancellationToken = default) => Task.CompletedTask; - - public Task> ListAsync(int limit, CancellationToken cancellationToken = default) - => Task.FromResult>(Array.Empty()); -} +return await PolicySimulationSmokeApp.RunAsync(args); diff --git a/src/Tools/RustFsMigrator/InternalsVisibleTo.cs b/src/Tools/RustFsMigrator/InternalsVisibleTo.cs new file mode 100644 index 000000000..8ad342864 --- /dev/null +++ b/src/Tools/RustFsMigrator/InternalsVisibleTo.cs @@ -0,0 +1,3 @@ +using System.Runtime.CompilerServices; + +[assembly: InternalsVisibleTo("RustFsMigrator.Tests")] diff --git a/src/Tools/RustFsMigrator/Program.cs b/src/Tools/RustFsMigrator/Program.cs index bae651e63..483215706 100644 --- a/src/Tools/RustFsMigrator/Program.cs +++ b/src/Tools/RustFsMigrator/Program.cs @@ -1,8 +1,10 @@ +using System.Globalization; +using System.Net; +using System.Net.Http.Headers; using Amazon; using Amazon.Runtime; using Amazon.S3; using Amazon.S3.Model; -using System.Net.Http.Headers; var options = MigrationOptions.Parse(args); if (options is null) @@ -36,6 +38,11 @@ if (!string.IsNullOrWhiteSpace(options.S3Region)) using var s3Client = CreateS3Client(options, s3Config); using var httpClient = CreateRustFsClient(options); +using var cts = options.TimeoutSeconds > 0 + ? new CancellationTokenSource(TimeSpan.FromSeconds(options.TimeoutSeconds)) + : null; +var cancellationToken = cts?.Token ?? CancellationToken.None; + var listRequest = new ListObjectsV2Request { BucketName = options.S3Bucket, @@ -46,69 +53,52 @@ var listRequest = new ListObjectsV2Request var migrated = 0; var skipped = 0; -do +try { - var response = await s3Client.ListObjectsV2Async(listRequest).ConfigureAwait(false); - foreach (var entry in response.S3Objects) + do { - if (entry.Size == 0 && entry.Key.EndsWith('/')) + var response = await ExecuteWithRetriesAsync( + token => s3Client.ListObjectsV2Async(listRequest, token), + "ListObjectsV2", + options, + cancellationToken).ConfigureAwait(false); + + foreach (var entry in response.S3Objects) { - skipped++; - continue; + if (entry.Size == 0 && entry.Key.EndsWith("/", StringComparison.Ordinal)) + { + skipped++; + continue; + } + + Console.WriteLine($"Migrating {entry.Key} ({entry.Size} bytes)..."); + + if (options.DryRun) + { + migrated++; + continue; + } + + try + { + await UploadObjectAsync(s3Client, httpClient, options, entry, cancellationToken).ConfigureAwait(false); + migrated++; + } + catch (Exception ex) when (ex is not OperationCanceledException) + { + Console.Error.WriteLine($"Failed to upload {entry.Key}: {ex.Message}"); + return 2; + } } - Console.WriteLine($"Migrating {entry.Key} ({entry.Size} bytes)..."); - - if (options.DryRun) - { - migrated++; - continue; - } - - using var getResponse = await s3Client.GetObjectAsync(new GetObjectRequest - { - BucketName = options.S3Bucket, - Key = entry.Key, - }).ConfigureAwait(false); - - await using var memory = new MemoryStream(); - await getResponse.ResponseStream.CopyToAsync(memory).ConfigureAwait(false); - memory.Position = 0; - - using var request = new HttpRequestMessage(HttpMethod.Put, BuildRustFsUri(options, entry.Key)) - { - Content = new ByteArrayContent(memory.ToArray()), - }; - request.Content.Headers.ContentType = MediaTypeHeaderValue.Parse("application/octet-stream"); - - if (options.Immutable) - { - request.Headers.TryAddWithoutValidation("X-RustFS-Immutable", "true"); - } - - if (options.RetentionSeconds is { } retainSeconds) - { - request.Headers.TryAddWithoutValidation("X-RustFS-Retain-Seconds", retainSeconds.ToString()); - } - - if (!string.IsNullOrWhiteSpace(options.RustFsApiKeyHeader) && !string.IsNullOrWhiteSpace(options.RustFsApiKey)) - { - request.Headers.TryAddWithoutValidation(options.RustFsApiKeyHeader!, options.RustFsApiKey!); - } - - using var responseMessage = await httpClient.SendAsync(request).ConfigureAwait(false); - if (!responseMessage.IsSuccessStatusCode) - { - var error = await responseMessage.Content.ReadAsStringAsync().ConfigureAwait(false); - Console.Error.WriteLine($"Failed to upload {entry.Key}: {(int)responseMessage.StatusCode} {responseMessage.ReasonPhrase}\n{error}"); - return 2; - } - - migrated++; - } - - listRequest.ContinuationToken = response.NextContinuationToken; -} while (!string.IsNullOrEmpty(listRequest.ContinuationToken)); + listRequest.ContinuationToken = response.NextContinuationToken; + } while (!string.IsNullOrEmpty(listRequest.ContinuationToken)); +} +catch (OperationCanceledException) +{ + Console.Error.WriteLine("Migration canceled."); + return 3; +} Console.WriteLine($"Migration complete. Migrated {migrated} objects. Skipped {skipped} directory markers."); return 0; @@ -140,18 +130,112 @@ static HttpClient CreateRustFsClient(MigrationOptions options) return client; } -static Uri BuildRustFsUri(MigrationOptions options, string key) +static async Task UploadObjectAsync(IAmazonS3 s3Client, HttpClient httpClient, MigrationOptions options, S3Object entry, CancellationToken cancellationToken) { - var normalized = string.Join('/', key - .Split('/', StringSplitOptions.RemoveEmptyEntries) - .Select(Uri.EscapeDataString)); - - var builder = new UriBuilder(options.RustFsEndpoint) + await ExecuteWithRetriesAsync(async token => { - Path = $"/api/v1/buckets/{Uri.EscapeDataString(options.RustFsBucket)}/objects/{normalized}", + using var getResponse = await s3Client.GetObjectAsync(new GetObjectRequest + { + BucketName = options.S3Bucket, + Key = entry.Key, + }, token).ConfigureAwait(false); + + using var request = BuildRustFsRequest(options, entry.Key, getResponse); + using var responseMessage = await httpClient.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, token).ConfigureAwait(false); + if (!responseMessage.IsSuccessStatusCode) + { + var error = await responseMessage.Content.ReadAsStringAsync(token).ConfigureAwait(false); + if (ShouldRetry(responseMessage.StatusCode)) + { + throw new RetryableException($"RustFS upload returned {(int)responseMessage.StatusCode} {responseMessage.ReasonPhrase}: {error}"); + } + + throw new InvalidOperationException($"RustFS upload returned {(int)responseMessage.StatusCode} {responseMessage.ReasonPhrase}: {error}"); + } + + return null!; + }, $"Upload {entry.Key}", options, cancellationToken).ConfigureAwait(false); +} + +static HttpRequestMessage BuildRustFsRequest(MigrationOptions options, string key, GetObjectResponse getResponse) +{ + var request = new HttpRequestMessage(HttpMethod.Put, RustFsMigratorPaths.BuildRustFsUri(options, key)) + { + Content = new StreamContent(getResponse.ResponseStream), }; - return builder.Uri; + request.Content.Headers.ContentType = MediaTypeHeaderValue.Parse("application/octet-stream"); + if (getResponse.Headers.ContentLength > 0) + { + request.Content.Headers.ContentLength = getResponse.Headers.ContentLength; + } + + if (options.Immutable) + { + request.Headers.TryAddWithoutValidation("X-RustFS-Immutable", "true"); + } + + if (options.RetentionSeconds is { } retainSeconds) + { + request.Headers.TryAddWithoutValidation("X-RustFS-Retain-Seconds", retainSeconds.ToString(CultureInfo.InvariantCulture)); + } + + if (!string.IsNullOrWhiteSpace(options.RustFsApiKeyHeader) && !string.IsNullOrWhiteSpace(options.RustFsApiKey)) + { + request.Headers.TryAddWithoutValidation(options.RustFsApiKeyHeader!, options.RustFsApiKey!); + } + + return request; +} + +static async Task ExecuteWithRetriesAsync(Func> action, string operation, MigrationOptions options, CancellationToken cancellationToken) +{ + Exception? last = null; + + for (var attempt = 1; attempt <= options.RetryAttempts; attempt++) + { + cancellationToken.ThrowIfCancellationRequested(); + + try + { + return await action(cancellationToken).ConfigureAwait(false); + } + catch (Exception ex) when (ShouldRetryException(ex) && attempt < options.RetryAttempts) + { + last = ex; + Console.Error.WriteLine($"[WARN] {operation} attempt {attempt} failed: {ex.Message}"); + await Task.Delay(ComputeBackoffDelay(attempt, options.RetryDelayMs), cancellationToken).ConfigureAwait(false); + } + } + + if (last is not null) + { + throw last; + } + + return await action(cancellationToken).ConfigureAwait(false); +} + +static TimeSpan ComputeBackoffDelay(int attempt, int retryDelayMs) +{ + var multiplier = Math.Pow(2, Math.Max(0, attempt - 1)); + var delayMs = Math.Min(retryDelayMs * multiplier, 5000); + return TimeSpan.FromMilliseconds(delayMs); +} + +static bool ShouldRetryException(Exception ex) + => ex is RetryableException or HttpRequestException or AmazonS3Exception or IOException; + +static bool ShouldRetry(HttpStatusCode statusCode) + => statusCode == HttpStatusCode.RequestTimeout + || statusCode == (HttpStatusCode)429 + || (int)statusCode >= 500; + +internal sealed class RetryableException : Exception +{ + public RetryableException(string message) : base(message) + { + } } internal sealed record MigrationOptions @@ -192,6 +276,15 @@ internal sealed record MigrationOptions public bool DryRun { get; init; } = false; + public int RetryAttempts { get; init; } + = 3; + + public int RetryDelayMs { get; init; } + = 250; + + public int TimeoutSeconds { get; init; } + = 0; + public static MigrationOptions? Parse(string[] args) { var builder = new Dictionary(StringComparer.OrdinalIgnoreCase); @@ -202,7 +295,8 @@ internal sealed record MigrationOptions if (key.StartsWith("--", StringComparison.OrdinalIgnoreCase)) { var normalized = key[2..]; - if (string.Equals(normalized, "immutable", StringComparison.OrdinalIgnoreCase) || string.Equals(normalized, "dry-run", StringComparison.OrdinalIgnoreCase)) + if (string.Equals(normalized, "immutable", StringComparison.OrdinalIgnoreCase) || + string.Equals(normalized, "dry-run", StringComparison.OrdinalIgnoreCase)) { builder[normalized] = "true"; continue; @@ -239,7 +333,7 @@ internal sealed record MigrationOptions int? retentionSeconds = null; if (builder.TryGetValue("retain-days", out var retainStr) && !string.IsNullOrWhiteSpace(retainStr)) { - if (double.TryParse(retainStr, out var days) && days > 0) + if (double.TryParse(retainStr, NumberStyles.Float, CultureInfo.InvariantCulture, out var days) && days > 0) { retentionSeconds = (int)Math.Ceiling(days * 24 * 60 * 60); } @@ -250,6 +344,10 @@ internal sealed record MigrationOptions } } + var retryAttempts = ParseIntOption(builder, "retry-attempts", 3, min: 1, max: 10); + var retryDelayMs = ParseIntOption(builder, "retry-delay-ms", 250, min: 50, max: 2000); + var timeoutSeconds = ParseIntOption(builder, "timeout-seconds", 0, min: 0, max: 3600); + return new MigrationOptions { S3Bucket = bucket, @@ -265,6 +363,9 @@ internal sealed record MigrationOptions Immutable = builder.ContainsKey("immutable"), RetentionSeconds = retentionSeconds, DryRun = builder.ContainsKey("dry-run"), + RetryAttempts = retryAttempts, + RetryDelayMs = retryDelayMs, + TimeoutSeconds = timeoutSeconds, }; } @@ -281,6 +382,29 @@ internal sealed record MigrationOptions [--prefix scanner/] \ [--immutable] \ [--retain-days 365] \ + [--retry-attempts 3] \ + [--retry-delay-ms 250] \ + [--timeout-seconds 0] \ [--dry-run]"); } + + private static int ParseIntOption(Dictionary values, string name, int fallback, int min, int max) + { + if (!values.TryGetValue(name, out var raw) || string.IsNullOrWhiteSpace(raw)) + { + return fallback; + } + + if (!int.TryParse(raw, NumberStyles.Integer, CultureInfo.InvariantCulture, out var parsed)) + { + return fallback; + } + + if (parsed < min) + { + return min; + } + + return parsed > max ? max : parsed; + } } diff --git a/src/Tools/RustFsMigrator/RustFsMigratorPaths.cs b/src/Tools/RustFsMigrator/RustFsMigratorPaths.cs new file mode 100644 index 000000000..3150a8e7e --- /dev/null +++ b/src/Tools/RustFsMigrator/RustFsMigratorPaths.cs @@ -0,0 +1,16 @@ +internal static class RustFsMigratorPaths +{ + internal static Uri BuildRustFsUri(MigrationOptions options, string key) + { + var normalized = string.Join('/', key + .Split('/', StringSplitOptions.RemoveEmptyEntries) + .Select(Uri.EscapeDataString)); + + var builder = new UriBuilder(options.RustFsEndpoint) + { + Path = $"/api/v1/buckets/{Uri.EscapeDataString(options.RustFsBucket)}/objects/{normalized}", + }; + + return builder.Uri; + } +} diff --git a/src/Tools/StellaOps.Tools.sln b/src/Tools/StellaOps.Tools.sln index 3461be09e..3366ed434 100644 --- a/src/Tools/StellaOps.Tools.sln +++ b/src/Tools/StellaOps.Tools.sln @@ -1,823 +1,1893 @@ -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 17 -VisualStudioVersion = 17.0.31903.59 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "FixtureUpdater", "FixtureUpdater", "{945F81BC-6A17-B466-15B3-47E17BBFFEEE}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "LanguageAnalyzerSmoke", "LanguageAnalyzerSmoke", "{678BFC83-F74C-CD21-AFE5-9F1FD29B4092}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "NotifySmokeCheck", "NotifySmokeCheck", "{569894C1-998D-B530-0EAA-AE633B3BC297}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "PolicyDslValidator", "PolicyDslValidator", "{F3E2E624-EBEF-D7C4-007E-1297E7001D38}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "PolicySchemaExporter", "PolicySchemaExporter", "{94E5B89C-8E1D-757B-350E-821DBEADD75D}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "PolicySimulationSmoke", "PolicySimulationSmoke", "{9475E1E8-B4B3-EFFC-3B43-71F90D2021F2}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "RustFsMigrator", "RustFsMigrator", "{22A9ABBF-F2DA-7E3C-B6E2-05A8AE8A24F5}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "__External", "__External", "{5B52EF8A-3661-DCFF-797D-BC4D6AC60BDA}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "AirGap", "AirGap", "{F310596E-88BB-9E54-885E-21C61971917E}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.AirGap.Policy", "StellaOps.AirGap.Policy", "{D9492ED1-A812-924B-65E4-F518592B49BB}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.AirGap.Policy", "StellaOps.AirGap.Policy", "{3823DE1E-2ACE-C956-99E1-00DB786D9E1D}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Aoc", "Aoc", "{03DFF14F-7321-1784-D4C7-4E99D4120F48}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "__Libraries", "__Libraries", "{BDD326D6-7616-84F0-B914-74743BFBA520}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Aoc", "StellaOps.Aoc", "{EC506DBE-AB6D-492E-786E-8B176021BF2E}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Attestor", "Attestor", "{5AC09D9A-F2A5-9CFA-B3C5-8D25F257651C}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Attestor", "StellaOps.Attestor", "{33B1AE27-692A-1778-48C1-CCEC2B9BC78F}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Attestor.Envelope", "StellaOps.Attestor.Envelope", "{018E0E11-1CCE-A2BE-641D-21EE14D2E90D}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Attestor.Core", "StellaOps.Attestor.Core", "{5F27FB4E-CF09-3A6B-F5B4-BF5A709FA609}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "__Libraries", "__Libraries", "{AB67BDB9-D701-3AC9-9CDF-ECCDCCD8DB6D}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Attestor.GraphRoot", "StellaOps.Attestor.GraphRoot", "{3F605548-87E2-8A1D-306D-0CE6960B8242}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Attestor.ProofChain", "StellaOps.Attestor.ProofChain", "{45F7FA87-7451-6970-7F6E-F8BAE45E081B}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Authority", "Authority", "{C1DCEFBD-12A5-EAAE-632E-8EEB9BE491B6}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Authority", "StellaOps.Authority", "{A6928CBA-4D4D-AB2B-CA19-FEE6E73ECE70}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Auth.Abstractions", "StellaOps.Auth.Abstractions", "{F2E6CB0E-DF77-1FAA-582B-62B040DF3848}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Auth.Client", "StellaOps.Auth.Client", "{C494ECBE-DEA5-3576-D2AF-200FF12BC144}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Authority.Plugins.Abstractions", "StellaOps.Authority.Plugins.Abstractions", "{64689413-46D7-8499-68A6-B6367ACBC597}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Concelier", "Concelier", "{157C3671-CA0B-69FA-A7C9-74A1FDA97B99}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "__Libraries", "__Libraries", "{F39E09D6-BF93-B64A-CFE7-2BA92815C0FE}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Concelier.Cache.Valkey", "StellaOps.Concelier.Cache.Valkey", "{39EFDA5B-F5EE-8212-D5BA-90E1B82013E7}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Concelier.Connector.Common", "StellaOps.Concelier.Connector.Common", "{3B82DBF3-3DAE-EA97-85F4-6DCFA09940DF}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Concelier.Connector.Ghsa", "StellaOps.Concelier.Connector.Ghsa", "{A4FEB09C-E55C-03AE-8FC2-BF6D4F6C9FD7}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Concelier.Connector.Nvd", "StellaOps.Concelier.Connector.Nvd", "{67E71A20-7221-A495-BBCA-9B40D5193448}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Concelier.Connector.Osv", "StellaOps.Concelier.Connector.Osv", "{3FC9AD6C-AF2C-E557-4D34-8E52BA6AD9E8}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Concelier.Core", "StellaOps.Concelier.Core", "{6844B539-C2A3-9D4F-139D-9D533BCABADA}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Concelier.Interest", "StellaOps.Concelier.Interest", "{4263AA71-0335-3F44-9A9B-423C3A3D05E6}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Concelier.Merge", "StellaOps.Concelier.Merge", "{F1B1DB47-D2D7-59CB-679B-23E4928E8328}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Concelier.Models", "StellaOps.Concelier.Models", "{BC35DE94-4F04-3436-27A3-F11647FEDD5C}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Concelier.Normalization", "StellaOps.Concelier.Normalization", "{864C8B80-771A-0C15-30A5-558F99006E0D}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Concelier.Persistence", "StellaOps.Concelier.Persistence", "{603E7A23-1D6B-D3A9-B0E6-3E332B13ED5C}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Concelier.ProofService", "StellaOps.Concelier.ProofService", "{D2F7E58B-47D4-5205-D917-144CA1CFF4F1}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Concelier.RawModels", "StellaOps.Concelier.RawModels", "{1DCF4EBB-DBC4-752C-13D4-D1EECE4E8907}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Concelier.SbomIntegration", "StellaOps.Concelier.SbomIntegration", "{1B37A859-E733-60CB-4806-1A24B6F10E05}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Concelier.SourceIntel", "StellaOps.Concelier.SourceIntel", "{F2B58F4E-6F28-A25F-5BFB-CDEBAD6B9A3E}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Feedser", "Feedser", "{C4A90603-BE42-0044-CAB4-3EB910AD51A5}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Feedser.BinaryAnalysis", "StellaOps.Feedser.BinaryAnalysis", "{054761F9-16D3-B2F8-6F4D-EFC2248805CD}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Feedser.Core", "StellaOps.Feedser.Core", "{B54CE64C-4167-1DD1-B7D6-2FD7A5AEF715}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Policy", "Policy", "{8E6B774C-CC4E-CE7C-AD4B-8AF7C92889A6}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Policy.RiskProfile", "StellaOps.Policy.RiskProfile", "{BC12ED55-6015-7C8B-8384-B39CE93C76D6}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "__Libraries", "__Libraries", "{FF70543D-AFF9-1D38-4950-4F8EE18D60BB}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Policy", "StellaOps.Policy", "{831265B0-8896-9C95-3488-E12FD9F6DC53}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Provenance", "Provenance", "{316BBD0A-04D2-85C9-52EA-7993CC6C8930}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Provenance.Attestation", "StellaOps.Provenance.Attestation", "{9D6AB85A-85EA-D85A-5566-A121D34016E6}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Router", "Router", "{FC018E5B-1E2F-DE19-1E97-0C845058C469}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "__Libraries", "__Libraries", "{1BE5B76C-B486-560B-6CB2-44C6537249AA}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Messaging", "StellaOps.Messaging", "{F4F1CBE2-1CDD-CAA4-41F0-266DB4677C05}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Scanner", "Scanner", "{5896C4B3-31D1-1EDD-11D0-C46DB178DC12}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "__Libraries", "__Libraries", "{D4D193A8-47D7-0B1A-1327-F9C580E7AD07}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Scanner.Analyzers.Lang", "StellaOps.Scanner.Analyzers.Lang", "{69C91AE6-4555-7B2C-AD32-F7F11B9C605A}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Scanner.Core", "StellaOps.Scanner.Core", "{C9BCCEDF-7B8A-BCD8-A6B4-75EB25689FE8}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Scanner.ProofSpine", "StellaOps.Scanner.ProofSpine", "{9F30DC58-7747-31D8-2403-D7D0F5454C87}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Scanner.Surface.Env", "StellaOps.Scanner.Surface.Env", "{336213F7-1241-D268-8EA5-1C73F0040714}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Scanner.Surface.FS", "StellaOps.Scanner.Surface.FS", "{5693F73D-6707-6F86-65D6-654023205615}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Scanner.Surface.Secrets", "StellaOps.Scanner.Surface.Secrets", "{593308D7-2453-DC66-4151-E983E4B3F422}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Scheduler", "Scheduler", "{B24B448A-28D8-778E-DCC1-FCF4A0916DF5}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "__Libraries", "__Libraries", "{BF1AF1AB-97A8-BD70-63F2-E028DE8EE90F}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Scheduler.Models", "StellaOps.Scheduler.Models", "{3DB6D7AE-8187-5324-1208-D6090D5324C6}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Signer", "Signer", "{3247EE0D-B3E9-9C11-B0AE-FE719410390B}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Signer", "StellaOps.Signer", "{CD7C09DA-FEC8-2CC5-D00C-E525638DFF4A}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Signer.Core", "StellaOps.Signer.Core", "{79B10804-91E9-972E-1913-EE0F0B11663E}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "__Libraries", "__Libraries", "{1345DD29-BB3A-FB5F-4B3D-E29F6045A27A}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Auth.Security", "StellaOps.Auth.Security", "{9C2DD234-FA33-FDB6-86F0-EF9B75A13450}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Canonical.Json", "StellaOps.Canonical.Json", "{79E122F4-2325-3E92-438E-5825A307B594}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Configuration", "StellaOps.Configuration", "{538E2D98-5325-3F54-BE74-EFE5FC1ECBD8}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Cryptography", "StellaOps.Cryptography", "{66557252-B5C4-664B-D807-07018C627474}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Cryptography.DependencyInjection", "StellaOps.Cryptography.DependencyInjection", "{7203223D-FF02-7BEB-2798-D1639ACC01C4}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Cryptography.Kms", "StellaOps.Cryptography.Kms", "{5AC9EE40-1881-5F8A-46A2-2C303950D3C8}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Cryptography.Plugin.CryptoPro", "StellaOps.Cryptography.Plugin.CryptoPro", "{3C69853C-90E3-D889-1960-3B9229882590}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Cryptography.Plugin.OpenSslGost", "StellaOps.Cryptography.Plugin.OpenSslGost", "{643E4D4C-BC96-A37F-E0EC-488127F0B127}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Cryptography.Plugin.Pkcs11Gost", "StellaOps.Cryptography.Plugin.Pkcs11Gost", "{6F2CA7F5-3E7C-C61B-94E6-E7DD1227B5B1}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Cryptography.Plugin.PqSoft", "StellaOps.Cryptography.Plugin.PqSoft", "{F04B7DBB-77A5-C978-B2DE-8C189A32AA72}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Cryptography.Plugin.SimRemote", "StellaOps.Cryptography.Plugin.SimRemote", "{7C72F22A-20FF-DF5B-9191-6DFD0D497DB2}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Cryptography.Plugin.SmRemote", "StellaOps.Cryptography.Plugin.SmRemote", "{C896CC0A-F5E6-9AA4-C582-E691441F8D32}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Cryptography.Plugin.SmSoft", "StellaOps.Cryptography.Plugin.SmSoft", "{0AA3A418-AB45-CCA4-46D4-EEBFE011FECA}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Cryptography.Plugin.WineCsp", "StellaOps.Cryptography.Plugin.WineCsp", "{225D9926-4AE8-E539-70AD-8698E688F271}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Cryptography.PluginLoader", "StellaOps.Cryptography.PluginLoader", "{D6E8E69C-F721-BBCB-8C39-9716D53D72AD}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.DependencyInjection", "StellaOps.DependencyInjection", "{589A43FD-8213-E9E3-6CFF-9CBA72D53E98}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Evidence.Bundle", "StellaOps.Evidence.Bundle", "{2BACF7E3-1278-FE99-8343-8221E6FBA9DE}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Evidence.Core", "StellaOps.Evidence.Core", "{75E47125-E4D7-8482-F1A4-726564970864}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Infrastructure.EfCore", "StellaOps.Infrastructure.EfCore", "{FCD529E0-DD17-6587-B29C-12D425C0AD0C}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Infrastructure.Postgres", "StellaOps.Infrastructure.Postgres", "{61B23570-4F2D-B060-BE1F-37995682E494}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Ingestion.Telemetry", "StellaOps.Ingestion.Telemetry", "{1182764D-2143-EEF0-9270-3DCE392F5D06}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Plugin", "StellaOps.Plugin", "{772B02B5-6280-E1D4-3E2E-248D0455C2FB}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Provcache", "StellaOps.Provcache", "{48F90289-938C-CCA7-B60F-D2143E7C9A69}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Provenance", "StellaOps.Provenance", "{E69FA1A0-6D1B-A6E4-2DC0-8F4C5F21BF04}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Replay.Core", "StellaOps.Replay.Core", "{083067CF-CE89-EF39-9BD3-4741919E26F3}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.VersionComparison", "StellaOps.VersionComparison", "{A7542386-71EB-4F34-E1CE-27D399325955}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "__Tests", "__Tests", "{90659617-4DF7-809A-4E5B-29BB5A98E8E1}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "__Libraries", "__Libraries", "{AB8B269C-5A2A-A4B8-0488-B5F81E55B4D9}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Concelier.Testing", "StellaOps.Concelier.Testing", "{A527DABC-AA87-7C64-8056-4627531A9960}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Infrastructure.Postgres.Testing", "StellaOps.Infrastructure.Postgres.Testing", "{CEDC2447-F717-3C95-7E08-F214D575A7B7}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FixtureUpdater", "FixtureUpdater\FixtureUpdater.csproj", "{52220F70-4EAA-D93F-752B-CD431AAEEDDB}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LanguageAnalyzerSmoke", "LanguageAnalyzerSmoke\LanguageAnalyzerSmoke.csproj", "{C0C58E4B-9B24-29EA-9585-4BB462666824}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NotifySmokeCheck", "NotifySmokeCheck\NotifySmokeCheck.csproj", "{24D80D5F-0A63-7924-B7C3-79A2772A28DF}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PolicyDslValidator", "PolicyDslValidator\PolicyDslValidator.csproj", "{8A3083F4-FBB0-6972-9FB5-FE3D05488CD6}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PolicySchemaExporter", "PolicySchemaExporter\PolicySchemaExporter.csproj", "{13E7A80F-191B-0B12-4C7F-A1CA9808DD65}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PolicySimulationSmoke", "PolicySimulationSmoke\PolicySimulationSmoke.csproj", "{A82DBB41-8BF0-440B-1BD1-611A2521DAA0}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RustFsMigrator", "RustFsMigrator\RustFsMigrator.csproj", "{8C96DAFC-3A63-EB7B-EA8F-07A63817204D}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.AirGap.Policy", "E:\dev\git.stella-ops.org\src\AirGap\StellaOps.AirGap.Policy\StellaOps.AirGap.Policy\StellaOps.AirGap.Policy.csproj", "{AD31623A-BC43-52C2-D906-AC1D8784A541}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Aoc", "E:\dev\git.stella-ops.org\src\Aoc\__Libraries\StellaOps.Aoc\StellaOps.Aoc.csproj", "{776E2142-804F-03B9-C804-D061D64C6092}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Attestor.Core", "E:\dev\git.stella-ops.org\src\Attestor\StellaOps.Attestor\StellaOps.Attestor.Core\StellaOps.Attestor.Core.csproj", "{5B4DF41E-C8CC-2606-FA2D-967118BD3C59}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Attestor.Envelope", "E:\dev\git.stella-ops.org\src\Attestor\StellaOps.Attestor.Envelope\StellaOps.Attestor.Envelope.csproj", "{3D8C5A6C-462D-7487-5BD0-A3EF6B657EB6}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Attestor.GraphRoot", "E:\dev\git.stella-ops.org\src\Attestor\__Libraries\StellaOps.Attestor.GraphRoot\StellaOps.Attestor.GraphRoot.csproj", "{2609BC1A-6765-29BE-78CC-C0F1D2814F10}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Attestor.ProofChain", "E:\dev\git.stella-ops.org\src\Attestor\__Libraries\StellaOps.Attestor.ProofChain\StellaOps.Attestor.ProofChain.csproj", "{C6822231-A4F4-9E69-6CE2-4FDB3E81C728}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Auth.Abstractions", "E:\dev\git.stella-ops.org\src\Authority\StellaOps.Authority\StellaOps.Auth.Abstractions\StellaOps.Auth.Abstractions.csproj", "{55D9B653-FB76-FCE8-1A3C-67B1BEDEC214}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Auth.Client", "E:\dev\git.stella-ops.org\src\Authority\StellaOps.Authority\StellaOps.Auth.Client\StellaOps.Auth.Client.csproj", "{DE5BF139-1E5C-D6EA-4FAA-661EF353A194}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Auth.Security", "E:\dev\git.stella-ops.org\src\__Libraries\StellaOps.Auth.Security\StellaOps.Auth.Security.csproj", "{335E62C0-9E69-A952-680B-753B1B17C6D0}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Authority.Plugins.Abstractions", "E:\dev\git.stella-ops.org\src\Authority\StellaOps.Authority\StellaOps.Authority.Plugins.Abstractions\StellaOps.Authority.Plugins.Abstractions.csproj", "{97F94029-5419-6187-5A63-5C8FD9232FAE}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Canonical.Json", "E:\dev\git.stella-ops.org\src\__Libraries\StellaOps.Canonical.Json\StellaOps.Canonical.Json.csproj", "{AF9E7F02-25AD-3540-18D7-F6A4F8BA5A60}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Concelier.Cache.Valkey", "E:\dev\git.stella-ops.org\src\Concelier\__Libraries\StellaOps.Concelier.Cache.Valkey\StellaOps.Concelier.Cache.Valkey.csproj", "{AB6AE2B6-8D6B-2D9F-2A88-7C596C59F4FC}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Concelier.Connector.Common", "E:\dev\git.stella-ops.org\src\Concelier\__Libraries\StellaOps.Concelier.Connector.Common\StellaOps.Concelier.Connector.Common.csproj", "{375F5AD0-F7EE-1782-7B34-E181CDB61B9F}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Concelier.Connector.Ghsa", "E:\dev\git.stella-ops.org\src\Concelier\__Libraries\StellaOps.Concelier.Connector.Ghsa\StellaOps.Concelier.Connector.Ghsa.csproj", "{C117E9AF-D7B8-D4E2-4262-84B6321A9F5C}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Concelier.Connector.Nvd", "E:\dev\git.stella-ops.org\src\Concelier\__Libraries\StellaOps.Concelier.Connector.Nvd\StellaOps.Concelier.Connector.Nvd.csproj", "{D492EFDB-294B-ABA2-FAFB-EAEE6F3DCB52}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Concelier.Connector.Osv", "E:\dev\git.stella-ops.org\src\Concelier\__Libraries\StellaOps.Concelier.Connector.Osv\StellaOps.Concelier.Connector.Osv.csproj", "{9D0C51AF-D1AB-9E12-0B16-A4AA974FAAB5}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Concelier.Core", "E:\dev\git.stella-ops.org\src\Concelier\__Libraries\StellaOps.Concelier.Core\StellaOps.Concelier.Core.csproj", "{BA45605A-1CCE-6B0C-489D-C113915B243F}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Concelier.Interest", "E:\dev\git.stella-ops.org\src\Concelier\__Libraries\StellaOps.Concelier.Interest\StellaOps.Concelier.Interest.csproj", "{9D31FC8A-2A69-B78A-D3E5-4F867B16D971}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Concelier.Merge", "E:\dev\git.stella-ops.org\src\Concelier\__Libraries\StellaOps.Concelier.Merge\StellaOps.Concelier.Merge.csproj", "{92268008-FBB0-C7AD-ECC2-7B75BED9F5E1}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Concelier.Models", "E:\dev\git.stella-ops.org\src\Concelier\__Libraries\StellaOps.Concelier.Models\StellaOps.Concelier.Models.csproj", "{8DCCAF70-D364-4C8B-4E90-AF65091DE0C5}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Concelier.Normalization", "E:\dev\git.stella-ops.org\src\Concelier\__Libraries\StellaOps.Concelier.Normalization\StellaOps.Concelier.Normalization.csproj", "{7828C164-DD01-2809-CCB3-364486834F60}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Concelier.Persistence", "E:\dev\git.stella-ops.org\src\Concelier\__Libraries\StellaOps.Concelier.Persistence\StellaOps.Concelier.Persistence.csproj", "{DE95E7B2-0937-A980-441F-829E023BC43E}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Concelier.ProofService", "E:\dev\git.stella-ops.org\src\Concelier\__Libraries\StellaOps.Concelier.ProofService\StellaOps.Concelier.ProofService.csproj", "{91D69463-23E2-E2C7-AA7E-A78B13CED620}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Concelier.RawModels", "E:\dev\git.stella-ops.org\src\Concelier\__Libraries\StellaOps.Concelier.RawModels\StellaOps.Concelier.RawModels.csproj", "{34EFF636-81A7-8DF6-7CC9-4DA784BAC7F3}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Concelier.SbomIntegration", "E:\dev\git.stella-ops.org\src\Concelier\__Libraries\StellaOps.Concelier.SbomIntegration\StellaOps.Concelier.SbomIntegration.csproj", "{5DCF16A8-97C6-2CB4-6A63-0370239039EB}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Concelier.SourceIntel", "E:\dev\git.stella-ops.org\src\Concelier\__Libraries\StellaOps.Concelier.SourceIntel\StellaOps.Concelier.SourceIntel.csproj", "{EB093C48-CDAC-106B-1196-AE34809B34C0}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Concelier.Testing", "E:\dev\git.stella-ops.org\src\__Tests\__Libraries\StellaOps.Concelier.Testing\StellaOps.Concelier.Testing.csproj", "{370A79BD-AAB3-B833-2B06-A28B3A19E153}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Configuration", "E:\dev\git.stella-ops.org\src\__Libraries\StellaOps.Configuration\StellaOps.Configuration.csproj", "{92C62F7B-8028-6EE1-B71B-F45F459B8E97}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Cryptography", "E:\dev\git.stella-ops.org\src\__Libraries\StellaOps.Cryptography\StellaOps.Cryptography.csproj", "{F664A948-E352-5808-E780-77A03F19E93E}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Cryptography.DependencyInjection", "E:\dev\git.stella-ops.org\src\__Libraries\StellaOps.Cryptography.DependencyInjection\StellaOps.Cryptography.DependencyInjection.csproj", "{FA83F778-5252-0B80-5555-E69F790322EA}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Cryptography.Kms", "E:\dev\git.stella-ops.org\src\__Libraries\StellaOps.Cryptography.Kms\StellaOps.Cryptography.Kms.csproj", "{F3A27846-6DE0-3448-222C-25A273E86B2E}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Cryptography.Plugin.CryptoPro", "E:\dev\git.stella-ops.org\src\__Libraries\StellaOps.Cryptography.Plugin.CryptoPro\StellaOps.Cryptography.Plugin.CryptoPro.csproj", "{C53E0895-879A-D9E6-0A43-24AD17A2F270}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Cryptography.Plugin.OpenSslGost", "E:\dev\git.stella-ops.org\src\__Libraries\StellaOps.Cryptography.Plugin.OpenSslGost\StellaOps.Cryptography.Plugin.OpenSslGost.csproj", "{0AED303F-69E6-238F-EF80-81985080EDB7}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Cryptography.Plugin.Pkcs11Gost", "E:\dev\git.stella-ops.org\src\__Libraries\StellaOps.Cryptography.Plugin.Pkcs11Gost\StellaOps.Cryptography.Plugin.Pkcs11Gost.csproj", "{2904D288-CE64-A565-2C46-C2E85A96A1EE}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Cryptography.Plugin.PqSoft", "E:\dev\git.stella-ops.org\src\__Libraries\StellaOps.Cryptography.Plugin.PqSoft\StellaOps.Cryptography.Plugin.PqSoft.csproj", "{A6667CC3-B77F-023E-3A67-05F99E9FF46A}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Cryptography.Plugin.SimRemote", "E:\dev\git.stella-ops.org\src\__Libraries\StellaOps.Cryptography.Plugin.SimRemote\StellaOps.Cryptography.Plugin.SimRemote.csproj", "{A26E2816-F787-F76B-1D6C-E086DD3E19CE}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Cryptography.Plugin.SmRemote", "E:\dev\git.stella-ops.org\src\__Libraries\StellaOps.Cryptography.Plugin.SmRemote\StellaOps.Cryptography.Plugin.SmRemote.csproj", "{B3DEC619-67AC-1B5A-4F3E-A1F24C3F6877}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Cryptography.Plugin.SmSoft", "E:\dev\git.stella-ops.org\src\__Libraries\StellaOps.Cryptography.Plugin.SmSoft\StellaOps.Cryptography.Plugin.SmSoft.csproj", "{90DB65B4-8F6E-FB8E-0281-505AD8BC6BA6}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Cryptography.Plugin.WineCsp", "E:\dev\git.stella-ops.org\src\__Libraries\StellaOps.Cryptography.Plugin.WineCsp\StellaOps.Cryptography.Plugin.WineCsp.csproj", "{059FBB86-DEE6-8207-3F23-2A1A3EC00DEA}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Cryptography.PluginLoader", "E:\dev\git.stella-ops.org\src\__Libraries\StellaOps.Cryptography.PluginLoader\StellaOps.Cryptography.PluginLoader.csproj", "{8BBA3159-C4CC-F685-A28C-7FE6CBD3D2A1}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.DependencyInjection", "E:\dev\git.stella-ops.org\src\__Libraries\StellaOps.DependencyInjection\StellaOps.DependencyInjection.csproj", "{632A1F0D-1BA5-C84B-B716-2BE638A92780}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Evidence.Bundle", "E:\dev\git.stella-ops.org\src\__Libraries\StellaOps.Evidence.Bundle\StellaOps.Evidence.Bundle.csproj", "{9DE7852B-7E2D-257E-B0F1-45D2687854ED}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Evidence.Core", "E:\dev\git.stella-ops.org\src\__Libraries\StellaOps.Evidence.Core\StellaOps.Evidence.Core.csproj", "{DC2AFC89-C3C8-4E9B-13A7-027EB6386EFA}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Feedser.BinaryAnalysis", "E:\dev\git.stella-ops.org\src\Feedser\StellaOps.Feedser.BinaryAnalysis\StellaOps.Feedser.BinaryAnalysis.csproj", "{CB296A20-2732-77C1-7F23-27D5BAEDD0C7}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Feedser.Core", "E:\dev\git.stella-ops.org\src\Feedser\StellaOps.Feedser.Core\StellaOps.Feedser.Core.csproj", "{0DBEC9BA-FE1D-3898-B2C6-E4357DC23E0F}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Infrastructure.EfCore", "E:\dev\git.stella-ops.org\src\__Libraries\StellaOps.Infrastructure.EfCore\StellaOps.Infrastructure.EfCore.csproj", "{A63897D9-9531-989B-7309-E384BCFC2BB9}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Infrastructure.Postgres", "E:\dev\git.stella-ops.org\src\__Libraries\StellaOps.Infrastructure.Postgres\StellaOps.Infrastructure.Postgres.csproj", "{8C594D82-3463-3367-4F06-900AC707753D}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Infrastructure.Postgres.Testing", "E:\dev\git.stella-ops.org\src\__Tests\__Libraries\StellaOps.Infrastructure.Postgres.Testing\StellaOps.Infrastructure.Postgres.Testing.csproj", "{52F400CD-D473-7A1F-7986-89011CD2A887}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Ingestion.Telemetry", "E:\dev\git.stella-ops.org\src\__Libraries\StellaOps.Ingestion.Telemetry\StellaOps.Ingestion.Telemetry.csproj", "{9588FBF9-C37E-D16E-2E8F-CFA226EAC01D}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Messaging", "E:\dev\git.stella-ops.org\src\Router\__Libraries\StellaOps.Messaging\StellaOps.Messaging.csproj", "{97998C88-E6E1-D5E2-B632-537B58E00CBF}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Plugin", "E:\dev\git.stella-ops.org\src\__Libraries\StellaOps.Plugin\StellaOps.Plugin.csproj", "{38A9EE9B-6FC8-93BC-0D43-2A906E678D66}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Policy", "E:\dev\git.stella-ops.org\src\Policy\__Libraries\StellaOps.Policy\StellaOps.Policy.csproj", "{19868E2D-7163-2108-1094-F13887C4F070}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Policy.RiskProfile", "E:\dev\git.stella-ops.org\src\Policy\StellaOps.Policy.RiskProfile\StellaOps.Policy.RiskProfile.csproj", "{CC319FC5-F4B1-C3DD-7310-4DAD343E0125}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Provcache", "E:\dev\git.stella-ops.org\src\__Libraries\StellaOps.Provcache\StellaOps.Provcache.csproj", "{84F711C2-C210-28D2-F0D9-B13733FEE23D}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Provenance", "E:\dev\git.stella-ops.org\src\__Libraries\StellaOps.Provenance\StellaOps.Provenance.csproj", "{CBB14B90-27F9-8DD6-DFC4-3507DBD1FBC6}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Provenance.Attestation", "E:\dev\git.stella-ops.org\src\Provenance\StellaOps.Provenance.Attestation\StellaOps.Provenance.Attestation.csproj", "{A78EBC0F-C62C-8F56-95C0-330E376242A2}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Replay.Core", "E:\dev\git.stella-ops.org\src\__Libraries\StellaOps.Replay.Core\StellaOps.Replay.Core.csproj", "{6D26FB21-7E48-024B-E5D4-E3F0F31976BB}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Scanner.Analyzers.Lang", "E:\dev\git.stella-ops.org\src\Scanner\__Libraries\StellaOps.Scanner.Analyzers.Lang\StellaOps.Scanner.Analyzers.Lang.csproj", "{28D91816-206C-576E-1A83-FD98E08C2E3C}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Scanner.Core", "E:\dev\git.stella-ops.org\src\Scanner\__Libraries\StellaOps.Scanner.Core\StellaOps.Scanner.Core.csproj", "{58D8630F-C0F4-B772-8572-BCC98FF0F0D8}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Scanner.ProofSpine", "E:\dev\git.stella-ops.org\src\Scanner\__Libraries\StellaOps.Scanner.ProofSpine\StellaOps.Scanner.ProofSpine.csproj", "{7CB7FEA8-8A12-A5D6-0057-AA65DB328617}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Scanner.Surface.Env", "E:\dev\git.stella-ops.org\src\Scanner\__Libraries\StellaOps.Scanner.Surface.Env\StellaOps.Scanner.Surface.Env.csproj", "{52698305-D6F8-C13C-0882-48FC37726404}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Scanner.Surface.FS", "E:\dev\git.stella-ops.org\src\Scanner\__Libraries\StellaOps.Scanner.Surface.FS\StellaOps.Scanner.Surface.FS.csproj", "{5567139C-0365-B6A0-5DD0-978A09B9F176}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Scanner.Surface.Secrets", "E:\dev\git.stella-ops.org\src\Scanner\__Libraries\StellaOps.Scanner.Surface.Secrets\StellaOps.Scanner.Surface.Secrets.csproj", "{256D269B-35EA-F833-2F1D-8E0058908DEE}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Scheduler.Models", "E:\dev\git.stella-ops.org\src\Scheduler\__Libraries\StellaOps.Scheduler.Models\StellaOps.Scheduler.Models.csproj", "{1F372AB9-D8DD-D295-1D5E-CB5D454CBB24}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Signer.Core", "E:\dev\git.stella-ops.org\src\Signer\StellaOps.Signer\StellaOps.Signer.Core\StellaOps.Signer.Core.csproj", "{0AF13355-173C-3128-5AFC-D32E540DA3EF}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.VersionComparison", "E:\dev\git.stella-ops.org\src\__Libraries\StellaOps.VersionComparison\StellaOps.VersionComparison.csproj", "{1D761F8B-921C-53BF-DCF5-5ABD329EEB0C}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Release|Any CPU = Release|Any CPU - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {52220F70-4EAA-D93F-752B-CD431AAEEDDB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {52220F70-4EAA-D93F-752B-CD431AAEEDDB}.Debug|Any CPU.Build.0 = Debug|Any CPU - {52220F70-4EAA-D93F-752B-CD431AAEEDDB}.Release|Any CPU.ActiveCfg = Release|Any CPU - {52220F70-4EAA-D93F-752B-CD431AAEEDDB}.Release|Any CPU.Build.0 = Release|Any CPU - {C0C58E4B-9B24-29EA-9585-4BB462666824}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {C0C58E4B-9B24-29EA-9585-4BB462666824}.Debug|Any CPU.Build.0 = Debug|Any CPU - {C0C58E4B-9B24-29EA-9585-4BB462666824}.Release|Any CPU.ActiveCfg = Release|Any CPU - {C0C58E4B-9B24-29EA-9585-4BB462666824}.Release|Any CPU.Build.0 = Release|Any CPU - {24D80D5F-0A63-7924-B7C3-79A2772A28DF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {24D80D5F-0A63-7924-B7C3-79A2772A28DF}.Debug|Any CPU.Build.0 = Debug|Any CPU - {24D80D5F-0A63-7924-B7C3-79A2772A28DF}.Release|Any CPU.ActiveCfg = Release|Any CPU - {24D80D5F-0A63-7924-B7C3-79A2772A28DF}.Release|Any CPU.Build.0 = Release|Any CPU - {8A3083F4-FBB0-6972-9FB5-FE3D05488CD6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {8A3083F4-FBB0-6972-9FB5-FE3D05488CD6}.Debug|Any CPU.Build.0 = Debug|Any CPU - {8A3083F4-FBB0-6972-9FB5-FE3D05488CD6}.Release|Any CPU.ActiveCfg = Release|Any CPU - {8A3083F4-FBB0-6972-9FB5-FE3D05488CD6}.Release|Any CPU.Build.0 = Release|Any CPU - {13E7A80F-191B-0B12-4C7F-A1CA9808DD65}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {13E7A80F-191B-0B12-4C7F-A1CA9808DD65}.Debug|Any CPU.Build.0 = Debug|Any CPU - {13E7A80F-191B-0B12-4C7F-A1CA9808DD65}.Release|Any CPU.ActiveCfg = Release|Any CPU - {13E7A80F-191B-0B12-4C7F-A1CA9808DD65}.Release|Any CPU.Build.0 = Release|Any CPU - {A82DBB41-8BF0-440B-1BD1-611A2521DAA0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {A82DBB41-8BF0-440B-1BD1-611A2521DAA0}.Debug|Any CPU.Build.0 = Debug|Any CPU - {A82DBB41-8BF0-440B-1BD1-611A2521DAA0}.Release|Any CPU.ActiveCfg = Release|Any CPU - {A82DBB41-8BF0-440B-1BD1-611A2521DAA0}.Release|Any CPU.Build.0 = Release|Any CPU - {8C96DAFC-3A63-EB7B-EA8F-07A63817204D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {8C96DAFC-3A63-EB7B-EA8F-07A63817204D}.Debug|Any CPU.Build.0 = Debug|Any CPU - {8C96DAFC-3A63-EB7B-EA8F-07A63817204D}.Release|Any CPU.ActiveCfg = Release|Any CPU - {8C96DAFC-3A63-EB7B-EA8F-07A63817204D}.Release|Any CPU.Build.0 = Release|Any CPU - {AD31623A-BC43-52C2-D906-AC1D8784A541}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {AD31623A-BC43-52C2-D906-AC1D8784A541}.Debug|Any CPU.Build.0 = Debug|Any CPU - {AD31623A-BC43-52C2-D906-AC1D8784A541}.Release|Any CPU.ActiveCfg = Release|Any CPU - {AD31623A-BC43-52C2-D906-AC1D8784A541}.Release|Any CPU.Build.0 = Release|Any CPU - {776E2142-804F-03B9-C804-D061D64C6092}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {776E2142-804F-03B9-C804-D061D64C6092}.Debug|Any CPU.Build.0 = Debug|Any CPU - {776E2142-804F-03B9-C804-D061D64C6092}.Release|Any CPU.ActiveCfg = Release|Any CPU - {776E2142-804F-03B9-C804-D061D64C6092}.Release|Any CPU.Build.0 = Release|Any CPU - {5B4DF41E-C8CC-2606-FA2D-967118BD3C59}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {5B4DF41E-C8CC-2606-FA2D-967118BD3C59}.Debug|Any CPU.Build.0 = Debug|Any CPU - {5B4DF41E-C8CC-2606-FA2D-967118BD3C59}.Release|Any CPU.ActiveCfg = Release|Any CPU - {5B4DF41E-C8CC-2606-FA2D-967118BD3C59}.Release|Any CPU.Build.0 = Release|Any CPU - {3D8C5A6C-462D-7487-5BD0-A3EF6B657EB6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {3D8C5A6C-462D-7487-5BD0-A3EF6B657EB6}.Debug|Any CPU.Build.0 = Debug|Any CPU - {3D8C5A6C-462D-7487-5BD0-A3EF6B657EB6}.Release|Any CPU.ActiveCfg = Release|Any CPU - {3D8C5A6C-462D-7487-5BD0-A3EF6B657EB6}.Release|Any CPU.Build.0 = Release|Any CPU - {2609BC1A-6765-29BE-78CC-C0F1D2814F10}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {2609BC1A-6765-29BE-78CC-C0F1D2814F10}.Debug|Any CPU.Build.0 = Debug|Any CPU - {2609BC1A-6765-29BE-78CC-C0F1D2814F10}.Release|Any CPU.ActiveCfg = Release|Any CPU - {2609BC1A-6765-29BE-78CC-C0F1D2814F10}.Release|Any CPU.Build.0 = Release|Any CPU - {C6822231-A4F4-9E69-6CE2-4FDB3E81C728}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {C6822231-A4F4-9E69-6CE2-4FDB3E81C728}.Debug|Any CPU.Build.0 = Debug|Any CPU - {C6822231-A4F4-9E69-6CE2-4FDB3E81C728}.Release|Any CPU.ActiveCfg = Release|Any CPU - {C6822231-A4F4-9E69-6CE2-4FDB3E81C728}.Release|Any CPU.Build.0 = Release|Any CPU - {55D9B653-FB76-FCE8-1A3C-67B1BEDEC214}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {55D9B653-FB76-FCE8-1A3C-67B1BEDEC214}.Debug|Any CPU.Build.0 = Debug|Any CPU - {55D9B653-FB76-FCE8-1A3C-67B1BEDEC214}.Release|Any CPU.ActiveCfg = Release|Any CPU - {55D9B653-FB76-FCE8-1A3C-67B1BEDEC214}.Release|Any CPU.Build.0 = Release|Any CPU - {DE5BF139-1E5C-D6EA-4FAA-661EF353A194}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {DE5BF139-1E5C-D6EA-4FAA-661EF353A194}.Debug|Any CPU.Build.0 = Debug|Any CPU - {DE5BF139-1E5C-D6EA-4FAA-661EF353A194}.Release|Any CPU.ActiveCfg = Release|Any CPU - {DE5BF139-1E5C-D6EA-4FAA-661EF353A194}.Release|Any CPU.Build.0 = Release|Any CPU - {335E62C0-9E69-A952-680B-753B1B17C6D0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {335E62C0-9E69-A952-680B-753B1B17C6D0}.Debug|Any CPU.Build.0 = Debug|Any CPU - {335E62C0-9E69-A952-680B-753B1B17C6D0}.Release|Any CPU.ActiveCfg = Release|Any CPU - {335E62C0-9E69-A952-680B-753B1B17C6D0}.Release|Any CPU.Build.0 = Release|Any CPU - {97F94029-5419-6187-5A63-5C8FD9232FAE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {97F94029-5419-6187-5A63-5C8FD9232FAE}.Debug|Any CPU.Build.0 = Debug|Any CPU - {97F94029-5419-6187-5A63-5C8FD9232FAE}.Release|Any CPU.ActiveCfg = Release|Any CPU - {97F94029-5419-6187-5A63-5C8FD9232FAE}.Release|Any CPU.Build.0 = Release|Any CPU - {AF9E7F02-25AD-3540-18D7-F6A4F8BA5A60}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {AF9E7F02-25AD-3540-18D7-F6A4F8BA5A60}.Debug|Any CPU.Build.0 = Debug|Any CPU - {AF9E7F02-25AD-3540-18D7-F6A4F8BA5A60}.Release|Any CPU.ActiveCfg = Release|Any CPU - {AF9E7F02-25AD-3540-18D7-F6A4F8BA5A60}.Release|Any CPU.Build.0 = Release|Any CPU - {AB6AE2B6-8D6B-2D9F-2A88-7C596C59F4FC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {AB6AE2B6-8D6B-2D9F-2A88-7C596C59F4FC}.Debug|Any CPU.Build.0 = Debug|Any CPU - {AB6AE2B6-8D6B-2D9F-2A88-7C596C59F4FC}.Release|Any CPU.ActiveCfg = Release|Any CPU - {AB6AE2B6-8D6B-2D9F-2A88-7C596C59F4FC}.Release|Any CPU.Build.0 = Release|Any CPU - {375F5AD0-F7EE-1782-7B34-E181CDB61B9F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {375F5AD0-F7EE-1782-7B34-E181CDB61B9F}.Debug|Any CPU.Build.0 = Debug|Any CPU - {375F5AD0-F7EE-1782-7B34-E181CDB61B9F}.Release|Any CPU.ActiveCfg = Release|Any CPU - {375F5AD0-F7EE-1782-7B34-E181CDB61B9F}.Release|Any CPU.Build.0 = Release|Any CPU - {C117E9AF-D7B8-D4E2-4262-84B6321A9F5C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {C117E9AF-D7B8-D4E2-4262-84B6321A9F5C}.Debug|Any CPU.Build.0 = Debug|Any CPU - {C117E9AF-D7B8-D4E2-4262-84B6321A9F5C}.Release|Any CPU.ActiveCfg = Release|Any CPU - {C117E9AF-D7B8-D4E2-4262-84B6321A9F5C}.Release|Any CPU.Build.0 = Release|Any CPU - {D492EFDB-294B-ABA2-FAFB-EAEE6F3DCB52}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {D492EFDB-294B-ABA2-FAFB-EAEE6F3DCB52}.Debug|Any CPU.Build.0 = Debug|Any CPU - {D492EFDB-294B-ABA2-FAFB-EAEE6F3DCB52}.Release|Any CPU.ActiveCfg = Release|Any CPU - {D492EFDB-294B-ABA2-FAFB-EAEE6F3DCB52}.Release|Any CPU.Build.0 = Release|Any CPU - {9D0C51AF-D1AB-9E12-0B16-A4AA974FAAB5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {9D0C51AF-D1AB-9E12-0B16-A4AA974FAAB5}.Debug|Any CPU.Build.0 = Debug|Any CPU - {9D0C51AF-D1AB-9E12-0B16-A4AA974FAAB5}.Release|Any CPU.ActiveCfg = Release|Any CPU - {9D0C51AF-D1AB-9E12-0B16-A4AA974FAAB5}.Release|Any CPU.Build.0 = Release|Any CPU - {BA45605A-1CCE-6B0C-489D-C113915B243F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {BA45605A-1CCE-6B0C-489D-C113915B243F}.Debug|Any CPU.Build.0 = Debug|Any CPU - {BA45605A-1CCE-6B0C-489D-C113915B243F}.Release|Any CPU.ActiveCfg = Release|Any CPU - {BA45605A-1CCE-6B0C-489D-C113915B243F}.Release|Any CPU.Build.0 = Release|Any CPU - {9D31FC8A-2A69-B78A-D3E5-4F867B16D971}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {9D31FC8A-2A69-B78A-D3E5-4F867B16D971}.Debug|Any CPU.Build.0 = Debug|Any CPU - {9D31FC8A-2A69-B78A-D3E5-4F867B16D971}.Release|Any CPU.ActiveCfg = Release|Any CPU - {9D31FC8A-2A69-B78A-D3E5-4F867B16D971}.Release|Any CPU.Build.0 = Release|Any CPU - {92268008-FBB0-C7AD-ECC2-7B75BED9F5E1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {92268008-FBB0-C7AD-ECC2-7B75BED9F5E1}.Debug|Any CPU.Build.0 = Debug|Any CPU - {92268008-FBB0-C7AD-ECC2-7B75BED9F5E1}.Release|Any CPU.ActiveCfg = Release|Any CPU - {92268008-FBB0-C7AD-ECC2-7B75BED9F5E1}.Release|Any CPU.Build.0 = Release|Any CPU - {8DCCAF70-D364-4C8B-4E90-AF65091DE0C5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {8DCCAF70-D364-4C8B-4E90-AF65091DE0C5}.Debug|Any CPU.Build.0 = Debug|Any CPU - {8DCCAF70-D364-4C8B-4E90-AF65091DE0C5}.Release|Any CPU.ActiveCfg = Release|Any CPU - {8DCCAF70-D364-4C8B-4E90-AF65091DE0C5}.Release|Any CPU.Build.0 = Release|Any CPU - {7828C164-DD01-2809-CCB3-364486834F60}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {7828C164-DD01-2809-CCB3-364486834F60}.Debug|Any CPU.Build.0 = Debug|Any CPU - {7828C164-DD01-2809-CCB3-364486834F60}.Release|Any CPU.ActiveCfg = Release|Any CPU - {7828C164-DD01-2809-CCB3-364486834F60}.Release|Any CPU.Build.0 = Release|Any CPU - {DE95E7B2-0937-A980-441F-829E023BC43E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {DE95E7B2-0937-A980-441F-829E023BC43E}.Debug|Any CPU.Build.0 = Debug|Any CPU - {DE95E7B2-0937-A980-441F-829E023BC43E}.Release|Any CPU.ActiveCfg = Release|Any CPU - {DE95E7B2-0937-A980-441F-829E023BC43E}.Release|Any CPU.Build.0 = Release|Any CPU - {91D69463-23E2-E2C7-AA7E-A78B13CED620}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {91D69463-23E2-E2C7-AA7E-A78B13CED620}.Debug|Any CPU.Build.0 = Debug|Any CPU - {91D69463-23E2-E2C7-AA7E-A78B13CED620}.Release|Any CPU.ActiveCfg = Release|Any CPU - {91D69463-23E2-E2C7-AA7E-A78B13CED620}.Release|Any CPU.Build.0 = Release|Any CPU - {34EFF636-81A7-8DF6-7CC9-4DA784BAC7F3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {34EFF636-81A7-8DF6-7CC9-4DA784BAC7F3}.Debug|Any CPU.Build.0 = Debug|Any CPU - {34EFF636-81A7-8DF6-7CC9-4DA784BAC7F3}.Release|Any CPU.ActiveCfg = Release|Any CPU - {34EFF636-81A7-8DF6-7CC9-4DA784BAC7F3}.Release|Any CPU.Build.0 = Release|Any CPU - {5DCF16A8-97C6-2CB4-6A63-0370239039EB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {5DCF16A8-97C6-2CB4-6A63-0370239039EB}.Debug|Any CPU.Build.0 = Debug|Any CPU - {5DCF16A8-97C6-2CB4-6A63-0370239039EB}.Release|Any CPU.ActiveCfg = Release|Any CPU - {5DCF16A8-97C6-2CB4-6A63-0370239039EB}.Release|Any CPU.Build.0 = Release|Any CPU - {EB093C48-CDAC-106B-1196-AE34809B34C0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {EB093C48-CDAC-106B-1196-AE34809B34C0}.Debug|Any CPU.Build.0 = Debug|Any CPU - {EB093C48-CDAC-106B-1196-AE34809B34C0}.Release|Any CPU.ActiveCfg = Release|Any CPU - {EB093C48-CDAC-106B-1196-AE34809B34C0}.Release|Any CPU.Build.0 = Release|Any CPU - {370A79BD-AAB3-B833-2B06-A28B3A19E153}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {370A79BD-AAB3-B833-2B06-A28B3A19E153}.Debug|Any CPU.Build.0 = Debug|Any CPU - {370A79BD-AAB3-B833-2B06-A28B3A19E153}.Release|Any CPU.ActiveCfg = Release|Any CPU - {370A79BD-AAB3-B833-2B06-A28B3A19E153}.Release|Any CPU.Build.0 = Release|Any CPU - {92C62F7B-8028-6EE1-B71B-F45F459B8E97}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {92C62F7B-8028-6EE1-B71B-F45F459B8E97}.Debug|Any CPU.Build.0 = Debug|Any CPU - {92C62F7B-8028-6EE1-B71B-F45F459B8E97}.Release|Any CPU.ActiveCfg = Release|Any CPU - {92C62F7B-8028-6EE1-B71B-F45F459B8E97}.Release|Any CPU.Build.0 = Release|Any CPU - {F664A948-E352-5808-E780-77A03F19E93E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {F664A948-E352-5808-E780-77A03F19E93E}.Debug|Any CPU.Build.0 = Debug|Any CPU - {F664A948-E352-5808-E780-77A03F19E93E}.Release|Any CPU.ActiveCfg = Release|Any CPU - {F664A948-E352-5808-E780-77A03F19E93E}.Release|Any CPU.Build.0 = Release|Any CPU - {FA83F778-5252-0B80-5555-E69F790322EA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {FA83F778-5252-0B80-5555-E69F790322EA}.Debug|Any CPU.Build.0 = Debug|Any CPU - {FA83F778-5252-0B80-5555-E69F790322EA}.Release|Any CPU.ActiveCfg = Release|Any CPU - {FA83F778-5252-0B80-5555-E69F790322EA}.Release|Any CPU.Build.0 = Release|Any CPU - {F3A27846-6DE0-3448-222C-25A273E86B2E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {F3A27846-6DE0-3448-222C-25A273E86B2E}.Debug|Any CPU.Build.0 = Debug|Any CPU - {F3A27846-6DE0-3448-222C-25A273E86B2E}.Release|Any CPU.ActiveCfg = Release|Any CPU - {F3A27846-6DE0-3448-222C-25A273E86B2E}.Release|Any CPU.Build.0 = Release|Any CPU - {C53E0895-879A-D9E6-0A43-24AD17A2F270}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {C53E0895-879A-D9E6-0A43-24AD17A2F270}.Debug|Any CPU.Build.0 = Debug|Any CPU - {C53E0895-879A-D9E6-0A43-24AD17A2F270}.Release|Any CPU.ActiveCfg = Release|Any CPU - {C53E0895-879A-D9E6-0A43-24AD17A2F270}.Release|Any CPU.Build.0 = Release|Any CPU - {0AED303F-69E6-238F-EF80-81985080EDB7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {0AED303F-69E6-238F-EF80-81985080EDB7}.Debug|Any CPU.Build.0 = Debug|Any CPU - {0AED303F-69E6-238F-EF80-81985080EDB7}.Release|Any CPU.ActiveCfg = Release|Any CPU - {0AED303F-69E6-238F-EF80-81985080EDB7}.Release|Any CPU.Build.0 = Release|Any CPU - {2904D288-CE64-A565-2C46-C2E85A96A1EE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {2904D288-CE64-A565-2C46-C2E85A96A1EE}.Debug|Any CPU.Build.0 = Debug|Any CPU - {2904D288-CE64-A565-2C46-C2E85A96A1EE}.Release|Any CPU.ActiveCfg = Release|Any CPU - {2904D288-CE64-A565-2C46-C2E85A96A1EE}.Release|Any CPU.Build.0 = Release|Any CPU - {A6667CC3-B77F-023E-3A67-05F99E9FF46A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {A6667CC3-B77F-023E-3A67-05F99E9FF46A}.Debug|Any CPU.Build.0 = Debug|Any CPU - {A6667CC3-B77F-023E-3A67-05F99E9FF46A}.Release|Any CPU.ActiveCfg = Release|Any CPU - {A6667CC3-B77F-023E-3A67-05F99E9FF46A}.Release|Any CPU.Build.0 = Release|Any CPU - {A26E2816-F787-F76B-1D6C-E086DD3E19CE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {A26E2816-F787-F76B-1D6C-E086DD3E19CE}.Debug|Any CPU.Build.0 = Debug|Any CPU - {A26E2816-F787-F76B-1D6C-E086DD3E19CE}.Release|Any CPU.ActiveCfg = Release|Any CPU - {A26E2816-F787-F76B-1D6C-E086DD3E19CE}.Release|Any CPU.Build.0 = Release|Any CPU - {B3DEC619-67AC-1B5A-4F3E-A1F24C3F6877}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {B3DEC619-67AC-1B5A-4F3E-A1F24C3F6877}.Debug|Any CPU.Build.0 = Debug|Any CPU - {B3DEC619-67AC-1B5A-4F3E-A1F24C3F6877}.Release|Any CPU.ActiveCfg = Release|Any CPU - {B3DEC619-67AC-1B5A-4F3E-A1F24C3F6877}.Release|Any CPU.Build.0 = Release|Any CPU - {90DB65B4-8F6E-FB8E-0281-505AD8BC6BA6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {90DB65B4-8F6E-FB8E-0281-505AD8BC6BA6}.Debug|Any CPU.Build.0 = Debug|Any CPU - {90DB65B4-8F6E-FB8E-0281-505AD8BC6BA6}.Release|Any CPU.ActiveCfg = Release|Any CPU - {90DB65B4-8F6E-FB8E-0281-505AD8BC6BA6}.Release|Any CPU.Build.0 = Release|Any CPU - {059FBB86-DEE6-8207-3F23-2A1A3EC00DEA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {059FBB86-DEE6-8207-3F23-2A1A3EC00DEA}.Debug|Any CPU.Build.0 = Debug|Any CPU - {059FBB86-DEE6-8207-3F23-2A1A3EC00DEA}.Release|Any CPU.ActiveCfg = Release|Any CPU - {059FBB86-DEE6-8207-3F23-2A1A3EC00DEA}.Release|Any CPU.Build.0 = Release|Any CPU - {8BBA3159-C4CC-F685-A28C-7FE6CBD3D2A1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {8BBA3159-C4CC-F685-A28C-7FE6CBD3D2A1}.Debug|Any CPU.Build.0 = Debug|Any CPU - {8BBA3159-C4CC-F685-A28C-7FE6CBD3D2A1}.Release|Any CPU.ActiveCfg = Release|Any CPU - {8BBA3159-C4CC-F685-A28C-7FE6CBD3D2A1}.Release|Any CPU.Build.0 = Release|Any CPU - {632A1F0D-1BA5-C84B-B716-2BE638A92780}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {632A1F0D-1BA5-C84B-B716-2BE638A92780}.Debug|Any CPU.Build.0 = Debug|Any CPU - {632A1F0D-1BA5-C84B-B716-2BE638A92780}.Release|Any CPU.ActiveCfg = Release|Any CPU - {632A1F0D-1BA5-C84B-B716-2BE638A92780}.Release|Any CPU.Build.0 = Release|Any CPU - {9DE7852B-7E2D-257E-B0F1-45D2687854ED}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {9DE7852B-7E2D-257E-B0F1-45D2687854ED}.Debug|Any CPU.Build.0 = Debug|Any CPU - {9DE7852B-7E2D-257E-B0F1-45D2687854ED}.Release|Any CPU.ActiveCfg = Release|Any CPU - {9DE7852B-7E2D-257E-B0F1-45D2687854ED}.Release|Any CPU.Build.0 = Release|Any CPU - {DC2AFC89-C3C8-4E9B-13A7-027EB6386EFA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {DC2AFC89-C3C8-4E9B-13A7-027EB6386EFA}.Debug|Any CPU.Build.0 = Debug|Any CPU - {DC2AFC89-C3C8-4E9B-13A7-027EB6386EFA}.Release|Any CPU.ActiveCfg = Release|Any CPU - {DC2AFC89-C3C8-4E9B-13A7-027EB6386EFA}.Release|Any CPU.Build.0 = Release|Any CPU - {CB296A20-2732-77C1-7F23-27D5BAEDD0C7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {CB296A20-2732-77C1-7F23-27D5BAEDD0C7}.Debug|Any CPU.Build.0 = Debug|Any CPU - {CB296A20-2732-77C1-7F23-27D5BAEDD0C7}.Release|Any CPU.ActiveCfg = Release|Any CPU - {CB296A20-2732-77C1-7F23-27D5BAEDD0C7}.Release|Any CPU.Build.0 = Release|Any CPU - {0DBEC9BA-FE1D-3898-B2C6-E4357DC23E0F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {0DBEC9BA-FE1D-3898-B2C6-E4357DC23E0F}.Debug|Any CPU.Build.0 = Debug|Any CPU - {0DBEC9BA-FE1D-3898-B2C6-E4357DC23E0F}.Release|Any CPU.ActiveCfg = Release|Any CPU - {0DBEC9BA-FE1D-3898-B2C6-E4357DC23E0F}.Release|Any CPU.Build.0 = Release|Any CPU - {A63897D9-9531-989B-7309-E384BCFC2BB9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {A63897D9-9531-989B-7309-E384BCFC2BB9}.Debug|Any CPU.Build.0 = Debug|Any CPU - {A63897D9-9531-989B-7309-E384BCFC2BB9}.Release|Any CPU.ActiveCfg = Release|Any CPU - {A63897D9-9531-989B-7309-E384BCFC2BB9}.Release|Any CPU.Build.0 = Release|Any CPU - {8C594D82-3463-3367-4F06-900AC707753D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {8C594D82-3463-3367-4F06-900AC707753D}.Debug|Any CPU.Build.0 = Debug|Any CPU - {8C594D82-3463-3367-4F06-900AC707753D}.Release|Any CPU.ActiveCfg = Release|Any CPU - {8C594D82-3463-3367-4F06-900AC707753D}.Release|Any CPU.Build.0 = Release|Any CPU - {52F400CD-D473-7A1F-7986-89011CD2A887}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {52F400CD-D473-7A1F-7986-89011CD2A887}.Debug|Any CPU.Build.0 = Debug|Any CPU - {52F400CD-D473-7A1F-7986-89011CD2A887}.Release|Any CPU.ActiveCfg = Release|Any CPU - {52F400CD-D473-7A1F-7986-89011CD2A887}.Release|Any CPU.Build.0 = Release|Any CPU - {9588FBF9-C37E-D16E-2E8F-CFA226EAC01D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {9588FBF9-C37E-D16E-2E8F-CFA226EAC01D}.Debug|Any CPU.Build.0 = Debug|Any CPU - {9588FBF9-C37E-D16E-2E8F-CFA226EAC01D}.Release|Any CPU.ActiveCfg = Release|Any CPU - {9588FBF9-C37E-D16E-2E8F-CFA226EAC01D}.Release|Any CPU.Build.0 = Release|Any CPU - {97998C88-E6E1-D5E2-B632-537B58E00CBF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {97998C88-E6E1-D5E2-B632-537B58E00CBF}.Debug|Any CPU.Build.0 = Debug|Any CPU - {97998C88-E6E1-D5E2-B632-537B58E00CBF}.Release|Any CPU.ActiveCfg = Release|Any CPU - {97998C88-E6E1-D5E2-B632-537B58E00CBF}.Release|Any CPU.Build.0 = Release|Any CPU - {38A9EE9B-6FC8-93BC-0D43-2A906E678D66}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {38A9EE9B-6FC8-93BC-0D43-2A906E678D66}.Debug|Any CPU.Build.0 = Debug|Any CPU - {38A9EE9B-6FC8-93BC-0D43-2A906E678D66}.Release|Any CPU.ActiveCfg = Release|Any CPU - {38A9EE9B-6FC8-93BC-0D43-2A906E678D66}.Release|Any CPU.Build.0 = Release|Any CPU - {19868E2D-7163-2108-1094-F13887C4F070}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {19868E2D-7163-2108-1094-F13887C4F070}.Debug|Any CPU.Build.0 = Debug|Any CPU - {19868E2D-7163-2108-1094-F13887C4F070}.Release|Any CPU.ActiveCfg = Release|Any CPU - {19868E2D-7163-2108-1094-F13887C4F070}.Release|Any CPU.Build.0 = Release|Any CPU - {CC319FC5-F4B1-C3DD-7310-4DAD343E0125}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {CC319FC5-F4B1-C3DD-7310-4DAD343E0125}.Debug|Any CPU.Build.0 = Debug|Any CPU - {CC319FC5-F4B1-C3DD-7310-4DAD343E0125}.Release|Any CPU.ActiveCfg = Release|Any CPU - {CC319FC5-F4B1-C3DD-7310-4DAD343E0125}.Release|Any CPU.Build.0 = Release|Any CPU - {84F711C2-C210-28D2-F0D9-B13733FEE23D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {84F711C2-C210-28D2-F0D9-B13733FEE23D}.Debug|Any CPU.Build.0 = Debug|Any CPU - {84F711C2-C210-28D2-F0D9-B13733FEE23D}.Release|Any CPU.ActiveCfg = Release|Any CPU - {84F711C2-C210-28D2-F0D9-B13733FEE23D}.Release|Any CPU.Build.0 = Release|Any CPU - {CBB14B90-27F9-8DD6-DFC4-3507DBD1FBC6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {CBB14B90-27F9-8DD6-DFC4-3507DBD1FBC6}.Debug|Any CPU.Build.0 = Debug|Any CPU - {CBB14B90-27F9-8DD6-DFC4-3507DBD1FBC6}.Release|Any CPU.ActiveCfg = Release|Any CPU - {CBB14B90-27F9-8DD6-DFC4-3507DBD1FBC6}.Release|Any CPU.Build.0 = Release|Any CPU - {A78EBC0F-C62C-8F56-95C0-330E376242A2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {A78EBC0F-C62C-8F56-95C0-330E376242A2}.Debug|Any CPU.Build.0 = Debug|Any CPU - {A78EBC0F-C62C-8F56-95C0-330E376242A2}.Release|Any CPU.ActiveCfg = Release|Any CPU - {A78EBC0F-C62C-8F56-95C0-330E376242A2}.Release|Any CPU.Build.0 = Release|Any CPU - {6D26FB21-7E48-024B-E5D4-E3F0F31976BB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {6D26FB21-7E48-024B-E5D4-E3F0F31976BB}.Debug|Any CPU.Build.0 = Debug|Any CPU - {6D26FB21-7E48-024B-E5D4-E3F0F31976BB}.Release|Any CPU.ActiveCfg = Release|Any CPU - {6D26FB21-7E48-024B-E5D4-E3F0F31976BB}.Release|Any CPU.Build.0 = Release|Any CPU - {28D91816-206C-576E-1A83-FD98E08C2E3C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {28D91816-206C-576E-1A83-FD98E08C2E3C}.Debug|Any CPU.Build.0 = Debug|Any CPU - {28D91816-206C-576E-1A83-FD98E08C2E3C}.Release|Any CPU.ActiveCfg = Release|Any CPU - {28D91816-206C-576E-1A83-FD98E08C2E3C}.Release|Any CPU.Build.0 = Release|Any CPU - {58D8630F-C0F4-B772-8572-BCC98FF0F0D8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {58D8630F-C0F4-B772-8572-BCC98FF0F0D8}.Debug|Any CPU.Build.0 = Debug|Any CPU - {58D8630F-C0F4-B772-8572-BCC98FF0F0D8}.Release|Any CPU.ActiveCfg = Release|Any CPU - {58D8630F-C0F4-B772-8572-BCC98FF0F0D8}.Release|Any CPU.Build.0 = Release|Any CPU - {7CB7FEA8-8A12-A5D6-0057-AA65DB328617}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {7CB7FEA8-8A12-A5D6-0057-AA65DB328617}.Debug|Any CPU.Build.0 = Debug|Any CPU - {7CB7FEA8-8A12-A5D6-0057-AA65DB328617}.Release|Any CPU.ActiveCfg = Release|Any CPU - {7CB7FEA8-8A12-A5D6-0057-AA65DB328617}.Release|Any CPU.Build.0 = Release|Any CPU - {52698305-D6F8-C13C-0882-48FC37726404}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {52698305-D6F8-C13C-0882-48FC37726404}.Debug|Any CPU.Build.0 = Debug|Any CPU - {52698305-D6F8-C13C-0882-48FC37726404}.Release|Any CPU.ActiveCfg = Release|Any CPU - {52698305-D6F8-C13C-0882-48FC37726404}.Release|Any CPU.Build.0 = Release|Any CPU - {5567139C-0365-B6A0-5DD0-978A09B9F176}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {5567139C-0365-B6A0-5DD0-978A09B9F176}.Debug|Any CPU.Build.0 = Debug|Any CPU - {5567139C-0365-B6A0-5DD0-978A09B9F176}.Release|Any CPU.ActiveCfg = Release|Any CPU - {5567139C-0365-B6A0-5DD0-978A09B9F176}.Release|Any CPU.Build.0 = Release|Any CPU - {256D269B-35EA-F833-2F1D-8E0058908DEE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {256D269B-35EA-F833-2F1D-8E0058908DEE}.Debug|Any CPU.Build.0 = Debug|Any CPU - {256D269B-35EA-F833-2F1D-8E0058908DEE}.Release|Any CPU.ActiveCfg = Release|Any CPU - {256D269B-35EA-F833-2F1D-8E0058908DEE}.Release|Any CPU.Build.0 = Release|Any CPU - {1F372AB9-D8DD-D295-1D5E-CB5D454CBB24}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {1F372AB9-D8DD-D295-1D5E-CB5D454CBB24}.Debug|Any CPU.Build.0 = Debug|Any CPU - {1F372AB9-D8DD-D295-1D5E-CB5D454CBB24}.Release|Any CPU.ActiveCfg = Release|Any CPU - {1F372AB9-D8DD-D295-1D5E-CB5D454CBB24}.Release|Any CPU.Build.0 = Release|Any CPU - {0AF13355-173C-3128-5AFC-D32E540DA3EF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {0AF13355-173C-3128-5AFC-D32E540DA3EF}.Debug|Any CPU.Build.0 = Debug|Any CPU - {0AF13355-173C-3128-5AFC-D32E540DA3EF}.Release|Any CPU.ActiveCfg = Release|Any CPU - {0AF13355-173C-3128-5AFC-D32E540DA3EF}.Release|Any CPU.Build.0 = Release|Any CPU - {1D761F8B-921C-53BF-DCF5-5ABD329EEB0C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {1D761F8B-921C-53BF-DCF5-5ABD329EEB0C}.Debug|Any CPU.Build.0 = Debug|Any CPU - {1D761F8B-921C-53BF-DCF5-5ABD329EEB0C}.Release|Any CPU.ActiveCfg = Release|Any CPU - {1D761F8B-921C-53BF-DCF5-5ABD329EEB0C}.Release|Any CPU.Build.0 = Release|Any CPU - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(NestedProjects) = preSolution - {F310596E-88BB-9E54-885E-21C61971917E} = {5B52EF8A-3661-DCFF-797D-BC4D6AC60BDA} - {D9492ED1-A812-924B-65E4-F518592B49BB} = {F310596E-88BB-9E54-885E-21C61971917E} - {3823DE1E-2ACE-C956-99E1-00DB786D9E1D} = {D9492ED1-A812-924B-65E4-F518592B49BB} - {03DFF14F-7321-1784-D4C7-4E99D4120F48} = {5B52EF8A-3661-DCFF-797D-BC4D6AC60BDA} - {BDD326D6-7616-84F0-B914-74743BFBA520} = {03DFF14F-7321-1784-D4C7-4E99D4120F48} - {EC506DBE-AB6D-492E-786E-8B176021BF2E} = {BDD326D6-7616-84F0-B914-74743BFBA520} - {5AC09D9A-F2A5-9CFA-B3C5-8D25F257651C} = {5B52EF8A-3661-DCFF-797D-BC4D6AC60BDA} - {33B1AE27-692A-1778-48C1-CCEC2B9BC78F} = {5AC09D9A-F2A5-9CFA-B3C5-8D25F257651C} - {018E0E11-1CCE-A2BE-641D-21EE14D2E90D} = {5AC09D9A-F2A5-9CFA-B3C5-8D25F257651C} - {5F27FB4E-CF09-3A6B-F5B4-BF5A709FA609} = {33B1AE27-692A-1778-48C1-CCEC2B9BC78F} - {AB67BDB9-D701-3AC9-9CDF-ECCDCCD8DB6D} = {5AC09D9A-F2A5-9CFA-B3C5-8D25F257651C} - {3F605548-87E2-8A1D-306D-0CE6960B8242} = {AB67BDB9-D701-3AC9-9CDF-ECCDCCD8DB6D} - {45F7FA87-7451-6970-7F6E-F8BAE45E081B} = {AB67BDB9-D701-3AC9-9CDF-ECCDCCD8DB6D} - {C1DCEFBD-12A5-EAAE-632E-8EEB9BE491B6} = {5B52EF8A-3661-DCFF-797D-BC4D6AC60BDA} - {A6928CBA-4D4D-AB2B-CA19-FEE6E73ECE70} = {C1DCEFBD-12A5-EAAE-632E-8EEB9BE491B6} - {F2E6CB0E-DF77-1FAA-582B-62B040DF3848} = {A6928CBA-4D4D-AB2B-CA19-FEE6E73ECE70} - {C494ECBE-DEA5-3576-D2AF-200FF12BC144} = {A6928CBA-4D4D-AB2B-CA19-FEE6E73ECE70} - {64689413-46D7-8499-68A6-B6367ACBC597} = {A6928CBA-4D4D-AB2B-CA19-FEE6E73ECE70} - {157C3671-CA0B-69FA-A7C9-74A1FDA97B99} = {5B52EF8A-3661-DCFF-797D-BC4D6AC60BDA} - {F39E09D6-BF93-B64A-CFE7-2BA92815C0FE} = {157C3671-CA0B-69FA-A7C9-74A1FDA97B99} - {39EFDA5B-F5EE-8212-D5BA-90E1B82013E7} = {F39E09D6-BF93-B64A-CFE7-2BA92815C0FE} - {3B82DBF3-3DAE-EA97-85F4-6DCFA09940DF} = {F39E09D6-BF93-B64A-CFE7-2BA92815C0FE} - {A4FEB09C-E55C-03AE-8FC2-BF6D4F6C9FD7} = {F39E09D6-BF93-B64A-CFE7-2BA92815C0FE} - {67E71A20-7221-A495-BBCA-9B40D5193448} = {F39E09D6-BF93-B64A-CFE7-2BA92815C0FE} - {3FC9AD6C-AF2C-E557-4D34-8E52BA6AD9E8} = {F39E09D6-BF93-B64A-CFE7-2BA92815C0FE} - {6844B539-C2A3-9D4F-139D-9D533BCABADA} = {F39E09D6-BF93-B64A-CFE7-2BA92815C0FE} - {4263AA71-0335-3F44-9A9B-423C3A3D05E6} = {F39E09D6-BF93-B64A-CFE7-2BA92815C0FE} - {F1B1DB47-D2D7-59CB-679B-23E4928E8328} = {F39E09D6-BF93-B64A-CFE7-2BA92815C0FE} - {BC35DE94-4F04-3436-27A3-F11647FEDD5C} = {F39E09D6-BF93-B64A-CFE7-2BA92815C0FE} - {864C8B80-771A-0C15-30A5-558F99006E0D} = {F39E09D6-BF93-B64A-CFE7-2BA92815C0FE} - {603E7A23-1D6B-D3A9-B0E6-3E332B13ED5C} = {F39E09D6-BF93-B64A-CFE7-2BA92815C0FE} - {D2F7E58B-47D4-5205-D917-144CA1CFF4F1} = {F39E09D6-BF93-B64A-CFE7-2BA92815C0FE} - {1DCF4EBB-DBC4-752C-13D4-D1EECE4E8907} = {F39E09D6-BF93-B64A-CFE7-2BA92815C0FE} - {1B37A859-E733-60CB-4806-1A24B6F10E05} = {F39E09D6-BF93-B64A-CFE7-2BA92815C0FE} - {F2B58F4E-6F28-A25F-5BFB-CDEBAD6B9A3E} = {F39E09D6-BF93-B64A-CFE7-2BA92815C0FE} - {C4A90603-BE42-0044-CAB4-3EB910AD51A5} = {5B52EF8A-3661-DCFF-797D-BC4D6AC60BDA} - {054761F9-16D3-B2F8-6F4D-EFC2248805CD} = {C4A90603-BE42-0044-CAB4-3EB910AD51A5} - {B54CE64C-4167-1DD1-B7D6-2FD7A5AEF715} = {C4A90603-BE42-0044-CAB4-3EB910AD51A5} - {8E6B774C-CC4E-CE7C-AD4B-8AF7C92889A6} = {5B52EF8A-3661-DCFF-797D-BC4D6AC60BDA} - {BC12ED55-6015-7C8B-8384-B39CE93C76D6} = {8E6B774C-CC4E-CE7C-AD4B-8AF7C92889A6} - {FF70543D-AFF9-1D38-4950-4F8EE18D60BB} = {8E6B774C-CC4E-CE7C-AD4B-8AF7C92889A6} - {831265B0-8896-9C95-3488-E12FD9F6DC53} = {FF70543D-AFF9-1D38-4950-4F8EE18D60BB} - {316BBD0A-04D2-85C9-52EA-7993CC6C8930} = {5B52EF8A-3661-DCFF-797D-BC4D6AC60BDA} - {9D6AB85A-85EA-D85A-5566-A121D34016E6} = {316BBD0A-04D2-85C9-52EA-7993CC6C8930} - {FC018E5B-1E2F-DE19-1E97-0C845058C469} = {5B52EF8A-3661-DCFF-797D-BC4D6AC60BDA} - {1BE5B76C-B486-560B-6CB2-44C6537249AA} = {FC018E5B-1E2F-DE19-1E97-0C845058C469} - {F4F1CBE2-1CDD-CAA4-41F0-266DB4677C05} = {1BE5B76C-B486-560B-6CB2-44C6537249AA} - {5896C4B3-31D1-1EDD-11D0-C46DB178DC12} = {5B52EF8A-3661-DCFF-797D-BC4D6AC60BDA} - {D4D193A8-47D7-0B1A-1327-F9C580E7AD07} = {5896C4B3-31D1-1EDD-11D0-C46DB178DC12} - {69C91AE6-4555-7B2C-AD32-F7F11B9C605A} = {D4D193A8-47D7-0B1A-1327-F9C580E7AD07} - {C9BCCEDF-7B8A-BCD8-A6B4-75EB25689FE8} = {D4D193A8-47D7-0B1A-1327-F9C580E7AD07} - {9F30DC58-7747-31D8-2403-D7D0F5454C87} = {D4D193A8-47D7-0B1A-1327-F9C580E7AD07} - {336213F7-1241-D268-8EA5-1C73F0040714} = {D4D193A8-47D7-0B1A-1327-F9C580E7AD07} - {5693F73D-6707-6F86-65D6-654023205615} = {D4D193A8-47D7-0B1A-1327-F9C580E7AD07} - {593308D7-2453-DC66-4151-E983E4B3F422} = {D4D193A8-47D7-0B1A-1327-F9C580E7AD07} - {B24B448A-28D8-778E-DCC1-FCF4A0916DF5} = {5B52EF8A-3661-DCFF-797D-BC4D6AC60BDA} - {BF1AF1AB-97A8-BD70-63F2-E028DE8EE90F} = {B24B448A-28D8-778E-DCC1-FCF4A0916DF5} - {3DB6D7AE-8187-5324-1208-D6090D5324C6} = {BF1AF1AB-97A8-BD70-63F2-E028DE8EE90F} - {3247EE0D-B3E9-9C11-B0AE-FE719410390B} = {5B52EF8A-3661-DCFF-797D-BC4D6AC60BDA} - {CD7C09DA-FEC8-2CC5-D00C-E525638DFF4A} = {3247EE0D-B3E9-9C11-B0AE-FE719410390B} - {79B10804-91E9-972E-1913-EE0F0B11663E} = {CD7C09DA-FEC8-2CC5-D00C-E525638DFF4A} - {1345DD29-BB3A-FB5F-4B3D-E29F6045A27A} = {5B52EF8A-3661-DCFF-797D-BC4D6AC60BDA} - {9C2DD234-FA33-FDB6-86F0-EF9B75A13450} = {1345DD29-BB3A-FB5F-4B3D-E29F6045A27A} - {79E122F4-2325-3E92-438E-5825A307B594} = {1345DD29-BB3A-FB5F-4B3D-E29F6045A27A} - {538E2D98-5325-3F54-BE74-EFE5FC1ECBD8} = {1345DD29-BB3A-FB5F-4B3D-E29F6045A27A} - {66557252-B5C4-664B-D807-07018C627474} = {1345DD29-BB3A-FB5F-4B3D-E29F6045A27A} - {7203223D-FF02-7BEB-2798-D1639ACC01C4} = {1345DD29-BB3A-FB5F-4B3D-E29F6045A27A} - {5AC9EE40-1881-5F8A-46A2-2C303950D3C8} = {1345DD29-BB3A-FB5F-4B3D-E29F6045A27A} - {3C69853C-90E3-D889-1960-3B9229882590} = {1345DD29-BB3A-FB5F-4B3D-E29F6045A27A} - {643E4D4C-BC96-A37F-E0EC-488127F0B127} = {1345DD29-BB3A-FB5F-4B3D-E29F6045A27A} - {6F2CA7F5-3E7C-C61B-94E6-E7DD1227B5B1} = {1345DD29-BB3A-FB5F-4B3D-E29F6045A27A} - {F04B7DBB-77A5-C978-B2DE-8C189A32AA72} = {1345DD29-BB3A-FB5F-4B3D-E29F6045A27A} - {7C72F22A-20FF-DF5B-9191-6DFD0D497DB2} = {1345DD29-BB3A-FB5F-4B3D-E29F6045A27A} - {C896CC0A-F5E6-9AA4-C582-E691441F8D32} = {1345DD29-BB3A-FB5F-4B3D-E29F6045A27A} - {0AA3A418-AB45-CCA4-46D4-EEBFE011FECA} = {1345DD29-BB3A-FB5F-4B3D-E29F6045A27A} - {225D9926-4AE8-E539-70AD-8698E688F271} = {1345DD29-BB3A-FB5F-4B3D-E29F6045A27A} - {D6E8E69C-F721-BBCB-8C39-9716D53D72AD} = {1345DD29-BB3A-FB5F-4B3D-E29F6045A27A} - {589A43FD-8213-E9E3-6CFF-9CBA72D53E98} = {1345DD29-BB3A-FB5F-4B3D-E29F6045A27A} - {2BACF7E3-1278-FE99-8343-8221E6FBA9DE} = {1345DD29-BB3A-FB5F-4B3D-E29F6045A27A} - {75E47125-E4D7-8482-F1A4-726564970864} = {1345DD29-BB3A-FB5F-4B3D-E29F6045A27A} - {FCD529E0-DD17-6587-B29C-12D425C0AD0C} = {1345DD29-BB3A-FB5F-4B3D-E29F6045A27A} - {61B23570-4F2D-B060-BE1F-37995682E494} = {1345DD29-BB3A-FB5F-4B3D-E29F6045A27A} - {1182764D-2143-EEF0-9270-3DCE392F5D06} = {1345DD29-BB3A-FB5F-4B3D-E29F6045A27A} - {772B02B5-6280-E1D4-3E2E-248D0455C2FB} = {1345DD29-BB3A-FB5F-4B3D-E29F6045A27A} - {48F90289-938C-CCA7-B60F-D2143E7C9A69} = {1345DD29-BB3A-FB5F-4B3D-E29F6045A27A} - {E69FA1A0-6D1B-A6E4-2DC0-8F4C5F21BF04} = {1345DD29-BB3A-FB5F-4B3D-E29F6045A27A} - {083067CF-CE89-EF39-9BD3-4741919E26F3} = {1345DD29-BB3A-FB5F-4B3D-E29F6045A27A} - {A7542386-71EB-4F34-E1CE-27D399325955} = {1345DD29-BB3A-FB5F-4B3D-E29F6045A27A} - {90659617-4DF7-809A-4E5B-29BB5A98E8E1} = {5B52EF8A-3661-DCFF-797D-BC4D6AC60BDA} - {AB8B269C-5A2A-A4B8-0488-B5F81E55B4D9} = {90659617-4DF7-809A-4E5B-29BB5A98E8E1} - {A527DABC-AA87-7C64-8056-4627531A9960} = {AB8B269C-5A2A-A4B8-0488-B5F81E55B4D9} - {CEDC2447-F717-3C95-7E08-F214D575A7B7} = {AB8B269C-5A2A-A4B8-0488-B5F81E55B4D9} - {52220F70-4EAA-D93F-752B-CD431AAEEDDB} = {945F81BC-6A17-B466-15B3-47E17BBFFEEE} - {C0C58E4B-9B24-29EA-9585-4BB462666824} = {678BFC83-F74C-CD21-AFE5-9F1FD29B4092} - {24D80D5F-0A63-7924-B7C3-79A2772A28DF} = {569894C1-998D-B530-0EAA-AE633B3BC297} - {8A3083F4-FBB0-6972-9FB5-FE3D05488CD6} = {F3E2E624-EBEF-D7C4-007E-1297E7001D38} - {13E7A80F-191B-0B12-4C7F-A1CA9808DD65} = {94E5B89C-8E1D-757B-350E-821DBEADD75D} - {A82DBB41-8BF0-440B-1BD1-611A2521DAA0} = {9475E1E8-B4B3-EFFC-3B43-71F90D2021F2} - {8C96DAFC-3A63-EB7B-EA8F-07A63817204D} = {22A9ABBF-F2DA-7E3C-B6E2-05A8AE8A24F5} - {AD31623A-BC43-52C2-D906-AC1D8784A541} = {3823DE1E-2ACE-C956-99E1-00DB786D9E1D} - {776E2142-804F-03B9-C804-D061D64C6092} = {EC506DBE-AB6D-492E-786E-8B176021BF2E} - {5B4DF41E-C8CC-2606-FA2D-967118BD3C59} = {5F27FB4E-CF09-3A6B-F5B4-BF5A709FA609} - {3D8C5A6C-462D-7487-5BD0-A3EF6B657EB6} = {018E0E11-1CCE-A2BE-641D-21EE14D2E90D} - {2609BC1A-6765-29BE-78CC-C0F1D2814F10} = {3F605548-87E2-8A1D-306D-0CE6960B8242} - {C6822231-A4F4-9E69-6CE2-4FDB3E81C728} = {45F7FA87-7451-6970-7F6E-F8BAE45E081B} - {55D9B653-FB76-FCE8-1A3C-67B1BEDEC214} = {F2E6CB0E-DF77-1FAA-582B-62B040DF3848} - {DE5BF139-1E5C-D6EA-4FAA-661EF353A194} = {C494ECBE-DEA5-3576-D2AF-200FF12BC144} - {335E62C0-9E69-A952-680B-753B1B17C6D0} = {9C2DD234-FA33-FDB6-86F0-EF9B75A13450} - {97F94029-5419-6187-5A63-5C8FD9232FAE} = {64689413-46D7-8499-68A6-B6367ACBC597} - {AF9E7F02-25AD-3540-18D7-F6A4F8BA5A60} = {79E122F4-2325-3E92-438E-5825A307B594} - {AB6AE2B6-8D6B-2D9F-2A88-7C596C59F4FC} = {39EFDA5B-F5EE-8212-D5BA-90E1B82013E7} - {375F5AD0-F7EE-1782-7B34-E181CDB61B9F} = {3B82DBF3-3DAE-EA97-85F4-6DCFA09940DF} - {C117E9AF-D7B8-D4E2-4262-84B6321A9F5C} = {A4FEB09C-E55C-03AE-8FC2-BF6D4F6C9FD7} - {D492EFDB-294B-ABA2-FAFB-EAEE6F3DCB52} = {67E71A20-7221-A495-BBCA-9B40D5193448} - {9D0C51AF-D1AB-9E12-0B16-A4AA974FAAB5} = {3FC9AD6C-AF2C-E557-4D34-8E52BA6AD9E8} - {BA45605A-1CCE-6B0C-489D-C113915B243F} = {6844B539-C2A3-9D4F-139D-9D533BCABADA} - {9D31FC8A-2A69-B78A-D3E5-4F867B16D971} = {4263AA71-0335-3F44-9A9B-423C3A3D05E6} - {92268008-FBB0-C7AD-ECC2-7B75BED9F5E1} = {F1B1DB47-D2D7-59CB-679B-23E4928E8328} - {8DCCAF70-D364-4C8B-4E90-AF65091DE0C5} = {BC35DE94-4F04-3436-27A3-F11647FEDD5C} - {7828C164-DD01-2809-CCB3-364486834F60} = {864C8B80-771A-0C15-30A5-558F99006E0D} - {DE95E7B2-0937-A980-441F-829E023BC43E} = {603E7A23-1D6B-D3A9-B0E6-3E332B13ED5C} - {91D69463-23E2-E2C7-AA7E-A78B13CED620} = {D2F7E58B-47D4-5205-D917-144CA1CFF4F1} - {34EFF636-81A7-8DF6-7CC9-4DA784BAC7F3} = {1DCF4EBB-DBC4-752C-13D4-D1EECE4E8907} - {5DCF16A8-97C6-2CB4-6A63-0370239039EB} = {1B37A859-E733-60CB-4806-1A24B6F10E05} - {EB093C48-CDAC-106B-1196-AE34809B34C0} = {F2B58F4E-6F28-A25F-5BFB-CDEBAD6B9A3E} - {370A79BD-AAB3-B833-2B06-A28B3A19E153} = {A527DABC-AA87-7C64-8056-4627531A9960} - {92C62F7B-8028-6EE1-B71B-F45F459B8E97} = {538E2D98-5325-3F54-BE74-EFE5FC1ECBD8} - {F664A948-E352-5808-E780-77A03F19E93E} = {66557252-B5C4-664B-D807-07018C627474} - {FA83F778-5252-0B80-5555-E69F790322EA} = {7203223D-FF02-7BEB-2798-D1639ACC01C4} - {F3A27846-6DE0-3448-222C-25A273E86B2E} = {5AC9EE40-1881-5F8A-46A2-2C303950D3C8} - {C53E0895-879A-D9E6-0A43-24AD17A2F270} = {3C69853C-90E3-D889-1960-3B9229882590} - {0AED303F-69E6-238F-EF80-81985080EDB7} = {643E4D4C-BC96-A37F-E0EC-488127F0B127} - {2904D288-CE64-A565-2C46-C2E85A96A1EE} = {6F2CA7F5-3E7C-C61B-94E6-E7DD1227B5B1} - {A6667CC3-B77F-023E-3A67-05F99E9FF46A} = {F04B7DBB-77A5-C978-B2DE-8C189A32AA72} - {A26E2816-F787-F76B-1D6C-E086DD3E19CE} = {7C72F22A-20FF-DF5B-9191-6DFD0D497DB2} - {B3DEC619-67AC-1B5A-4F3E-A1F24C3F6877} = {C896CC0A-F5E6-9AA4-C582-E691441F8D32} - {90DB65B4-8F6E-FB8E-0281-505AD8BC6BA6} = {0AA3A418-AB45-CCA4-46D4-EEBFE011FECA} - {059FBB86-DEE6-8207-3F23-2A1A3EC00DEA} = {225D9926-4AE8-E539-70AD-8698E688F271} - {8BBA3159-C4CC-F685-A28C-7FE6CBD3D2A1} = {D6E8E69C-F721-BBCB-8C39-9716D53D72AD} - {632A1F0D-1BA5-C84B-B716-2BE638A92780} = {589A43FD-8213-E9E3-6CFF-9CBA72D53E98} - {9DE7852B-7E2D-257E-B0F1-45D2687854ED} = {2BACF7E3-1278-FE99-8343-8221E6FBA9DE} - {DC2AFC89-C3C8-4E9B-13A7-027EB6386EFA} = {75E47125-E4D7-8482-F1A4-726564970864} - {CB296A20-2732-77C1-7F23-27D5BAEDD0C7} = {054761F9-16D3-B2F8-6F4D-EFC2248805CD} - {0DBEC9BA-FE1D-3898-B2C6-E4357DC23E0F} = {B54CE64C-4167-1DD1-B7D6-2FD7A5AEF715} - {A63897D9-9531-989B-7309-E384BCFC2BB9} = {FCD529E0-DD17-6587-B29C-12D425C0AD0C} - {8C594D82-3463-3367-4F06-900AC707753D} = {61B23570-4F2D-B060-BE1F-37995682E494} - {52F400CD-D473-7A1F-7986-89011CD2A887} = {CEDC2447-F717-3C95-7E08-F214D575A7B7} - {9588FBF9-C37E-D16E-2E8F-CFA226EAC01D} = {1182764D-2143-EEF0-9270-3DCE392F5D06} - {97998C88-E6E1-D5E2-B632-537B58E00CBF} = {F4F1CBE2-1CDD-CAA4-41F0-266DB4677C05} - {38A9EE9B-6FC8-93BC-0D43-2A906E678D66} = {772B02B5-6280-E1D4-3E2E-248D0455C2FB} - {19868E2D-7163-2108-1094-F13887C4F070} = {831265B0-8896-9C95-3488-E12FD9F6DC53} - {CC319FC5-F4B1-C3DD-7310-4DAD343E0125} = {BC12ED55-6015-7C8B-8384-B39CE93C76D6} - {84F711C2-C210-28D2-F0D9-B13733FEE23D} = {48F90289-938C-CCA7-B60F-D2143E7C9A69} - {CBB14B90-27F9-8DD6-DFC4-3507DBD1FBC6} = {E69FA1A0-6D1B-A6E4-2DC0-8F4C5F21BF04} - {A78EBC0F-C62C-8F56-95C0-330E376242A2} = {9D6AB85A-85EA-D85A-5566-A121D34016E6} - {6D26FB21-7E48-024B-E5D4-E3F0F31976BB} = {083067CF-CE89-EF39-9BD3-4741919E26F3} - {28D91816-206C-576E-1A83-FD98E08C2E3C} = {69C91AE6-4555-7B2C-AD32-F7F11B9C605A} - {58D8630F-C0F4-B772-8572-BCC98FF0F0D8} = {C9BCCEDF-7B8A-BCD8-A6B4-75EB25689FE8} - {7CB7FEA8-8A12-A5D6-0057-AA65DB328617} = {9F30DC58-7747-31D8-2403-D7D0F5454C87} - {52698305-D6F8-C13C-0882-48FC37726404} = {336213F7-1241-D268-8EA5-1C73F0040714} - {5567139C-0365-B6A0-5DD0-978A09B9F176} = {5693F73D-6707-6F86-65D6-654023205615} - {256D269B-35EA-F833-2F1D-8E0058908DEE} = {593308D7-2453-DC66-4151-E983E4B3F422} - {1F372AB9-D8DD-D295-1D5E-CB5D454CBB24} = {3DB6D7AE-8187-5324-1208-D6090D5324C6} - {0AF13355-173C-3128-5AFC-D32E540DA3EF} = {79B10804-91E9-972E-1913-EE0F0B11663E} - {1D761F8B-921C-53BF-DCF5-5ABD329EEB0C} = {A7542386-71EB-4F34-E1CE-27D399325955} - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {180AF072-9F83-5251-AFF7-C5FF574F0925} - EndGlobalSection -EndGlobal + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.0.31903.59 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "FixtureUpdater", "FixtureUpdater", "{945F81BC-6A17-B466-15B3-47E17BBFFEEE}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "LanguageAnalyzerSmoke", "LanguageAnalyzerSmoke", "{678BFC83-F74C-CD21-AFE5-9F1FD29B4092}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "NotifySmokeCheck", "NotifySmokeCheck", "{569894C1-998D-B530-0EAA-AE633B3BC297}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "PolicyDslValidator", "PolicyDslValidator", "{F3E2E624-EBEF-D7C4-007E-1297E7001D38}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "PolicySchemaExporter", "PolicySchemaExporter", "{94E5B89C-8E1D-757B-350E-821DBEADD75D}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "PolicySimulationSmoke", "PolicySimulationSmoke", "{9475E1E8-B4B3-EFFC-3B43-71F90D2021F2}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "RustFsMigrator", "RustFsMigrator", "{22A9ABBF-F2DA-7E3C-B6E2-05A8AE8A24F5}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "__External", "__External", "{5B52EF8A-3661-DCFF-797D-BC4D6AC60BDA}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "AirGap", "AirGap", "{F310596E-88BB-9E54-885E-21C61971917E}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.AirGap.Policy", "StellaOps.AirGap.Policy", "{D9492ED1-A812-924B-65E4-F518592B49BB}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.AirGap.Policy", "StellaOps.AirGap.Policy", "{3823DE1E-2ACE-C956-99E1-00DB786D9E1D}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Aoc", "Aoc", "{03DFF14F-7321-1784-D4C7-4E99D4120F48}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "__Libraries", "__Libraries", "{BDD326D6-7616-84F0-B914-74743BFBA520}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Aoc", "StellaOps.Aoc", "{EC506DBE-AB6D-492E-786E-8B176021BF2E}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Attestor", "Attestor", "{5AC09D9A-F2A5-9CFA-B3C5-8D25F257651C}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Attestor", "StellaOps.Attestor", "{33B1AE27-692A-1778-48C1-CCEC2B9BC78F}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Attestor.Envelope", "StellaOps.Attestor.Envelope", "{018E0E11-1CCE-A2BE-641D-21EE14D2E90D}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Attestor.Core", "StellaOps.Attestor.Core", "{5F27FB4E-CF09-3A6B-F5B4-BF5A709FA609}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "__Libraries", "__Libraries", "{AB67BDB9-D701-3AC9-9CDF-ECCDCCD8DB6D}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Attestor.GraphRoot", "StellaOps.Attestor.GraphRoot", "{3F605548-87E2-8A1D-306D-0CE6960B8242}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Attestor.ProofChain", "StellaOps.Attestor.ProofChain", "{45F7FA87-7451-6970-7F6E-F8BAE45E081B}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Authority", "Authority", "{C1DCEFBD-12A5-EAAE-632E-8EEB9BE491B6}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Authority", "StellaOps.Authority", "{A6928CBA-4D4D-AB2B-CA19-FEE6E73ECE70}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Auth.Abstractions", "StellaOps.Auth.Abstractions", "{F2E6CB0E-DF77-1FAA-582B-62B040DF3848}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Auth.Client", "StellaOps.Auth.Client", "{C494ECBE-DEA5-3576-D2AF-200FF12BC144}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Authority.Plugins.Abstractions", "StellaOps.Authority.Plugins.Abstractions", "{64689413-46D7-8499-68A6-B6367ACBC597}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Concelier", "Concelier", "{157C3671-CA0B-69FA-A7C9-74A1FDA97B99}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "__Libraries", "__Libraries", "{F39E09D6-BF93-B64A-CFE7-2BA92815C0FE}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Concelier.Cache.Valkey", "StellaOps.Concelier.Cache.Valkey", "{39EFDA5B-F5EE-8212-D5BA-90E1B82013E7}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Concelier.Connector.Common", "StellaOps.Concelier.Connector.Common", "{3B82DBF3-3DAE-EA97-85F4-6DCFA09940DF}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Concelier.Connector.Ghsa", "StellaOps.Concelier.Connector.Ghsa", "{A4FEB09C-E55C-03AE-8FC2-BF6D4F6C9FD7}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Concelier.Connector.Nvd", "StellaOps.Concelier.Connector.Nvd", "{67E71A20-7221-A495-BBCA-9B40D5193448}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Concelier.Connector.Osv", "StellaOps.Concelier.Connector.Osv", "{3FC9AD6C-AF2C-E557-4D34-8E52BA6AD9E8}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Concelier.Core", "StellaOps.Concelier.Core", "{6844B539-C2A3-9D4F-139D-9D533BCABADA}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Concelier.Interest", "StellaOps.Concelier.Interest", "{4263AA71-0335-3F44-9A9B-423C3A3D05E6}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Concelier.Merge", "StellaOps.Concelier.Merge", "{F1B1DB47-D2D7-59CB-679B-23E4928E8328}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Concelier.Models", "StellaOps.Concelier.Models", "{BC35DE94-4F04-3436-27A3-F11647FEDD5C}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Concelier.Normalization", "StellaOps.Concelier.Normalization", "{864C8B80-771A-0C15-30A5-558F99006E0D}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Concelier.Persistence", "StellaOps.Concelier.Persistence", "{603E7A23-1D6B-D3A9-B0E6-3E332B13ED5C}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Concelier.ProofService", "StellaOps.Concelier.ProofService", "{D2F7E58B-47D4-5205-D917-144CA1CFF4F1}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Concelier.RawModels", "StellaOps.Concelier.RawModels", "{1DCF4EBB-DBC4-752C-13D4-D1EECE4E8907}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Concelier.SbomIntegration", "StellaOps.Concelier.SbomIntegration", "{1B37A859-E733-60CB-4806-1A24B6F10E05}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Concelier.SourceIntel", "StellaOps.Concelier.SourceIntel", "{F2B58F4E-6F28-A25F-5BFB-CDEBAD6B9A3E}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Feedser", "Feedser", "{C4A90603-BE42-0044-CAB4-3EB910AD51A5}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Feedser.BinaryAnalysis", "StellaOps.Feedser.BinaryAnalysis", "{054761F9-16D3-B2F8-6F4D-EFC2248805CD}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Feedser.Core", "StellaOps.Feedser.Core", "{B54CE64C-4167-1DD1-B7D6-2FD7A5AEF715}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Policy", "Policy", "{8E6B774C-CC4E-CE7C-AD4B-8AF7C92889A6}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Policy.RiskProfile", "StellaOps.Policy.RiskProfile", "{BC12ED55-6015-7C8B-8384-B39CE93C76D6}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "__Libraries", "__Libraries", "{FF70543D-AFF9-1D38-4950-4F8EE18D60BB}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Policy", "StellaOps.Policy", "{831265B0-8896-9C95-3488-E12FD9F6DC53}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Provenance", "Provenance", "{316BBD0A-04D2-85C9-52EA-7993CC6C8930}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Provenance.Attestation", "StellaOps.Provenance.Attestation", "{9D6AB85A-85EA-D85A-5566-A121D34016E6}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Router", "Router", "{FC018E5B-1E2F-DE19-1E97-0C845058C469}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "__Libraries", "__Libraries", "{1BE5B76C-B486-560B-6CB2-44C6537249AA}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Messaging", "StellaOps.Messaging", "{F4F1CBE2-1CDD-CAA4-41F0-266DB4677C05}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Scanner", "Scanner", "{5896C4B3-31D1-1EDD-11D0-C46DB178DC12}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "__Libraries", "__Libraries", "{D4D193A8-47D7-0B1A-1327-F9C580E7AD07}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Scanner.Analyzers.Lang", "StellaOps.Scanner.Analyzers.Lang", "{69C91AE6-4555-7B2C-AD32-F7F11B9C605A}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Scanner.Core", "StellaOps.Scanner.Core", "{C9BCCEDF-7B8A-BCD8-A6B4-75EB25689FE8}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Scanner.ProofSpine", "StellaOps.Scanner.ProofSpine", "{9F30DC58-7747-31D8-2403-D7D0F5454C87}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Scanner.Surface.Env", "StellaOps.Scanner.Surface.Env", "{336213F7-1241-D268-8EA5-1C73F0040714}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Scanner.Surface.FS", "StellaOps.Scanner.Surface.FS", "{5693F73D-6707-6F86-65D6-654023205615}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Scanner.Surface.Secrets", "StellaOps.Scanner.Surface.Secrets", "{593308D7-2453-DC66-4151-E983E4B3F422}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Scheduler", "Scheduler", "{B24B448A-28D8-778E-DCC1-FCF4A0916DF5}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "__Libraries", "__Libraries", "{BF1AF1AB-97A8-BD70-63F2-E028DE8EE90F}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Scheduler.Models", "StellaOps.Scheduler.Models", "{3DB6D7AE-8187-5324-1208-D6090D5324C6}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Signer", "Signer", "{3247EE0D-B3E9-9C11-B0AE-FE719410390B}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Signer", "StellaOps.Signer", "{CD7C09DA-FEC8-2CC5-D00C-E525638DFF4A}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Signer.Core", "StellaOps.Signer.Core", "{79B10804-91E9-972E-1913-EE0F0B11663E}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "__Libraries", "__Libraries", "{1345DD29-BB3A-FB5F-4B3D-E29F6045A27A}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Auth.Security", "StellaOps.Auth.Security", "{9C2DD234-FA33-FDB6-86F0-EF9B75A13450}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Canonical.Json", "StellaOps.Canonical.Json", "{79E122F4-2325-3E92-438E-5825A307B594}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Configuration", "StellaOps.Configuration", "{538E2D98-5325-3F54-BE74-EFE5FC1ECBD8}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Cryptography", "StellaOps.Cryptography", "{66557252-B5C4-664B-D807-07018C627474}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Cryptography.DependencyInjection", "StellaOps.Cryptography.DependencyInjection", "{7203223D-FF02-7BEB-2798-D1639ACC01C4}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Cryptography.Kms", "StellaOps.Cryptography.Kms", "{5AC9EE40-1881-5F8A-46A2-2C303950D3C8}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Cryptography.Plugin.CryptoPro", "StellaOps.Cryptography.Plugin.CryptoPro", "{3C69853C-90E3-D889-1960-3B9229882590}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Cryptography.Plugin.OpenSslGost", "StellaOps.Cryptography.Plugin.OpenSslGost", "{643E4D4C-BC96-A37F-E0EC-488127F0B127}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Cryptography.Plugin.Pkcs11Gost", "StellaOps.Cryptography.Plugin.Pkcs11Gost", "{6F2CA7F5-3E7C-C61B-94E6-E7DD1227B5B1}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Cryptography.Plugin.PqSoft", "StellaOps.Cryptography.Plugin.PqSoft", "{F04B7DBB-77A5-C978-B2DE-8C189A32AA72}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Cryptography.Plugin.SimRemote", "StellaOps.Cryptography.Plugin.SimRemote", "{7C72F22A-20FF-DF5B-9191-6DFD0D497DB2}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Cryptography.Plugin.SmRemote", "StellaOps.Cryptography.Plugin.SmRemote", "{C896CC0A-F5E6-9AA4-C582-E691441F8D32}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Cryptography.Plugin.SmSoft", "StellaOps.Cryptography.Plugin.SmSoft", "{0AA3A418-AB45-CCA4-46D4-EEBFE011FECA}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Cryptography.Plugin.WineCsp", "StellaOps.Cryptography.Plugin.WineCsp", "{225D9926-4AE8-E539-70AD-8698E688F271}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Cryptography.PluginLoader", "StellaOps.Cryptography.PluginLoader", "{D6E8E69C-F721-BBCB-8C39-9716D53D72AD}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.DependencyInjection", "StellaOps.DependencyInjection", "{589A43FD-8213-E9E3-6CFF-9CBA72D53E98}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Evidence.Bundle", "StellaOps.Evidence.Bundle", "{2BACF7E3-1278-FE99-8343-8221E6FBA9DE}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Evidence.Core", "StellaOps.Evidence.Core", "{75E47125-E4D7-8482-F1A4-726564970864}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Infrastructure.EfCore", "StellaOps.Infrastructure.EfCore", "{FCD529E0-DD17-6587-B29C-12D425C0AD0C}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Infrastructure.Postgres", "StellaOps.Infrastructure.Postgres", "{61B23570-4F2D-B060-BE1F-37995682E494}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Ingestion.Telemetry", "StellaOps.Ingestion.Telemetry", "{1182764D-2143-EEF0-9270-3DCE392F5D06}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Plugin", "StellaOps.Plugin", "{772B02B5-6280-E1D4-3E2E-248D0455C2FB}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Provcache", "StellaOps.Provcache", "{48F90289-938C-CCA7-B60F-D2143E7C9A69}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Provenance", "StellaOps.Provenance", "{E69FA1A0-6D1B-A6E4-2DC0-8F4C5F21BF04}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Replay.Core", "StellaOps.Replay.Core", "{083067CF-CE89-EF39-9BD3-4741919E26F3}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.VersionComparison", "StellaOps.VersionComparison", "{A7542386-71EB-4F34-E1CE-27D399325955}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "__Tests", "__Tests", "{90659617-4DF7-809A-4E5B-29BB5A98E8E1}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "__Libraries", "__Libraries", "{AB8B269C-5A2A-A4B8-0488-B5F81E55B4D9}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Concelier.Testing", "StellaOps.Concelier.Testing", "{A527DABC-AA87-7C64-8056-4627531A9960}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "StellaOps.Infrastructure.Postgres.Testing", "StellaOps.Infrastructure.Postgres.Testing", "{CEDC2447-F717-3C95-7E08-F214D575A7B7}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FixtureUpdater", "FixtureUpdater\FixtureUpdater.csproj", "{52220F70-4EAA-D93F-752B-CD431AAEEDDB}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LanguageAnalyzerSmoke", "LanguageAnalyzerSmoke\LanguageAnalyzerSmoke.csproj", "{C0C58E4B-9B24-29EA-9585-4BB462666824}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NotifySmokeCheck", "NotifySmokeCheck\NotifySmokeCheck.csproj", "{24D80D5F-0A63-7924-B7C3-79A2772A28DF}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PolicyDslValidator", "PolicyDslValidator\PolicyDslValidator.csproj", "{8A3083F4-FBB0-6972-9FB5-FE3D05488CD6}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PolicySchemaExporter", "PolicySchemaExporter\PolicySchemaExporter.csproj", "{13E7A80F-191B-0B12-4C7F-A1CA9808DD65}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PolicySimulationSmoke", "PolicySimulationSmoke\PolicySimulationSmoke.csproj", "{A82DBB41-8BF0-440B-1BD1-611A2521DAA0}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RustFsMigrator", "RustFsMigrator\RustFsMigrator.csproj", "{8C96DAFC-3A63-EB7B-EA8F-07A63817204D}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.AirGap.Policy", "E:\dev\git.stella-ops.org\src\AirGap\StellaOps.AirGap.Policy\StellaOps.AirGap.Policy\StellaOps.AirGap.Policy.csproj", "{AD31623A-BC43-52C2-D906-AC1D8784A541}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Aoc", "E:\dev\git.stella-ops.org\src\Aoc\__Libraries\StellaOps.Aoc\StellaOps.Aoc.csproj", "{776E2142-804F-03B9-C804-D061D64C6092}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Attestor.Core", "E:\dev\git.stella-ops.org\src\Attestor\StellaOps.Attestor\StellaOps.Attestor.Core\StellaOps.Attestor.Core.csproj", "{5B4DF41E-C8CC-2606-FA2D-967118BD3C59}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Attestor.Envelope", "E:\dev\git.stella-ops.org\src\Attestor\StellaOps.Attestor.Envelope\StellaOps.Attestor.Envelope.csproj", "{3D8C5A6C-462D-7487-5BD0-A3EF6B657EB6}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Attestor.GraphRoot", "E:\dev\git.stella-ops.org\src\Attestor\__Libraries\StellaOps.Attestor.GraphRoot\StellaOps.Attestor.GraphRoot.csproj", "{2609BC1A-6765-29BE-78CC-C0F1D2814F10}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Attestor.ProofChain", "E:\dev\git.stella-ops.org\src\Attestor\__Libraries\StellaOps.Attestor.ProofChain\StellaOps.Attestor.ProofChain.csproj", "{C6822231-A4F4-9E69-6CE2-4FDB3E81C728}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Auth.Abstractions", "E:\dev\git.stella-ops.org\src\Authority\StellaOps.Authority\StellaOps.Auth.Abstractions\StellaOps.Auth.Abstractions.csproj", "{55D9B653-FB76-FCE8-1A3C-67B1BEDEC214}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Auth.Client", "E:\dev\git.stella-ops.org\src\Authority\StellaOps.Authority\StellaOps.Auth.Client\StellaOps.Auth.Client.csproj", "{DE5BF139-1E5C-D6EA-4FAA-661EF353A194}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Auth.Security", "E:\dev\git.stella-ops.org\src\__Libraries\StellaOps.Auth.Security\StellaOps.Auth.Security.csproj", "{335E62C0-9E69-A952-680B-753B1B17C6D0}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Authority.Plugins.Abstractions", "E:\dev\git.stella-ops.org\src\Authority\StellaOps.Authority\StellaOps.Authority.Plugins.Abstractions\StellaOps.Authority.Plugins.Abstractions.csproj", "{97F94029-5419-6187-5A63-5C8FD9232FAE}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Canonical.Json", "E:\dev\git.stella-ops.org\src\__Libraries\StellaOps.Canonical.Json\StellaOps.Canonical.Json.csproj", "{AF9E7F02-25AD-3540-18D7-F6A4F8BA5A60}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Concelier.Cache.Valkey", "E:\dev\git.stella-ops.org\src\Concelier\__Libraries\StellaOps.Concelier.Cache.Valkey\StellaOps.Concelier.Cache.Valkey.csproj", "{AB6AE2B6-8D6B-2D9F-2A88-7C596C59F4FC}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Concelier.Connector.Common", "E:\dev\git.stella-ops.org\src\Concelier\__Libraries\StellaOps.Concelier.Connector.Common\StellaOps.Concelier.Connector.Common.csproj", "{375F5AD0-F7EE-1782-7B34-E181CDB61B9F}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Concelier.Connector.Ghsa", "E:\dev\git.stella-ops.org\src\Concelier\__Libraries\StellaOps.Concelier.Connector.Ghsa\StellaOps.Concelier.Connector.Ghsa.csproj", "{C117E9AF-D7B8-D4E2-4262-84B6321A9F5C}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Concelier.Connector.Nvd", "E:\dev\git.stella-ops.org\src\Concelier\__Libraries\StellaOps.Concelier.Connector.Nvd\StellaOps.Concelier.Connector.Nvd.csproj", "{D492EFDB-294B-ABA2-FAFB-EAEE6F3DCB52}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Concelier.Connector.Osv", "E:\dev\git.stella-ops.org\src\Concelier\__Libraries\StellaOps.Concelier.Connector.Osv\StellaOps.Concelier.Connector.Osv.csproj", "{9D0C51AF-D1AB-9E12-0B16-A4AA974FAAB5}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Concelier.Core", "E:\dev\git.stella-ops.org\src\Concelier\__Libraries\StellaOps.Concelier.Core\StellaOps.Concelier.Core.csproj", "{BA45605A-1CCE-6B0C-489D-C113915B243F}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Concelier.Interest", "E:\dev\git.stella-ops.org\src\Concelier\__Libraries\StellaOps.Concelier.Interest\StellaOps.Concelier.Interest.csproj", "{9D31FC8A-2A69-B78A-D3E5-4F867B16D971}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Concelier.Merge", "E:\dev\git.stella-ops.org\src\Concelier\__Libraries\StellaOps.Concelier.Merge\StellaOps.Concelier.Merge.csproj", "{92268008-FBB0-C7AD-ECC2-7B75BED9F5E1}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Concelier.Models", "E:\dev\git.stella-ops.org\src\Concelier\__Libraries\StellaOps.Concelier.Models\StellaOps.Concelier.Models.csproj", "{8DCCAF70-D364-4C8B-4E90-AF65091DE0C5}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Concelier.Normalization", "E:\dev\git.stella-ops.org\src\Concelier\__Libraries\StellaOps.Concelier.Normalization\StellaOps.Concelier.Normalization.csproj", "{7828C164-DD01-2809-CCB3-364486834F60}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Concelier.Persistence", "E:\dev\git.stella-ops.org\src\Concelier\__Libraries\StellaOps.Concelier.Persistence\StellaOps.Concelier.Persistence.csproj", "{DE95E7B2-0937-A980-441F-829E023BC43E}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Concelier.ProofService", "E:\dev\git.stella-ops.org\src\Concelier\__Libraries\StellaOps.Concelier.ProofService\StellaOps.Concelier.ProofService.csproj", "{91D69463-23E2-E2C7-AA7E-A78B13CED620}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Concelier.RawModels", "E:\dev\git.stella-ops.org\src\Concelier\__Libraries\StellaOps.Concelier.RawModels\StellaOps.Concelier.RawModels.csproj", "{34EFF636-81A7-8DF6-7CC9-4DA784BAC7F3}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Concelier.SbomIntegration", "E:\dev\git.stella-ops.org\src\Concelier\__Libraries\StellaOps.Concelier.SbomIntegration\StellaOps.Concelier.SbomIntegration.csproj", "{5DCF16A8-97C6-2CB4-6A63-0370239039EB}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Concelier.SourceIntel", "E:\dev\git.stella-ops.org\src\Concelier\__Libraries\StellaOps.Concelier.SourceIntel\StellaOps.Concelier.SourceIntel.csproj", "{EB093C48-CDAC-106B-1196-AE34809B34C0}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Concelier.Testing", "E:\dev\git.stella-ops.org\src\__Tests\__Libraries\StellaOps.Concelier.Testing\StellaOps.Concelier.Testing.csproj", "{370A79BD-AAB3-B833-2B06-A28B3A19E153}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Configuration", "E:\dev\git.stella-ops.org\src\__Libraries\StellaOps.Configuration\StellaOps.Configuration.csproj", "{92C62F7B-8028-6EE1-B71B-F45F459B8E97}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Cryptography", "E:\dev\git.stella-ops.org\src\__Libraries\StellaOps.Cryptography\StellaOps.Cryptography.csproj", "{F664A948-E352-5808-E780-77A03F19E93E}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Cryptography.DependencyInjection", "E:\dev\git.stella-ops.org\src\__Libraries\StellaOps.Cryptography.DependencyInjection\StellaOps.Cryptography.DependencyInjection.csproj", "{FA83F778-5252-0B80-5555-E69F790322EA}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Cryptography.Kms", "E:\dev\git.stella-ops.org\src\__Libraries\StellaOps.Cryptography.Kms\StellaOps.Cryptography.Kms.csproj", "{F3A27846-6DE0-3448-222C-25A273E86B2E}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Cryptography.Plugin.CryptoPro", "E:\dev\git.stella-ops.org\src\__Libraries\StellaOps.Cryptography.Plugin.CryptoPro\StellaOps.Cryptography.Plugin.CryptoPro.csproj", "{C53E0895-879A-D9E6-0A43-24AD17A2F270}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Cryptography.Plugin.OpenSslGost", "E:\dev\git.stella-ops.org\src\__Libraries\StellaOps.Cryptography.Plugin.OpenSslGost\StellaOps.Cryptography.Plugin.OpenSslGost.csproj", "{0AED303F-69E6-238F-EF80-81985080EDB7}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Cryptography.Plugin.Pkcs11Gost", "E:\dev\git.stella-ops.org\src\__Libraries\StellaOps.Cryptography.Plugin.Pkcs11Gost\StellaOps.Cryptography.Plugin.Pkcs11Gost.csproj", "{2904D288-CE64-A565-2C46-C2E85A96A1EE}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Cryptography.Plugin.PqSoft", "E:\dev\git.stella-ops.org\src\__Libraries\StellaOps.Cryptography.Plugin.PqSoft\StellaOps.Cryptography.Plugin.PqSoft.csproj", "{A6667CC3-B77F-023E-3A67-05F99E9FF46A}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Cryptography.Plugin.SimRemote", "E:\dev\git.stella-ops.org\src\__Libraries\StellaOps.Cryptography.Plugin.SimRemote\StellaOps.Cryptography.Plugin.SimRemote.csproj", "{A26E2816-F787-F76B-1D6C-E086DD3E19CE}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Cryptography.Plugin.SmRemote", "E:\dev\git.stella-ops.org\src\__Libraries\StellaOps.Cryptography.Plugin.SmRemote\StellaOps.Cryptography.Plugin.SmRemote.csproj", "{B3DEC619-67AC-1B5A-4F3E-A1F24C3F6877}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Cryptography.Plugin.SmSoft", "E:\dev\git.stella-ops.org\src\__Libraries\StellaOps.Cryptography.Plugin.SmSoft\StellaOps.Cryptography.Plugin.SmSoft.csproj", "{90DB65B4-8F6E-FB8E-0281-505AD8BC6BA6}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Cryptography.Plugin.WineCsp", "E:\dev\git.stella-ops.org\src\__Libraries\StellaOps.Cryptography.Plugin.WineCsp\StellaOps.Cryptography.Plugin.WineCsp.csproj", "{059FBB86-DEE6-8207-3F23-2A1A3EC00DEA}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Cryptography.PluginLoader", "E:\dev\git.stella-ops.org\src\__Libraries\StellaOps.Cryptography.PluginLoader\StellaOps.Cryptography.PluginLoader.csproj", "{8BBA3159-C4CC-F685-A28C-7FE6CBD3D2A1}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.DependencyInjection", "E:\dev\git.stella-ops.org\src\__Libraries\StellaOps.DependencyInjection\StellaOps.DependencyInjection.csproj", "{632A1F0D-1BA5-C84B-B716-2BE638A92780}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Evidence.Bundle", "E:\dev\git.stella-ops.org\src\__Libraries\StellaOps.Evidence.Bundle\StellaOps.Evidence.Bundle.csproj", "{9DE7852B-7E2D-257E-B0F1-45D2687854ED}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Evidence.Core", "E:\dev\git.stella-ops.org\src\__Libraries\StellaOps.Evidence.Core\StellaOps.Evidence.Core.csproj", "{DC2AFC89-C3C8-4E9B-13A7-027EB6386EFA}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Feedser.BinaryAnalysis", "E:\dev\git.stella-ops.org\src\Feedser\StellaOps.Feedser.BinaryAnalysis\StellaOps.Feedser.BinaryAnalysis.csproj", "{CB296A20-2732-77C1-7F23-27D5BAEDD0C7}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Feedser.Core", "E:\dev\git.stella-ops.org\src\Feedser\StellaOps.Feedser.Core\StellaOps.Feedser.Core.csproj", "{0DBEC9BA-FE1D-3898-B2C6-E4357DC23E0F}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Infrastructure.EfCore", "E:\dev\git.stella-ops.org\src\__Libraries\StellaOps.Infrastructure.EfCore\StellaOps.Infrastructure.EfCore.csproj", "{A63897D9-9531-989B-7309-E384BCFC2BB9}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Infrastructure.Postgres", "E:\dev\git.stella-ops.org\src\__Libraries\StellaOps.Infrastructure.Postgres\StellaOps.Infrastructure.Postgres.csproj", "{8C594D82-3463-3367-4F06-900AC707753D}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Infrastructure.Postgres.Testing", "E:\dev\git.stella-ops.org\src\__Tests\__Libraries\StellaOps.Infrastructure.Postgres.Testing\StellaOps.Infrastructure.Postgres.Testing.csproj", "{52F400CD-D473-7A1F-7986-89011CD2A887}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Ingestion.Telemetry", "E:\dev\git.stella-ops.org\src\__Libraries\StellaOps.Ingestion.Telemetry\StellaOps.Ingestion.Telemetry.csproj", "{9588FBF9-C37E-D16E-2E8F-CFA226EAC01D}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Messaging", "E:\dev\git.stella-ops.org\src\Router\__Libraries\StellaOps.Messaging\StellaOps.Messaging.csproj", "{97998C88-E6E1-D5E2-B632-537B58E00CBF}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Plugin", "E:\dev\git.stella-ops.org\src\__Libraries\StellaOps.Plugin\StellaOps.Plugin.csproj", "{38A9EE9B-6FC8-93BC-0D43-2A906E678D66}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Policy", "E:\dev\git.stella-ops.org\src\Policy\__Libraries\StellaOps.Policy\StellaOps.Policy.csproj", "{19868E2D-7163-2108-1094-F13887C4F070}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Policy.RiskProfile", "E:\dev\git.stella-ops.org\src\Policy\StellaOps.Policy.RiskProfile\StellaOps.Policy.RiskProfile.csproj", "{CC319FC5-F4B1-C3DD-7310-4DAD343E0125}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Provcache", "E:\dev\git.stella-ops.org\src\__Libraries\StellaOps.Provcache\StellaOps.Provcache.csproj", "{84F711C2-C210-28D2-F0D9-B13733FEE23D}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Provenance", "E:\dev\git.stella-ops.org\src\__Libraries\StellaOps.Provenance\StellaOps.Provenance.csproj", "{CBB14B90-27F9-8DD6-DFC4-3507DBD1FBC6}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Provenance.Attestation", "E:\dev\git.stella-ops.org\src\Provenance\StellaOps.Provenance.Attestation\StellaOps.Provenance.Attestation.csproj", "{A78EBC0F-C62C-8F56-95C0-330E376242A2}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Replay.Core", "E:\dev\git.stella-ops.org\src\__Libraries\StellaOps.Replay.Core\StellaOps.Replay.Core.csproj", "{6D26FB21-7E48-024B-E5D4-E3F0F31976BB}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Scanner.Analyzers.Lang", "E:\dev\git.stella-ops.org\src\Scanner\__Libraries\StellaOps.Scanner.Analyzers.Lang\StellaOps.Scanner.Analyzers.Lang.csproj", "{28D91816-206C-576E-1A83-FD98E08C2E3C}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Scanner.Core", "E:\dev\git.stella-ops.org\src\Scanner\__Libraries\StellaOps.Scanner.Core\StellaOps.Scanner.Core.csproj", "{58D8630F-C0F4-B772-8572-BCC98FF0F0D8}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Scanner.ProofSpine", "E:\dev\git.stella-ops.org\src\Scanner\__Libraries\StellaOps.Scanner.ProofSpine\StellaOps.Scanner.ProofSpine.csproj", "{7CB7FEA8-8A12-A5D6-0057-AA65DB328617}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Scanner.Surface.Env", "E:\dev\git.stella-ops.org\src\Scanner\__Libraries\StellaOps.Scanner.Surface.Env\StellaOps.Scanner.Surface.Env.csproj", "{52698305-D6F8-C13C-0882-48FC37726404}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Scanner.Surface.FS", "E:\dev\git.stella-ops.org\src\Scanner\__Libraries\StellaOps.Scanner.Surface.FS\StellaOps.Scanner.Surface.FS.csproj", "{5567139C-0365-B6A0-5DD0-978A09B9F176}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Scanner.Surface.Secrets", "E:\dev\git.stella-ops.org\src\Scanner\__Libraries\StellaOps.Scanner.Surface.Secrets\StellaOps.Scanner.Surface.Secrets.csproj", "{256D269B-35EA-F833-2F1D-8E0058908DEE}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Scheduler.Models", "E:\dev\git.stella-ops.org\src\Scheduler\__Libraries\StellaOps.Scheduler.Models\StellaOps.Scheduler.Models.csproj", "{1F372AB9-D8DD-D295-1D5E-CB5D454CBB24}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Signer.Core", "E:\dev\git.stella-ops.org\src\Signer\StellaOps.Signer\StellaOps.Signer.Core\StellaOps.Signer.Core.csproj", "{0AF13355-173C-3128-5AFC-D32E540DA3EF}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.VersionComparison", "E:\dev\git.stella-ops.org\src\__Libraries\StellaOps.VersionComparison\StellaOps.VersionComparison.csproj", "{1D761F8B-921C-53BF-DCF5-5ABD329EEB0C}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "__Tests", "__Tests", "{56BCE1BF-7CBA-7CE8-203D-A88051F1D642}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PolicyDslValidator.Tests", "__Tests\PolicyDslValidator.Tests\PolicyDslValidator.Tests.csproj", "{50FA7781-4439-465A-8061-BEC5C3469814}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Concelier.Testing", "..\__Tests\__Libraries\StellaOps.Concelier.Testing\StellaOps.Concelier.Testing.csproj", "{32FE4D0A-D516-4DF2-80C0-E5211D95B0AD}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Concelier.Connector.Common", "..\Concelier\__Libraries\StellaOps.Concelier.Connector.Common\StellaOps.Concelier.Connector.Common.csproj", "{E15C7277-1131-4998-9D78-6156B53C2225}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Concelier.Normalization", "..\Concelier\__Libraries\StellaOps.Concelier.Normalization\StellaOps.Concelier.Normalization.csproj", "{9D9555C1-9A99-4F48-B0FB-1E24DFD53680}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Concelier.Models", "..\Concelier\__Libraries\StellaOps.Concelier.Models\StellaOps.Concelier.Models.csproj", "{8949E7C3-DC37-4317-9DE0-E7828DA27E14}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Concelier.RawModels", "..\Concelier\__Libraries\StellaOps.Concelier.RawModels\StellaOps.Concelier.RawModels.csproj", "{9D5F9801-96AC-44D5-ABC2-13265AC3E9BD}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Plugin", "..\__Libraries\StellaOps.Plugin\StellaOps.Plugin.csproj", "{3A932381-572C-4DBD-8C4C-53AEA8673697}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.DependencyInjection", "..\__Libraries\StellaOps.DependencyInjection\StellaOps.DependencyInjection.csproj", "{5DDFB053-7DA2-47AB-B4D3-7EBF0720E7BB}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Cryptography", "..\__Libraries\StellaOps.Cryptography\StellaOps.Cryptography.csproj", "{847728D6-7CF8-40DC-899B-17BBA288A2AC}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Concelier.Core", "..\Concelier\__Libraries\StellaOps.Concelier.Core\StellaOps.Concelier.Core.csproj", "{221D52DD-5DCB-4B44-AD14-ED5924155D1E}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Ingestion.Telemetry", "..\__Libraries\StellaOps.Ingestion.Telemetry\StellaOps.Ingestion.Telemetry.csproj", "{12D822DC-8CA8-46A4-89FD-1491A4649B39}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Provenance", "..\__Libraries\StellaOps.Provenance\StellaOps.Provenance.csproj", "{C8753162-F434-4C46-91AE-C4CC05AAEAD4}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Aoc", "..\Aoc\__Libraries\StellaOps.Aoc\StellaOps.Aoc.csproj", "{85117726-9F80-43F5-806A-38D41653E963}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Concelier.Persistence", "..\Concelier\__Libraries\StellaOps.Concelier.Persistence\StellaOps.Concelier.Persistence.csproj", "{67BB82D9-06BE-450D-B956-6350C5EDBFBB}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Infrastructure.Postgres", "..\__Libraries\StellaOps.Infrastructure.Postgres\StellaOps.Infrastructure.Postgres.csproj", "{8F7C01D1-2573-4FC0-8390-516A4F8310DA}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Infrastructure.EfCore", "..\__Libraries\StellaOps.Infrastructure.EfCore\StellaOps.Infrastructure.EfCore.csproj", "{B8FB2391-7A43-451A-90EF-340E157F1C69}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Concelier.Interest", "..\Concelier\__Libraries\StellaOps.Concelier.Interest\StellaOps.Concelier.Interest.csproj", "{C374DB33-2508-4F49-9216-35EF02F78128}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Concelier.Cache.Valkey", "..\Concelier\__Libraries\StellaOps.Concelier.Cache.Valkey\StellaOps.Concelier.Cache.Valkey.csproj", "{40D2202C-F62E-42F4-8C96-36C0990E3316}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Concelier.SbomIntegration", "..\Concelier\__Libraries\StellaOps.Concelier.SbomIntegration\StellaOps.Concelier.SbomIntegration.csproj", "{03143416-8B17-445B-B9FB-8753B9997D39}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Messaging", "..\Router\__Libraries\StellaOps.Messaging\StellaOps.Messaging.csproj", "{61769CBA-A534-449C-8E65-8FF763F82851}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Concelier.Merge", "..\Concelier\__Libraries\StellaOps.Concelier.Merge\StellaOps.Concelier.Merge.csproj", "{B2B8D3BF-A764-42F7-BFBE-8F266D457B49}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Concelier.ProofService", "..\Concelier\__Libraries\StellaOps.Concelier.ProofService\StellaOps.Concelier.ProofService.csproj", "{DF2F93A8-0514-42DE-9C19-0C564036BF13}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Concelier.SourceIntel", "..\Concelier\__Libraries\StellaOps.Concelier.SourceIntel\StellaOps.Concelier.SourceIntel.csproj", "{B910025A-7D54-480E-A036-4B85582F458C}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Feedser.Core", "..\Feedser\StellaOps.Feedser.Core\StellaOps.Feedser.Core.csproj", "{00D7AFF4-5400-441D-BA15-CDB52A0C0654}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Feedser.BinaryAnalysis", "..\Feedser\StellaOps.Feedser.BinaryAnalysis\StellaOps.Feedser.BinaryAnalysis.csproj", "{756624C1-CEDE-4CF2-B5D4-5B22C0C9F131}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Attestor.ProofChain", "..\Attestor\__Libraries\StellaOps.Attestor.ProofChain\StellaOps.Attestor.ProofChain.csproj", "{F5DECABB-33AB-409B-B330-AE8F4C1AEA43}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Canonical.Json", "..\__Libraries\StellaOps.Canonical.Json\StellaOps.Canonical.Json.csproj", "{A57E60A4-3EF4-4A44-A5AE-8BCCED3BCEA5}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Attestor.Envelope", "..\Attestor\StellaOps.Attestor.Envelope\StellaOps.Attestor.Envelope.csproj", "{A8D09907-03D7-41DE-B225-3D52AFC1B29A}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Provcache", "..\__Libraries\StellaOps.Provcache\StellaOps.Provcache.csproj", "{9E59CBEF-FAC9-4060-96E2-D7C5AB73722D}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Provenance.Attestation", "..\Provenance\StellaOps.Provenance.Attestation\StellaOps.Provenance.Attestation.csproj", "{2F60D283-D878-454D-8A2B-7E79A2D94916}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.VersionComparison", "..\__Libraries\StellaOps.VersionComparison\StellaOps.VersionComparison.csproj", "{F557A6F0-03F6-4687-9FDA-7BEBC8969391}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StellaOps.Infrastructure.Postgres.Testing", "..\__Tests\__Libraries\StellaOps.Infrastructure.Postgres.Testing\StellaOps.Infrastructure.Postgres.Testing.csproj", "{0B67426D-5E0E-40A2-B3B1-9C3466795149}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PolicySchemaExporter.Tests", "__Tests\PolicySchemaExporter.Tests\PolicySchemaExporter.Tests.csproj", "{F2181DC4-43EB-4F3A-BD3E-03AD1F9CE3C5}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PolicySimulationSmoke.Tests", "__Tests\PolicySimulationSmoke.Tests\PolicySimulationSmoke.Tests.csproj", "{321594DF-0087-4FD9-8421-C17C749FF742}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|Any CPU = Release|Any CPU + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {52220F70-4EAA-D93F-752B-CD431AAEEDDB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {52220F70-4EAA-D93F-752B-CD431AAEEDDB}.Debug|Any CPU.Build.0 = Debug|Any CPU + {52220F70-4EAA-D93F-752B-CD431AAEEDDB}.Debug|x64.ActiveCfg = Debug|Any CPU + {52220F70-4EAA-D93F-752B-CD431AAEEDDB}.Debug|x64.Build.0 = Debug|Any CPU + {52220F70-4EAA-D93F-752B-CD431AAEEDDB}.Debug|x86.ActiveCfg = Debug|Any CPU + {52220F70-4EAA-D93F-752B-CD431AAEEDDB}.Debug|x86.Build.0 = Debug|Any CPU + {52220F70-4EAA-D93F-752B-CD431AAEEDDB}.Release|Any CPU.ActiveCfg = Release|Any CPU + {52220F70-4EAA-D93F-752B-CD431AAEEDDB}.Release|Any CPU.Build.0 = Release|Any CPU + {52220F70-4EAA-D93F-752B-CD431AAEEDDB}.Release|x64.ActiveCfg = Release|Any CPU + {52220F70-4EAA-D93F-752B-CD431AAEEDDB}.Release|x64.Build.0 = Release|Any CPU + {52220F70-4EAA-D93F-752B-CD431AAEEDDB}.Release|x86.ActiveCfg = Release|Any CPU + {52220F70-4EAA-D93F-752B-CD431AAEEDDB}.Release|x86.Build.0 = Release|Any CPU + {C0C58E4B-9B24-29EA-9585-4BB462666824}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C0C58E4B-9B24-29EA-9585-4BB462666824}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C0C58E4B-9B24-29EA-9585-4BB462666824}.Debug|x64.ActiveCfg = Debug|Any CPU + {C0C58E4B-9B24-29EA-9585-4BB462666824}.Debug|x64.Build.0 = Debug|Any CPU + {C0C58E4B-9B24-29EA-9585-4BB462666824}.Debug|x86.ActiveCfg = Debug|Any CPU + {C0C58E4B-9B24-29EA-9585-4BB462666824}.Debug|x86.Build.0 = Debug|Any CPU + {C0C58E4B-9B24-29EA-9585-4BB462666824}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C0C58E4B-9B24-29EA-9585-4BB462666824}.Release|Any CPU.Build.0 = Release|Any CPU + {C0C58E4B-9B24-29EA-9585-4BB462666824}.Release|x64.ActiveCfg = Release|Any CPU + {C0C58E4B-9B24-29EA-9585-4BB462666824}.Release|x64.Build.0 = Release|Any CPU + {C0C58E4B-9B24-29EA-9585-4BB462666824}.Release|x86.ActiveCfg = Release|Any CPU + {C0C58E4B-9B24-29EA-9585-4BB462666824}.Release|x86.Build.0 = Release|Any CPU + {24D80D5F-0A63-7924-B7C3-79A2772A28DF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {24D80D5F-0A63-7924-B7C3-79A2772A28DF}.Debug|Any CPU.Build.0 = Debug|Any CPU + {24D80D5F-0A63-7924-B7C3-79A2772A28DF}.Debug|x64.ActiveCfg = Debug|Any CPU + {24D80D5F-0A63-7924-B7C3-79A2772A28DF}.Debug|x64.Build.0 = Debug|Any CPU + {24D80D5F-0A63-7924-B7C3-79A2772A28DF}.Debug|x86.ActiveCfg = Debug|Any CPU + {24D80D5F-0A63-7924-B7C3-79A2772A28DF}.Debug|x86.Build.0 = Debug|Any CPU + {24D80D5F-0A63-7924-B7C3-79A2772A28DF}.Release|Any CPU.ActiveCfg = Release|Any CPU + {24D80D5F-0A63-7924-B7C3-79A2772A28DF}.Release|Any CPU.Build.0 = Release|Any CPU + {24D80D5F-0A63-7924-B7C3-79A2772A28DF}.Release|x64.ActiveCfg = Release|Any CPU + {24D80D5F-0A63-7924-B7C3-79A2772A28DF}.Release|x64.Build.0 = Release|Any CPU + {24D80D5F-0A63-7924-B7C3-79A2772A28DF}.Release|x86.ActiveCfg = Release|Any CPU + {24D80D5F-0A63-7924-B7C3-79A2772A28DF}.Release|x86.Build.0 = Release|Any CPU + {8A3083F4-FBB0-6972-9FB5-FE3D05488CD6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {8A3083F4-FBB0-6972-9FB5-FE3D05488CD6}.Debug|Any CPU.Build.0 = Debug|Any CPU + {8A3083F4-FBB0-6972-9FB5-FE3D05488CD6}.Debug|x64.ActiveCfg = Debug|Any CPU + {8A3083F4-FBB0-6972-9FB5-FE3D05488CD6}.Debug|x64.Build.0 = Debug|Any CPU + {8A3083F4-FBB0-6972-9FB5-FE3D05488CD6}.Debug|x86.ActiveCfg = Debug|Any CPU + {8A3083F4-FBB0-6972-9FB5-FE3D05488CD6}.Debug|x86.Build.0 = Debug|Any CPU + {8A3083F4-FBB0-6972-9FB5-FE3D05488CD6}.Release|Any CPU.ActiveCfg = Release|Any CPU + {8A3083F4-FBB0-6972-9FB5-FE3D05488CD6}.Release|Any CPU.Build.0 = Release|Any CPU + {8A3083F4-FBB0-6972-9FB5-FE3D05488CD6}.Release|x64.ActiveCfg = Release|Any CPU + {8A3083F4-FBB0-6972-9FB5-FE3D05488CD6}.Release|x64.Build.0 = Release|Any CPU + {8A3083F4-FBB0-6972-9FB5-FE3D05488CD6}.Release|x86.ActiveCfg = Release|Any CPU + {8A3083F4-FBB0-6972-9FB5-FE3D05488CD6}.Release|x86.Build.0 = Release|Any CPU + {13E7A80F-191B-0B12-4C7F-A1CA9808DD65}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {13E7A80F-191B-0B12-4C7F-A1CA9808DD65}.Debug|Any CPU.Build.0 = Debug|Any CPU + {13E7A80F-191B-0B12-4C7F-A1CA9808DD65}.Debug|x64.ActiveCfg = Debug|Any CPU + {13E7A80F-191B-0B12-4C7F-A1CA9808DD65}.Debug|x64.Build.0 = Debug|Any CPU + {13E7A80F-191B-0B12-4C7F-A1CA9808DD65}.Debug|x86.ActiveCfg = Debug|Any CPU + {13E7A80F-191B-0B12-4C7F-A1CA9808DD65}.Debug|x86.Build.0 = Debug|Any CPU + {13E7A80F-191B-0B12-4C7F-A1CA9808DD65}.Release|Any CPU.ActiveCfg = Release|Any CPU + {13E7A80F-191B-0B12-4C7F-A1CA9808DD65}.Release|Any CPU.Build.0 = Release|Any CPU + {13E7A80F-191B-0B12-4C7F-A1CA9808DD65}.Release|x64.ActiveCfg = Release|Any CPU + {13E7A80F-191B-0B12-4C7F-A1CA9808DD65}.Release|x64.Build.0 = Release|Any CPU + {13E7A80F-191B-0B12-4C7F-A1CA9808DD65}.Release|x86.ActiveCfg = Release|Any CPU + {13E7A80F-191B-0B12-4C7F-A1CA9808DD65}.Release|x86.Build.0 = Release|Any CPU + {A82DBB41-8BF0-440B-1BD1-611A2521DAA0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A82DBB41-8BF0-440B-1BD1-611A2521DAA0}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A82DBB41-8BF0-440B-1BD1-611A2521DAA0}.Debug|x64.ActiveCfg = Debug|Any CPU + {A82DBB41-8BF0-440B-1BD1-611A2521DAA0}.Debug|x64.Build.0 = Debug|Any CPU + {A82DBB41-8BF0-440B-1BD1-611A2521DAA0}.Debug|x86.ActiveCfg = Debug|Any CPU + {A82DBB41-8BF0-440B-1BD1-611A2521DAA0}.Debug|x86.Build.0 = Debug|Any CPU + {A82DBB41-8BF0-440B-1BD1-611A2521DAA0}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A82DBB41-8BF0-440B-1BD1-611A2521DAA0}.Release|Any CPU.Build.0 = Release|Any CPU + {A82DBB41-8BF0-440B-1BD1-611A2521DAA0}.Release|x64.ActiveCfg = Release|Any CPU + {A82DBB41-8BF0-440B-1BD1-611A2521DAA0}.Release|x64.Build.0 = Release|Any CPU + {A82DBB41-8BF0-440B-1BD1-611A2521DAA0}.Release|x86.ActiveCfg = Release|Any CPU + {A82DBB41-8BF0-440B-1BD1-611A2521DAA0}.Release|x86.Build.0 = Release|Any CPU + {8C96DAFC-3A63-EB7B-EA8F-07A63817204D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {8C96DAFC-3A63-EB7B-EA8F-07A63817204D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {8C96DAFC-3A63-EB7B-EA8F-07A63817204D}.Debug|x64.ActiveCfg = Debug|Any CPU + {8C96DAFC-3A63-EB7B-EA8F-07A63817204D}.Debug|x64.Build.0 = Debug|Any CPU + {8C96DAFC-3A63-EB7B-EA8F-07A63817204D}.Debug|x86.ActiveCfg = Debug|Any CPU + {8C96DAFC-3A63-EB7B-EA8F-07A63817204D}.Debug|x86.Build.0 = Debug|Any CPU + {8C96DAFC-3A63-EB7B-EA8F-07A63817204D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {8C96DAFC-3A63-EB7B-EA8F-07A63817204D}.Release|Any CPU.Build.0 = Release|Any CPU + {8C96DAFC-3A63-EB7B-EA8F-07A63817204D}.Release|x64.ActiveCfg = Release|Any CPU + {8C96DAFC-3A63-EB7B-EA8F-07A63817204D}.Release|x64.Build.0 = Release|Any CPU + {8C96DAFC-3A63-EB7B-EA8F-07A63817204D}.Release|x86.ActiveCfg = Release|Any CPU + {8C96DAFC-3A63-EB7B-EA8F-07A63817204D}.Release|x86.Build.0 = Release|Any CPU + {AD31623A-BC43-52C2-D906-AC1D8784A541}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {AD31623A-BC43-52C2-D906-AC1D8784A541}.Debug|Any CPU.Build.0 = Debug|Any CPU + {AD31623A-BC43-52C2-D906-AC1D8784A541}.Debug|x64.ActiveCfg = Debug|Any CPU + {AD31623A-BC43-52C2-D906-AC1D8784A541}.Debug|x64.Build.0 = Debug|Any CPU + {AD31623A-BC43-52C2-D906-AC1D8784A541}.Debug|x86.ActiveCfg = Debug|Any CPU + {AD31623A-BC43-52C2-D906-AC1D8784A541}.Debug|x86.Build.0 = Debug|Any CPU + {AD31623A-BC43-52C2-D906-AC1D8784A541}.Release|Any CPU.ActiveCfg = Release|Any CPU + {AD31623A-BC43-52C2-D906-AC1D8784A541}.Release|Any CPU.Build.0 = Release|Any CPU + {AD31623A-BC43-52C2-D906-AC1D8784A541}.Release|x64.ActiveCfg = Release|Any CPU + {AD31623A-BC43-52C2-D906-AC1D8784A541}.Release|x64.Build.0 = Release|Any CPU + {AD31623A-BC43-52C2-D906-AC1D8784A541}.Release|x86.ActiveCfg = Release|Any CPU + {AD31623A-BC43-52C2-D906-AC1D8784A541}.Release|x86.Build.0 = Release|Any CPU + {776E2142-804F-03B9-C804-D061D64C6092}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {776E2142-804F-03B9-C804-D061D64C6092}.Debug|Any CPU.Build.0 = Debug|Any CPU + {776E2142-804F-03B9-C804-D061D64C6092}.Debug|x64.ActiveCfg = Debug|Any CPU + {776E2142-804F-03B9-C804-D061D64C6092}.Debug|x64.Build.0 = Debug|Any CPU + {776E2142-804F-03B9-C804-D061D64C6092}.Debug|x86.ActiveCfg = Debug|Any CPU + {776E2142-804F-03B9-C804-D061D64C6092}.Debug|x86.Build.0 = Debug|Any CPU + {776E2142-804F-03B9-C804-D061D64C6092}.Release|Any CPU.ActiveCfg = Release|Any CPU + {776E2142-804F-03B9-C804-D061D64C6092}.Release|Any CPU.Build.0 = Release|Any CPU + {776E2142-804F-03B9-C804-D061D64C6092}.Release|x64.ActiveCfg = Release|Any CPU + {776E2142-804F-03B9-C804-D061D64C6092}.Release|x64.Build.0 = Release|Any CPU + {776E2142-804F-03B9-C804-D061D64C6092}.Release|x86.ActiveCfg = Release|Any CPU + {776E2142-804F-03B9-C804-D061D64C6092}.Release|x86.Build.0 = Release|Any CPU + {5B4DF41E-C8CC-2606-FA2D-967118BD3C59}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {5B4DF41E-C8CC-2606-FA2D-967118BD3C59}.Debug|Any CPU.Build.0 = Debug|Any CPU + {5B4DF41E-C8CC-2606-FA2D-967118BD3C59}.Debug|x64.ActiveCfg = Debug|Any CPU + {5B4DF41E-C8CC-2606-FA2D-967118BD3C59}.Debug|x64.Build.0 = Debug|Any CPU + {5B4DF41E-C8CC-2606-FA2D-967118BD3C59}.Debug|x86.ActiveCfg = Debug|Any CPU + {5B4DF41E-C8CC-2606-FA2D-967118BD3C59}.Debug|x86.Build.0 = Debug|Any CPU + {5B4DF41E-C8CC-2606-FA2D-967118BD3C59}.Release|Any CPU.ActiveCfg = Release|Any CPU + {5B4DF41E-C8CC-2606-FA2D-967118BD3C59}.Release|Any CPU.Build.0 = Release|Any CPU + {5B4DF41E-C8CC-2606-FA2D-967118BD3C59}.Release|x64.ActiveCfg = Release|Any CPU + {5B4DF41E-C8CC-2606-FA2D-967118BD3C59}.Release|x64.Build.0 = Release|Any CPU + {5B4DF41E-C8CC-2606-FA2D-967118BD3C59}.Release|x86.ActiveCfg = Release|Any CPU + {5B4DF41E-C8CC-2606-FA2D-967118BD3C59}.Release|x86.Build.0 = Release|Any CPU + {3D8C5A6C-462D-7487-5BD0-A3EF6B657EB6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {3D8C5A6C-462D-7487-5BD0-A3EF6B657EB6}.Debug|Any CPU.Build.0 = Debug|Any CPU + {3D8C5A6C-462D-7487-5BD0-A3EF6B657EB6}.Debug|x64.ActiveCfg = Debug|Any CPU + {3D8C5A6C-462D-7487-5BD0-A3EF6B657EB6}.Debug|x64.Build.0 = Debug|Any CPU + {3D8C5A6C-462D-7487-5BD0-A3EF6B657EB6}.Debug|x86.ActiveCfg = Debug|Any CPU + {3D8C5A6C-462D-7487-5BD0-A3EF6B657EB6}.Debug|x86.Build.0 = Debug|Any CPU + {3D8C5A6C-462D-7487-5BD0-A3EF6B657EB6}.Release|Any CPU.ActiveCfg = Release|Any CPU + {3D8C5A6C-462D-7487-5BD0-A3EF6B657EB6}.Release|Any CPU.Build.0 = Release|Any CPU + {3D8C5A6C-462D-7487-5BD0-A3EF6B657EB6}.Release|x64.ActiveCfg = Release|Any CPU + {3D8C5A6C-462D-7487-5BD0-A3EF6B657EB6}.Release|x64.Build.0 = Release|Any CPU + {3D8C5A6C-462D-7487-5BD0-A3EF6B657EB6}.Release|x86.ActiveCfg = Release|Any CPU + {3D8C5A6C-462D-7487-5BD0-A3EF6B657EB6}.Release|x86.Build.0 = Release|Any CPU + {2609BC1A-6765-29BE-78CC-C0F1D2814F10}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {2609BC1A-6765-29BE-78CC-C0F1D2814F10}.Debug|Any CPU.Build.0 = Debug|Any CPU + {2609BC1A-6765-29BE-78CC-C0F1D2814F10}.Debug|x64.ActiveCfg = Debug|Any CPU + {2609BC1A-6765-29BE-78CC-C0F1D2814F10}.Debug|x64.Build.0 = Debug|Any CPU + {2609BC1A-6765-29BE-78CC-C0F1D2814F10}.Debug|x86.ActiveCfg = Debug|Any CPU + {2609BC1A-6765-29BE-78CC-C0F1D2814F10}.Debug|x86.Build.0 = Debug|Any CPU + {2609BC1A-6765-29BE-78CC-C0F1D2814F10}.Release|Any CPU.ActiveCfg = Release|Any CPU + {2609BC1A-6765-29BE-78CC-C0F1D2814F10}.Release|Any CPU.Build.0 = Release|Any CPU + {2609BC1A-6765-29BE-78CC-C0F1D2814F10}.Release|x64.ActiveCfg = Release|Any CPU + {2609BC1A-6765-29BE-78CC-C0F1D2814F10}.Release|x64.Build.0 = Release|Any CPU + {2609BC1A-6765-29BE-78CC-C0F1D2814F10}.Release|x86.ActiveCfg = Release|Any CPU + {2609BC1A-6765-29BE-78CC-C0F1D2814F10}.Release|x86.Build.0 = Release|Any CPU + {C6822231-A4F4-9E69-6CE2-4FDB3E81C728}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C6822231-A4F4-9E69-6CE2-4FDB3E81C728}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C6822231-A4F4-9E69-6CE2-4FDB3E81C728}.Debug|x64.ActiveCfg = Debug|Any CPU + {C6822231-A4F4-9E69-6CE2-4FDB3E81C728}.Debug|x64.Build.0 = Debug|Any CPU + {C6822231-A4F4-9E69-6CE2-4FDB3E81C728}.Debug|x86.ActiveCfg = Debug|Any CPU + {C6822231-A4F4-9E69-6CE2-4FDB3E81C728}.Debug|x86.Build.0 = Debug|Any CPU + {C6822231-A4F4-9E69-6CE2-4FDB3E81C728}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C6822231-A4F4-9E69-6CE2-4FDB3E81C728}.Release|Any CPU.Build.0 = Release|Any CPU + {C6822231-A4F4-9E69-6CE2-4FDB3E81C728}.Release|x64.ActiveCfg = Release|Any CPU + {C6822231-A4F4-9E69-6CE2-4FDB3E81C728}.Release|x64.Build.0 = Release|Any CPU + {C6822231-A4F4-9E69-6CE2-4FDB3E81C728}.Release|x86.ActiveCfg = Release|Any CPU + {C6822231-A4F4-9E69-6CE2-4FDB3E81C728}.Release|x86.Build.0 = Release|Any CPU + {55D9B653-FB76-FCE8-1A3C-67B1BEDEC214}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {55D9B653-FB76-FCE8-1A3C-67B1BEDEC214}.Debug|Any CPU.Build.0 = Debug|Any CPU + {55D9B653-FB76-FCE8-1A3C-67B1BEDEC214}.Debug|x64.ActiveCfg = Debug|Any CPU + {55D9B653-FB76-FCE8-1A3C-67B1BEDEC214}.Debug|x64.Build.0 = Debug|Any CPU + {55D9B653-FB76-FCE8-1A3C-67B1BEDEC214}.Debug|x86.ActiveCfg = Debug|Any CPU + {55D9B653-FB76-FCE8-1A3C-67B1BEDEC214}.Debug|x86.Build.0 = Debug|Any CPU + {55D9B653-FB76-FCE8-1A3C-67B1BEDEC214}.Release|Any CPU.ActiveCfg = Release|Any CPU + {55D9B653-FB76-FCE8-1A3C-67B1BEDEC214}.Release|Any CPU.Build.0 = Release|Any CPU + {55D9B653-FB76-FCE8-1A3C-67B1BEDEC214}.Release|x64.ActiveCfg = Release|Any CPU + {55D9B653-FB76-FCE8-1A3C-67B1BEDEC214}.Release|x64.Build.0 = Release|Any CPU + {55D9B653-FB76-FCE8-1A3C-67B1BEDEC214}.Release|x86.ActiveCfg = Release|Any CPU + {55D9B653-FB76-FCE8-1A3C-67B1BEDEC214}.Release|x86.Build.0 = Release|Any CPU + {DE5BF139-1E5C-D6EA-4FAA-661EF353A194}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {DE5BF139-1E5C-D6EA-4FAA-661EF353A194}.Debug|Any CPU.Build.0 = Debug|Any CPU + {DE5BF139-1E5C-D6EA-4FAA-661EF353A194}.Debug|x64.ActiveCfg = Debug|Any CPU + {DE5BF139-1E5C-D6EA-4FAA-661EF353A194}.Debug|x64.Build.0 = Debug|Any CPU + {DE5BF139-1E5C-D6EA-4FAA-661EF353A194}.Debug|x86.ActiveCfg = Debug|Any CPU + {DE5BF139-1E5C-D6EA-4FAA-661EF353A194}.Debug|x86.Build.0 = Debug|Any CPU + {DE5BF139-1E5C-D6EA-4FAA-661EF353A194}.Release|Any CPU.ActiveCfg = Release|Any CPU + {DE5BF139-1E5C-D6EA-4FAA-661EF353A194}.Release|Any CPU.Build.0 = Release|Any CPU + {DE5BF139-1E5C-D6EA-4FAA-661EF353A194}.Release|x64.ActiveCfg = Release|Any CPU + {DE5BF139-1E5C-D6EA-4FAA-661EF353A194}.Release|x64.Build.0 = Release|Any CPU + {DE5BF139-1E5C-D6EA-4FAA-661EF353A194}.Release|x86.ActiveCfg = Release|Any CPU + {DE5BF139-1E5C-D6EA-4FAA-661EF353A194}.Release|x86.Build.0 = Release|Any CPU + {335E62C0-9E69-A952-680B-753B1B17C6D0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {335E62C0-9E69-A952-680B-753B1B17C6D0}.Debug|Any CPU.Build.0 = Debug|Any CPU + {335E62C0-9E69-A952-680B-753B1B17C6D0}.Debug|x64.ActiveCfg = Debug|Any CPU + {335E62C0-9E69-A952-680B-753B1B17C6D0}.Debug|x64.Build.0 = Debug|Any CPU + {335E62C0-9E69-A952-680B-753B1B17C6D0}.Debug|x86.ActiveCfg = Debug|Any CPU + {335E62C0-9E69-A952-680B-753B1B17C6D0}.Debug|x86.Build.0 = Debug|Any CPU + {335E62C0-9E69-A952-680B-753B1B17C6D0}.Release|Any CPU.ActiveCfg = Release|Any CPU + {335E62C0-9E69-A952-680B-753B1B17C6D0}.Release|Any CPU.Build.0 = Release|Any CPU + {335E62C0-9E69-A952-680B-753B1B17C6D0}.Release|x64.ActiveCfg = Release|Any CPU + {335E62C0-9E69-A952-680B-753B1B17C6D0}.Release|x64.Build.0 = Release|Any CPU + {335E62C0-9E69-A952-680B-753B1B17C6D0}.Release|x86.ActiveCfg = Release|Any CPU + {335E62C0-9E69-A952-680B-753B1B17C6D0}.Release|x86.Build.0 = Release|Any CPU + {97F94029-5419-6187-5A63-5C8FD9232FAE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {97F94029-5419-6187-5A63-5C8FD9232FAE}.Debug|Any CPU.Build.0 = Debug|Any CPU + {97F94029-5419-6187-5A63-5C8FD9232FAE}.Debug|x64.ActiveCfg = Debug|Any CPU + {97F94029-5419-6187-5A63-5C8FD9232FAE}.Debug|x64.Build.0 = Debug|Any CPU + {97F94029-5419-6187-5A63-5C8FD9232FAE}.Debug|x86.ActiveCfg = Debug|Any CPU + {97F94029-5419-6187-5A63-5C8FD9232FAE}.Debug|x86.Build.0 = Debug|Any CPU + {97F94029-5419-6187-5A63-5C8FD9232FAE}.Release|Any CPU.ActiveCfg = Release|Any CPU + {97F94029-5419-6187-5A63-5C8FD9232FAE}.Release|Any CPU.Build.0 = Release|Any CPU + {97F94029-5419-6187-5A63-5C8FD9232FAE}.Release|x64.ActiveCfg = Release|Any CPU + {97F94029-5419-6187-5A63-5C8FD9232FAE}.Release|x64.Build.0 = Release|Any CPU + {97F94029-5419-6187-5A63-5C8FD9232FAE}.Release|x86.ActiveCfg = Release|Any CPU + {97F94029-5419-6187-5A63-5C8FD9232FAE}.Release|x86.Build.0 = Release|Any CPU + {AF9E7F02-25AD-3540-18D7-F6A4F8BA5A60}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {AF9E7F02-25AD-3540-18D7-F6A4F8BA5A60}.Debug|Any CPU.Build.0 = Debug|Any CPU + {AF9E7F02-25AD-3540-18D7-F6A4F8BA5A60}.Debug|x64.ActiveCfg = Debug|Any CPU + {AF9E7F02-25AD-3540-18D7-F6A4F8BA5A60}.Debug|x64.Build.0 = Debug|Any CPU + {AF9E7F02-25AD-3540-18D7-F6A4F8BA5A60}.Debug|x86.ActiveCfg = Debug|Any CPU + {AF9E7F02-25AD-3540-18D7-F6A4F8BA5A60}.Debug|x86.Build.0 = Debug|Any CPU + {AF9E7F02-25AD-3540-18D7-F6A4F8BA5A60}.Release|Any CPU.ActiveCfg = Release|Any CPU + {AF9E7F02-25AD-3540-18D7-F6A4F8BA5A60}.Release|Any CPU.Build.0 = Release|Any CPU + {AF9E7F02-25AD-3540-18D7-F6A4F8BA5A60}.Release|x64.ActiveCfg = Release|Any CPU + {AF9E7F02-25AD-3540-18D7-F6A4F8BA5A60}.Release|x64.Build.0 = Release|Any CPU + {AF9E7F02-25AD-3540-18D7-F6A4F8BA5A60}.Release|x86.ActiveCfg = Release|Any CPU + {AF9E7F02-25AD-3540-18D7-F6A4F8BA5A60}.Release|x86.Build.0 = Release|Any CPU + {AB6AE2B6-8D6B-2D9F-2A88-7C596C59F4FC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {AB6AE2B6-8D6B-2D9F-2A88-7C596C59F4FC}.Debug|Any CPU.Build.0 = Debug|Any CPU + {AB6AE2B6-8D6B-2D9F-2A88-7C596C59F4FC}.Debug|x64.ActiveCfg = Debug|Any CPU + {AB6AE2B6-8D6B-2D9F-2A88-7C596C59F4FC}.Debug|x64.Build.0 = Debug|Any CPU + {AB6AE2B6-8D6B-2D9F-2A88-7C596C59F4FC}.Debug|x86.ActiveCfg = Debug|Any CPU + {AB6AE2B6-8D6B-2D9F-2A88-7C596C59F4FC}.Debug|x86.Build.0 = Debug|Any CPU + {AB6AE2B6-8D6B-2D9F-2A88-7C596C59F4FC}.Release|Any CPU.ActiveCfg = Release|Any CPU + {AB6AE2B6-8D6B-2D9F-2A88-7C596C59F4FC}.Release|Any CPU.Build.0 = Release|Any CPU + {AB6AE2B6-8D6B-2D9F-2A88-7C596C59F4FC}.Release|x64.ActiveCfg = Release|Any CPU + {AB6AE2B6-8D6B-2D9F-2A88-7C596C59F4FC}.Release|x64.Build.0 = Release|Any CPU + {AB6AE2B6-8D6B-2D9F-2A88-7C596C59F4FC}.Release|x86.ActiveCfg = Release|Any CPU + {AB6AE2B6-8D6B-2D9F-2A88-7C596C59F4FC}.Release|x86.Build.0 = Release|Any CPU + {375F5AD0-F7EE-1782-7B34-E181CDB61B9F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {375F5AD0-F7EE-1782-7B34-E181CDB61B9F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {375F5AD0-F7EE-1782-7B34-E181CDB61B9F}.Debug|x64.ActiveCfg = Debug|Any CPU + {375F5AD0-F7EE-1782-7B34-E181CDB61B9F}.Debug|x64.Build.0 = Debug|Any CPU + {375F5AD0-F7EE-1782-7B34-E181CDB61B9F}.Debug|x86.ActiveCfg = Debug|Any CPU + {375F5AD0-F7EE-1782-7B34-E181CDB61B9F}.Debug|x86.Build.0 = Debug|Any CPU + {375F5AD0-F7EE-1782-7B34-E181CDB61B9F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {375F5AD0-F7EE-1782-7B34-E181CDB61B9F}.Release|Any CPU.Build.0 = Release|Any CPU + {375F5AD0-F7EE-1782-7B34-E181CDB61B9F}.Release|x64.ActiveCfg = Release|Any CPU + {375F5AD0-F7EE-1782-7B34-E181CDB61B9F}.Release|x64.Build.0 = Release|Any CPU + {375F5AD0-F7EE-1782-7B34-E181CDB61B9F}.Release|x86.ActiveCfg = Release|Any CPU + {375F5AD0-F7EE-1782-7B34-E181CDB61B9F}.Release|x86.Build.0 = Release|Any CPU + {C117E9AF-D7B8-D4E2-4262-84B6321A9F5C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C117E9AF-D7B8-D4E2-4262-84B6321A9F5C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C117E9AF-D7B8-D4E2-4262-84B6321A9F5C}.Debug|x64.ActiveCfg = Debug|Any CPU + {C117E9AF-D7B8-D4E2-4262-84B6321A9F5C}.Debug|x64.Build.0 = Debug|Any CPU + {C117E9AF-D7B8-D4E2-4262-84B6321A9F5C}.Debug|x86.ActiveCfg = Debug|Any CPU + {C117E9AF-D7B8-D4E2-4262-84B6321A9F5C}.Debug|x86.Build.0 = Debug|Any CPU + {C117E9AF-D7B8-D4E2-4262-84B6321A9F5C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C117E9AF-D7B8-D4E2-4262-84B6321A9F5C}.Release|Any CPU.Build.0 = Release|Any CPU + {C117E9AF-D7B8-D4E2-4262-84B6321A9F5C}.Release|x64.ActiveCfg = Release|Any CPU + {C117E9AF-D7B8-D4E2-4262-84B6321A9F5C}.Release|x64.Build.0 = Release|Any CPU + {C117E9AF-D7B8-D4E2-4262-84B6321A9F5C}.Release|x86.ActiveCfg = Release|Any CPU + {C117E9AF-D7B8-D4E2-4262-84B6321A9F5C}.Release|x86.Build.0 = Release|Any CPU + {D492EFDB-294B-ABA2-FAFB-EAEE6F3DCB52}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D492EFDB-294B-ABA2-FAFB-EAEE6F3DCB52}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D492EFDB-294B-ABA2-FAFB-EAEE6F3DCB52}.Debug|x64.ActiveCfg = Debug|Any CPU + {D492EFDB-294B-ABA2-FAFB-EAEE6F3DCB52}.Debug|x64.Build.0 = Debug|Any CPU + {D492EFDB-294B-ABA2-FAFB-EAEE6F3DCB52}.Debug|x86.ActiveCfg = Debug|Any CPU + {D492EFDB-294B-ABA2-FAFB-EAEE6F3DCB52}.Debug|x86.Build.0 = Debug|Any CPU + {D492EFDB-294B-ABA2-FAFB-EAEE6F3DCB52}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D492EFDB-294B-ABA2-FAFB-EAEE6F3DCB52}.Release|Any CPU.Build.0 = Release|Any CPU + {D492EFDB-294B-ABA2-FAFB-EAEE6F3DCB52}.Release|x64.ActiveCfg = Release|Any CPU + {D492EFDB-294B-ABA2-FAFB-EAEE6F3DCB52}.Release|x64.Build.0 = Release|Any CPU + {D492EFDB-294B-ABA2-FAFB-EAEE6F3DCB52}.Release|x86.ActiveCfg = Release|Any CPU + {D492EFDB-294B-ABA2-FAFB-EAEE6F3DCB52}.Release|x86.Build.0 = Release|Any CPU + {9D0C51AF-D1AB-9E12-0B16-A4AA974FAAB5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {9D0C51AF-D1AB-9E12-0B16-A4AA974FAAB5}.Debug|Any CPU.Build.0 = Debug|Any CPU + {9D0C51AF-D1AB-9E12-0B16-A4AA974FAAB5}.Debug|x64.ActiveCfg = Debug|Any CPU + {9D0C51AF-D1AB-9E12-0B16-A4AA974FAAB5}.Debug|x64.Build.0 = Debug|Any CPU + {9D0C51AF-D1AB-9E12-0B16-A4AA974FAAB5}.Debug|x86.ActiveCfg = Debug|Any CPU + {9D0C51AF-D1AB-9E12-0B16-A4AA974FAAB5}.Debug|x86.Build.0 = Debug|Any CPU + {9D0C51AF-D1AB-9E12-0B16-A4AA974FAAB5}.Release|Any CPU.ActiveCfg = Release|Any CPU + {9D0C51AF-D1AB-9E12-0B16-A4AA974FAAB5}.Release|Any CPU.Build.0 = Release|Any CPU + {9D0C51AF-D1AB-9E12-0B16-A4AA974FAAB5}.Release|x64.ActiveCfg = Release|Any CPU + {9D0C51AF-D1AB-9E12-0B16-A4AA974FAAB5}.Release|x64.Build.0 = Release|Any CPU + {9D0C51AF-D1AB-9E12-0B16-A4AA974FAAB5}.Release|x86.ActiveCfg = Release|Any CPU + {9D0C51AF-D1AB-9E12-0B16-A4AA974FAAB5}.Release|x86.Build.0 = Release|Any CPU + {BA45605A-1CCE-6B0C-489D-C113915B243F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {BA45605A-1CCE-6B0C-489D-C113915B243F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {BA45605A-1CCE-6B0C-489D-C113915B243F}.Debug|x64.ActiveCfg = Debug|Any CPU + {BA45605A-1CCE-6B0C-489D-C113915B243F}.Debug|x64.Build.0 = Debug|Any CPU + {BA45605A-1CCE-6B0C-489D-C113915B243F}.Debug|x86.ActiveCfg = Debug|Any CPU + {BA45605A-1CCE-6B0C-489D-C113915B243F}.Debug|x86.Build.0 = Debug|Any CPU + {BA45605A-1CCE-6B0C-489D-C113915B243F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {BA45605A-1CCE-6B0C-489D-C113915B243F}.Release|Any CPU.Build.0 = Release|Any CPU + {BA45605A-1CCE-6B0C-489D-C113915B243F}.Release|x64.ActiveCfg = Release|Any CPU + {BA45605A-1CCE-6B0C-489D-C113915B243F}.Release|x64.Build.0 = Release|Any CPU + {BA45605A-1CCE-6B0C-489D-C113915B243F}.Release|x86.ActiveCfg = Release|Any CPU + {BA45605A-1CCE-6B0C-489D-C113915B243F}.Release|x86.Build.0 = Release|Any CPU + {9D31FC8A-2A69-B78A-D3E5-4F867B16D971}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {9D31FC8A-2A69-B78A-D3E5-4F867B16D971}.Debug|Any CPU.Build.0 = Debug|Any CPU + {9D31FC8A-2A69-B78A-D3E5-4F867B16D971}.Debug|x64.ActiveCfg = Debug|Any CPU + {9D31FC8A-2A69-B78A-D3E5-4F867B16D971}.Debug|x64.Build.0 = Debug|Any CPU + {9D31FC8A-2A69-B78A-D3E5-4F867B16D971}.Debug|x86.ActiveCfg = Debug|Any CPU + {9D31FC8A-2A69-B78A-D3E5-4F867B16D971}.Debug|x86.Build.0 = Debug|Any CPU + {9D31FC8A-2A69-B78A-D3E5-4F867B16D971}.Release|Any CPU.ActiveCfg = Release|Any CPU + {9D31FC8A-2A69-B78A-D3E5-4F867B16D971}.Release|Any CPU.Build.0 = Release|Any CPU + {9D31FC8A-2A69-B78A-D3E5-4F867B16D971}.Release|x64.ActiveCfg = Release|Any CPU + {9D31FC8A-2A69-B78A-D3E5-4F867B16D971}.Release|x64.Build.0 = Release|Any CPU + {9D31FC8A-2A69-B78A-D3E5-4F867B16D971}.Release|x86.ActiveCfg = Release|Any CPU + {9D31FC8A-2A69-B78A-D3E5-4F867B16D971}.Release|x86.Build.0 = Release|Any CPU + {92268008-FBB0-C7AD-ECC2-7B75BED9F5E1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {92268008-FBB0-C7AD-ECC2-7B75BED9F5E1}.Debug|Any CPU.Build.0 = Debug|Any CPU + {92268008-FBB0-C7AD-ECC2-7B75BED9F5E1}.Debug|x64.ActiveCfg = Debug|Any CPU + {92268008-FBB0-C7AD-ECC2-7B75BED9F5E1}.Debug|x64.Build.0 = Debug|Any CPU + {92268008-FBB0-C7AD-ECC2-7B75BED9F5E1}.Debug|x86.ActiveCfg = Debug|Any CPU + {92268008-FBB0-C7AD-ECC2-7B75BED9F5E1}.Debug|x86.Build.0 = Debug|Any CPU + {92268008-FBB0-C7AD-ECC2-7B75BED9F5E1}.Release|Any CPU.ActiveCfg = Release|Any CPU + {92268008-FBB0-C7AD-ECC2-7B75BED9F5E1}.Release|Any CPU.Build.0 = Release|Any CPU + {92268008-FBB0-C7AD-ECC2-7B75BED9F5E1}.Release|x64.ActiveCfg = Release|Any CPU + {92268008-FBB0-C7AD-ECC2-7B75BED9F5E1}.Release|x64.Build.0 = Release|Any CPU + {92268008-FBB0-C7AD-ECC2-7B75BED9F5E1}.Release|x86.ActiveCfg = Release|Any CPU + {92268008-FBB0-C7AD-ECC2-7B75BED9F5E1}.Release|x86.Build.0 = Release|Any CPU + {8DCCAF70-D364-4C8B-4E90-AF65091DE0C5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {8DCCAF70-D364-4C8B-4E90-AF65091DE0C5}.Debug|Any CPU.Build.0 = Debug|Any CPU + {8DCCAF70-D364-4C8B-4E90-AF65091DE0C5}.Debug|x64.ActiveCfg = Debug|Any CPU + {8DCCAF70-D364-4C8B-4E90-AF65091DE0C5}.Debug|x64.Build.0 = Debug|Any CPU + {8DCCAF70-D364-4C8B-4E90-AF65091DE0C5}.Debug|x86.ActiveCfg = Debug|Any CPU + {8DCCAF70-D364-4C8B-4E90-AF65091DE0C5}.Debug|x86.Build.0 = Debug|Any CPU + {8DCCAF70-D364-4C8B-4E90-AF65091DE0C5}.Release|Any CPU.ActiveCfg = Release|Any CPU + {8DCCAF70-D364-4C8B-4E90-AF65091DE0C5}.Release|Any CPU.Build.0 = Release|Any CPU + {8DCCAF70-D364-4C8B-4E90-AF65091DE0C5}.Release|x64.ActiveCfg = Release|Any CPU + {8DCCAF70-D364-4C8B-4E90-AF65091DE0C5}.Release|x64.Build.0 = Release|Any CPU + {8DCCAF70-D364-4C8B-4E90-AF65091DE0C5}.Release|x86.ActiveCfg = Release|Any CPU + {8DCCAF70-D364-4C8B-4E90-AF65091DE0C5}.Release|x86.Build.0 = Release|Any CPU + {7828C164-DD01-2809-CCB3-364486834F60}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {7828C164-DD01-2809-CCB3-364486834F60}.Debug|Any CPU.Build.0 = Debug|Any CPU + {7828C164-DD01-2809-CCB3-364486834F60}.Debug|x64.ActiveCfg = Debug|Any CPU + {7828C164-DD01-2809-CCB3-364486834F60}.Debug|x64.Build.0 = Debug|Any CPU + {7828C164-DD01-2809-CCB3-364486834F60}.Debug|x86.ActiveCfg = Debug|Any CPU + {7828C164-DD01-2809-CCB3-364486834F60}.Debug|x86.Build.0 = Debug|Any CPU + {7828C164-DD01-2809-CCB3-364486834F60}.Release|Any CPU.ActiveCfg = Release|Any CPU + {7828C164-DD01-2809-CCB3-364486834F60}.Release|Any CPU.Build.0 = Release|Any CPU + {7828C164-DD01-2809-CCB3-364486834F60}.Release|x64.ActiveCfg = Release|Any CPU + {7828C164-DD01-2809-CCB3-364486834F60}.Release|x64.Build.0 = Release|Any CPU + {7828C164-DD01-2809-CCB3-364486834F60}.Release|x86.ActiveCfg = Release|Any CPU + {7828C164-DD01-2809-CCB3-364486834F60}.Release|x86.Build.0 = Release|Any CPU + {DE95E7B2-0937-A980-441F-829E023BC43E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {DE95E7B2-0937-A980-441F-829E023BC43E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {DE95E7B2-0937-A980-441F-829E023BC43E}.Debug|x64.ActiveCfg = Debug|Any CPU + {DE95E7B2-0937-A980-441F-829E023BC43E}.Debug|x64.Build.0 = Debug|Any CPU + {DE95E7B2-0937-A980-441F-829E023BC43E}.Debug|x86.ActiveCfg = Debug|Any CPU + {DE95E7B2-0937-A980-441F-829E023BC43E}.Debug|x86.Build.0 = Debug|Any CPU + {DE95E7B2-0937-A980-441F-829E023BC43E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {DE95E7B2-0937-A980-441F-829E023BC43E}.Release|Any CPU.Build.0 = Release|Any CPU + {DE95E7B2-0937-A980-441F-829E023BC43E}.Release|x64.ActiveCfg = Release|Any CPU + {DE95E7B2-0937-A980-441F-829E023BC43E}.Release|x64.Build.0 = Release|Any CPU + {DE95E7B2-0937-A980-441F-829E023BC43E}.Release|x86.ActiveCfg = Release|Any CPU + {DE95E7B2-0937-A980-441F-829E023BC43E}.Release|x86.Build.0 = Release|Any CPU + {91D69463-23E2-E2C7-AA7E-A78B13CED620}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {91D69463-23E2-E2C7-AA7E-A78B13CED620}.Debug|Any CPU.Build.0 = Debug|Any CPU + {91D69463-23E2-E2C7-AA7E-A78B13CED620}.Debug|x64.ActiveCfg = Debug|Any CPU + {91D69463-23E2-E2C7-AA7E-A78B13CED620}.Debug|x64.Build.0 = Debug|Any CPU + {91D69463-23E2-E2C7-AA7E-A78B13CED620}.Debug|x86.ActiveCfg = Debug|Any CPU + {91D69463-23E2-E2C7-AA7E-A78B13CED620}.Debug|x86.Build.0 = Debug|Any CPU + {91D69463-23E2-E2C7-AA7E-A78B13CED620}.Release|Any CPU.ActiveCfg = Release|Any CPU + {91D69463-23E2-E2C7-AA7E-A78B13CED620}.Release|Any CPU.Build.0 = Release|Any CPU + {91D69463-23E2-E2C7-AA7E-A78B13CED620}.Release|x64.ActiveCfg = Release|Any CPU + {91D69463-23E2-E2C7-AA7E-A78B13CED620}.Release|x64.Build.0 = Release|Any CPU + {91D69463-23E2-E2C7-AA7E-A78B13CED620}.Release|x86.ActiveCfg = Release|Any CPU + {91D69463-23E2-E2C7-AA7E-A78B13CED620}.Release|x86.Build.0 = Release|Any CPU + {34EFF636-81A7-8DF6-7CC9-4DA784BAC7F3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {34EFF636-81A7-8DF6-7CC9-4DA784BAC7F3}.Debug|Any CPU.Build.0 = Debug|Any CPU + {34EFF636-81A7-8DF6-7CC9-4DA784BAC7F3}.Debug|x64.ActiveCfg = Debug|Any CPU + {34EFF636-81A7-8DF6-7CC9-4DA784BAC7F3}.Debug|x64.Build.0 = Debug|Any CPU + {34EFF636-81A7-8DF6-7CC9-4DA784BAC7F3}.Debug|x86.ActiveCfg = Debug|Any CPU + {34EFF636-81A7-8DF6-7CC9-4DA784BAC7F3}.Debug|x86.Build.0 = Debug|Any CPU + {34EFF636-81A7-8DF6-7CC9-4DA784BAC7F3}.Release|Any CPU.ActiveCfg = Release|Any CPU + {34EFF636-81A7-8DF6-7CC9-4DA784BAC7F3}.Release|Any CPU.Build.0 = Release|Any CPU + {34EFF636-81A7-8DF6-7CC9-4DA784BAC7F3}.Release|x64.ActiveCfg = Release|Any CPU + {34EFF636-81A7-8DF6-7CC9-4DA784BAC7F3}.Release|x64.Build.0 = Release|Any CPU + {34EFF636-81A7-8DF6-7CC9-4DA784BAC7F3}.Release|x86.ActiveCfg = Release|Any CPU + {34EFF636-81A7-8DF6-7CC9-4DA784BAC7F3}.Release|x86.Build.0 = Release|Any CPU + {5DCF16A8-97C6-2CB4-6A63-0370239039EB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {5DCF16A8-97C6-2CB4-6A63-0370239039EB}.Debug|Any CPU.Build.0 = Debug|Any CPU + {5DCF16A8-97C6-2CB4-6A63-0370239039EB}.Debug|x64.ActiveCfg = Debug|Any CPU + {5DCF16A8-97C6-2CB4-6A63-0370239039EB}.Debug|x64.Build.0 = Debug|Any CPU + {5DCF16A8-97C6-2CB4-6A63-0370239039EB}.Debug|x86.ActiveCfg = Debug|Any CPU + {5DCF16A8-97C6-2CB4-6A63-0370239039EB}.Debug|x86.Build.0 = Debug|Any CPU + {5DCF16A8-97C6-2CB4-6A63-0370239039EB}.Release|Any CPU.ActiveCfg = Release|Any CPU + {5DCF16A8-97C6-2CB4-6A63-0370239039EB}.Release|Any CPU.Build.0 = Release|Any CPU + {5DCF16A8-97C6-2CB4-6A63-0370239039EB}.Release|x64.ActiveCfg = Release|Any CPU + {5DCF16A8-97C6-2CB4-6A63-0370239039EB}.Release|x64.Build.0 = Release|Any CPU + {5DCF16A8-97C6-2CB4-6A63-0370239039EB}.Release|x86.ActiveCfg = Release|Any CPU + {5DCF16A8-97C6-2CB4-6A63-0370239039EB}.Release|x86.Build.0 = Release|Any CPU + {EB093C48-CDAC-106B-1196-AE34809B34C0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {EB093C48-CDAC-106B-1196-AE34809B34C0}.Debug|Any CPU.Build.0 = Debug|Any CPU + {EB093C48-CDAC-106B-1196-AE34809B34C0}.Debug|x64.ActiveCfg = Debug|Any CPU + {EB093C48-CDAC-106B-1196-AE34809B34C0}.Debug|x64.Build.0 = Debug|Any CPU + {EB093C48-CDAC-106B-1196-AE34809B34C0}.Debug|x86.ActiveCfg = Debug|Any CPU + {EB093C48-CDAC-106B-1196-AE34809B34C0}.Debug|x86.Build.0 = Debug|Any CPU + {EB093C48-CDAC-106B-1196-AE34809B34C0}.Release|Any CPU.ActiveCfg = Release|Any CPU + {EB093C48-CDAC-106B-1196-AE34809B34C0}.Release|Any CPU.Build.0 = Release|Any CPU + {EB093C48-CDAC-106B-1196-AE34809B34C0}.Release|x64.ActiveCfg = Release|Any CPU + {EB093C48-CDAC-106B-1196-AE34809B34C0}.Release|x64.Build.0 = Release|Any CPU + {EB093C48-CDAC-106B-1196-AE34809B34C0}.Release|x86.ActiveCfg = Release|Any CPU + {EB093C48-CDAC-106B-1196-AE34809B34C0}.Release|x86.Build.0 = Release|Any CPU + {370A79BD-AAB3-B833-2B06-A28B3A19E153}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {370A79BD-AAB3-B833-2B06-A28B3A19E153}.Debug|Any CPU.Build.0 = Debug|Any CPU + {370A79BD-AAB3-B833-2B06-A28B3A19E153}.Debug|x64.ActiveCfg = Debug|Any CPU + {370A79BD-AAB3-B833-2B06-A28B3A19E153}.Debug|x64.Build.0 = Debug|Any CPU + {370A79BD-AAB3-B833-2B06-A28B3A19E153}.Debug|x86.ActiveCfg = Debug|Any CPU + {370A79BD-AAB3-B833-2B06-A28B3A19E153}.Debug|x86.Build.0 = Debug|Any CPU + {370A79BD-AAB3-B833-2B06-A28B3A19E153}.Release|Any CPU.ActiveCfg = Release|Any CPU + {370A79BD-AAB3-B833-2B06-A28B3A19E153}.Release|Any CPU.Build.0 = Release|Any CPU + {370A79BD-AAB3-B833-2B06-A28B3A19E153}.Release|x64.ActiveCfg = Release|Any CPU + {370A79BD-AAB3-B833-2B06-A28B3A19E153}.Release|x64.Build.0 = Release|Any CPU + {370A79BD-AAB3-B833-2B06-A28B3A19E153}.Release|x86.ActiveCfg = Release|Any CPU + {370A79BD-AAB3-B833-2B06-A28B3A19E153}.Release|x86.Build.0 = Release|Any CPU + {92C62F7B-8028-6EE1-B71B-F45F459B8E97}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {92C62F7B-8028-6EE1-B71B-F45F459B8E97}.Debug|Any CPU.Build.0 = Debug|Any CPU + {92C62F7B-8028-6EE1-B71B-F45F459B8E97}.Debug|x64.ActiveCfg = Debug|Any CPU + {92C62F7B-8028-6EE1-B71B-F45F459B8E97}.Debug|x64.Build.0 = Debug|Any CPU + {92C62F7B-8028-6EE1-B71B-F45F459B8E97}.Debug|x86.ActiveCfg = Debug|Any CPU + {92C62F7B-8028-6EE1-B71B-F45F459B8E97}.Debug|x86.Build.0 = Debug|Any CPU + {92C62F7B-8028-6EE1-B71B-F45F459B8E97}.Release|Any CPU.ActiveCfg = Release|Any CPU + {92C62F7B-8028-6EE1-B71B-F45F459B8E97}.Release|Any CPU.Build.0 = Release|Any CPU + {92C62F7B-8028-6EE1-B71B-F45F459B8E97}.Release|x64.ActiveCfg = Release|Any CPU + {92C62F7B-8028-6EE1-B71B-F45F459B8E97}.Release|x64.Build.0 = Release|Any CPU + {92C62F7B-8028-6EE1-B71B-F45F459B8E97}.Release|x86.ActiveCfg = Release|Any CPU + {92C62F7B-8028-6EE1-B71B-F45F459B8E97}.Release|x86.Build.0 = Release|Any CPU + {F664A948-E352-5808-E780-77A03F19E93E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F664A948-E352-5808-E780-77A03F19E93E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F664A948-E352-5808-E780-77A03F19E93E}.Debug|x64.ActiveCfg = Debug|Any CPU + {F664A948-E352-5808-E780-77A03F19E93E}.Debug|x64.Build.0 = Debug|Any CPU + {F664A948-E352-5808-E780-77A03F19E93E}.Debug|x86.ActiveCfg = Debug|Any CPU + {F664A948-E352-5808-E780-77A03F19E93E}.Debug|x86.Build.0 = Debug|Any CPU + {F664A948-E352-5808-E780-77A03F19E93E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F664A948-E352-5808-E780-77A03F19E93E}.Release|Any CPU.Build.0 = Release|Any CPU + {F664A948-E352-5808-E780-77A03F19E93E}.Release|x64.ActiveCfg = Release|Any CPU + {F664A948-E352-5808-E780-77A03F19E93E}.Release|x64.Build.0 = Release|Any CPU + {F664A948-E352-5808-E780-77A03F19E93E}.Release|x86.ActiveCfg = Release|Any CPU + {F664A948-E352-5808-E780-77A03F19E93E}.Release|x86.Build.0 = Release|Any CPU + {FA83F778-5252-0B80-5555-E69F790322EA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {FA83F778-5252-0B80-5555-E69F790322EA}.Debug|Any CPU.Build.0 = Debug|Any CPU + {FA83F778-5252-0B80-5555-E69F790322EA}.Debug|x64.ActiveCfg = Debug|Any CPU + {FA83F778-5252-0B80-5555-E69F790322EA}.Debug|x64.Build.0 = Debug|Any CPU + {FA83F778-5252-0B80-5555-E69F790322EA}.Debug|x86.ActiveCfg = Debug|Any CPU + {FA83F778-5252-0B80-5555-E69F790322EA}.Debug|x86.Build.0 = Debug|Any CPU + {FA83F778-5252-0B80-5555-E69F790322EA}.Release|Any CPU.ActiveCfg = Release|Any CPU + {FA83F778-5252-0B80-5555-E69F790322EA}.Release|Any CPU.Build.0 = Release|Any CPU + {FA83F778-5252-0B80-5555-E69F790322EA}.Release|x64.ActiveCfg = Release|Any CPU + {FA83F778-5252-0B80-5555-E69F790322EA}.Release|x64.Build.0 = Release|Any CPU + {FA83F778-5252-0B80-5555-E69F790322EA}.Release|x86.ActiveCfg = Release|Any CPU + {FA83F778-5252-0B80-5555-E69F790322EA}.Release|x86.Build.0 = Release|Any CPU + {F3A27846-6DE0-3448-222C-25A273E86B2E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F3A27846-6DE0-3448-222C-25A273E86B2E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F3A27846-6DE0-3448-222C-25A273E86B2E}.Debug|x64.ActiveCfg = Debug|Any CPU + {F3A27846-6DE0-3448-222C-25A273E86B2E}.Debug|x64.Build.0 = Debug|Any CPU + {F3A27846-6DE0-3448-222C-25A273E86B2E}.Debug|x86.ActiveCfg = Debug|Any CPU + {F3A27846-6DE0-3448-222C-25A273E86B2E}.Debug|x86.Build.0 = Debug|Any CPU + {F3A27846-6DE0-3448-222C-25A273E86B2E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F3A27846-6DE0-3448-222C-25A273E86B2E}.Release|Any CPU.Build.0 = Release|Any CPU + {F3A27846-6DE0-3448-222C-25A273E86B2E}.Release|x64.ActiveCfg = Release|Any CPU + {F3A27846-6DE0-3448-222C-25A273E86B2E}.Release|x64.Build.0 = Release|Any CPU + {F3A27846-6DE0-3448-222C-25A273E86B2E}.Release|x86.ActiveCfg = Release|Any CPU + {F3A27846-6DE0-3448-222C-25A273E86B2E}.Release|x86.Build.0 = Release|Any CPU + {C53E0895-879A-D9E6-0A43-24AD17A2F270}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C53E0895-879A-D9E6-0A43-24AD17A2F270}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C53E0895-879A-D9E6-0A43-24AD17A2F270}.Debug|x64.ActiveCfg = Debug|Any CPU + {C53E0895-879A-D9E6-0A43-24AD17A2F270}.Debug|x64.Build.0 = Debug|Any CPU + {C53E0895-879A-D9E6-0A43-24AD17A2F270}.Debug|x86.ActiveCfg = Debug|Any CPU + {C53E0895-879A-D9E6-0A43-24AD17A2F270}.Debug|x86.Build.0 = Debug|Any CPU + {C53E0895-879A-D9E6-0A43-24AD17A2F270}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C53E0895-879A-D9E6-0A43-24AD17A2F270}.Release|Any CPU.Build.0 = Release|Any CPU + {C53E0895-879A-D9E6-0A43-24AD17A2F270}.Release|x64.ActiveCfg = Release|Any CPU + {C53E0895-879A-D9E6-0A43-24AD17A2F270}.Release|x64.Build.0 = Release|Any CPU + {C53E0895-879A-D9E6-0A43-24AD17A2F270}.Release|x86.ActiveCfg = Release|Any CPU + {C53E0895-879A-D9E6-0A43-24AD17A2F270}.Release|x86.Build.0 = Release|Any CPU + {0AED303F-69E6-238F-EF80-81985080EDB7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {0AED303F-69E6-238F-EF80-81985080EDB7}.Debug|Any CPU.Build.0 = Debug|Any CPU + {0AED303F-69E6-238F-EF80-81985080EDB7}.Debug|x64.ActiveCfg = Debug|Any CPU + {0AED303F-69E6-238F-EF80-81985080EDB7}.Debug|x64.Build.0 = Debug|Any CPU + {0AED303F-69E6-238F-EF80-81985080EDB7}.Debug|x86.ActiveCfg = Debug|Any CPU + {0AED303F-69E6-238F-EF80-81985080EDB7}.Debug|x86.Build.0 = Debug|Any CPU + {0AED303F-69E6-238F-EF80-81985080EDB7}.Release|Any CPU.ActiveCfg = Release|Any CPU + {0AED303F-69E6-238F-EF80-81985080EDB7}.Release|Any CPU.Build.0 = Release|Any CPU + {0AED303F-69E6-238F-EF80-81985080EDB7}.Release|x64.ActiveCfg = Release|Any CPU + {0AED303F-69E6-238F-EF80-81985080EDB7}.Release|x64.Build.0 = Release|Any CPU + {0AED303F-69E6-238F-EF80-81985080EDB7}.Release|x86.ActiveCfg = Release|Any CPU + {0AED303F-69E6-238F-EF80-81985080EDB7}.Release|x86.Build.0 = Release|Any CPU + {2904D288-CE64-A565-2C46-C2E85A96A1EE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {2904D288-CE64-A565-2C46-C2E85A96A1EE}.Debug|Any CPU.Build.0 = Debug|Any CPU + {2904D288-CE64-A565-2C46-C2E85A96A1EE}.Debug|x64.ActiveCfg = Debug|Any CPU + {2904D288-CE64-A565-2C46-C2E85A96A1EE}.Debug|x64.Build.0 = Debug|Any CPU + {2904D288-CE64-A565-2C46-C2E85A96A1EE}.Debug|x86.ActiveCfg = Debug|Any CPU + {2904D288-CE64-A565-2C46-C2E85A96A1EE}.Debug|x86.Build.0 = Debug|Any CPU + {2904D288-CE64-A565-2C46-C2E85A96A1EE}.Release|Any CPU.ActiveCfg = Release|Any CPU + {2904D288-CE64-A565-2C46-C2E85A96A1EE}.Release|Any CPU.Build.0 = Release|Any CPU + {2904D288-CE64-A565-2C46-C2E85A96A1EE}.Release|x64.ActiveCfg = Release|Any CPU + {2904D288-CE64-A565-2C46-C2E85A96A1EE}.Release|x64.Build.0 = Release|Any CPU + {2904D288-CE64-A565-2C46-C2E85A96A1EE}.Release|x86.ActiveCfg = Release|Any CPU + {2904D288-CE64-A565-2C46-C2E85A96A1EE}.Release|x86.Build.0 = Release|Any CPU + {A6667CC3-B77F-023E-3A67-05F99E9FF46A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A6667CC3-B77F-023E-3A67-05F99E9FF46A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A6667CC3-B77F-023E-3A67-05F99E9FF46A}.Debug|x64.ActiveCfg = Debug|Any CPU + {A6667CC3-B77F-023E-3A67-05F99E9FF46A}.Debug|x64.Build.0 = Debug|Any CPU + {A6667CC3-B77F-023E-3A67-05F99E9FF46A}.Debug|x86.ActiveCfg = Debug|Any CPU + {A6667CC3-B77F-023E-3A67-05F99E9FF46A}.Debug|x86.Build.0 = Debug|Any CPU + {A6667CC3-B77F-023E-3A67-05F99E9FF46A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A6667CC3-B77F-023E-3A67-05F99E9FF46A}.Release|Any CPU.Build.0 = Release|Any CPU + {A6667CC3-B77F-023E-3A67-05F99E9FF46A}.Release|x64.ActiveCfg = Release|Any CPU + {A6667CC3-B77F-023E-3A67-05F99E9FF46A}.Release|x64.Build.0 = Release|Any CPU + {A6667CC3-B77F-023E-3A67-05F99E9FF46A}.Release|x86.ActiveCfg = Release|Any CPU + {A6667CC3-B77F-023E-3A67-05F99E9FF46A}.Release|x86.Build.0 = Release|Any CPU + {A26E2816-F787-F76B-1D6C-E086DD3E19CE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A26E2816-F787-F76B-1D6C-E086DD3E19CE}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A26E2816-F787-F76B-1D6C-E086DD3E19CE}.Debug|x64.ActiveCfg = Debug|Any CPU + {A26E2816-F787-F76B-1D6C-E086DD3E19CE}.Debug|x64.Build.0 = Debug|Any CPU + {A26E2816-F787-F76B-1D6C-E086DD3E19CE}.Debug|x86.ActiveCfg = Debug|Any CPU + {A26E2816-F787-F76B-1D6C-E086DD3E19CE}.Debug|x86.Build.0 = Debug|Any CPU + {A26E2816-F787-F76B-1D6C-E086DD3E19CE}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A26E2816-F787-F76B-1D6C-E086DD3E19CE}.Release|Any CPU.Build.0 = Release|Any CPU + {A26E2816-F787-F76B-1D6C-E086DD3E19CE}.Release|x64.ActiveCfg = Release|Any CPU + {A26E2816-F787-F76B-1D6C-E086DD3E19CE}.Release|x64.Build.0 = Release|Any CPU + {A26E2816-F787-F76B-1D6C-E086DD3E19CE}.Release|x86.ActiveCfg = Release|Any CPU + {A26E2816-F787-F76B-1D6C-E086DD3E19CE}.Release|x86.Build.0 = Release|Any CPU + {B3DEC619-67AC-1B5A-4F3E-A1F24C3F6877}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B3DEC619-67AC-1B5A-4F3E-A1F24C3F6877}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B3DEC619-67AC-1B5A-4F3E-A1F24C3F6877}.Debug|x64.ActiveCfg = Debug|Any CPU + {B3DEC619-67AC-1B5A-4F3E-A1F24C3F6877}.Debug|x64.Build.0 = Debug|Any CPU + {B3DEC619-67AC-1B5A-4F3E-A1F24C3F6877}.Debug|x86.ActiveCfg = Debug|Any CPU + {B3DEC619-67AC-1B5A-4F3E-A1F24C3F6877}.Debug|x86.Build.0 = Debug|Any CPU + {B3DEC619-67AC-1B5A-4F3E-A1F24C3F6877}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B3DEC619-67AC-1B5A-4F3E-A1F24C3F6877}.Release|Any CPU.Build.0 = Release|Any CPU + {B3DEC619-67AC-1B5A-4F3E-A1F24C3F6877}.Release|x64.ActiveCfg = Release|Any CPU + {B3DEC619-67AC-1B5A-4F3E-A1F24C3F6877}.Release|x64.Build.0 = Release|Any CPU + {B3DEC619-67AC-1B5A-4F3E-A1F24C3F6877}.Release|x86.ActiveCfg = Release|Any CPU + {B3DEC619-67AC-1B5A-4F3E-A1F24C3F6877}.Release|x86.Build.0 = Release|Any CPU + {90DB65B4-8F6E-FB8E-0281-505AD8BC6BA6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {90DB65B4-8F6E-FB8E-0281-505AD8BC6BA6}.Debug|Any CPU.Build.0 = Debug|Any CPU + {90DB65B4-8F6E-FB8E-0281-505AD8BC6BA6}.Debug|x64.ActiveCfg = Debug|Any CPU + {90DB65B4-8F6E-FB8E-0281-505AD8BC6BA6}.Debug|x64.Build.0 = Debug|Any CPU + {90DB65B4-8F6E-FB8E-0281-505AD8BC6BA6}.Debug|x86.ActiveCfg = Debug|Any CPU + {90DB65B4-8F6E-FB8E-0281-505AD8BC6BA6}.Debug|x86.Build.0 = Debug|Any CPU + {90DB65B4-8F6E-FB8E-0281-505AD8BC6BA6}.Release|Any CPU.ActiveCfg = Release|Any CPU + {90DB65B4-8F6E-FB8E-0281-505AD8BC6BA6}.Release|Any CPU.Build.0 = Release|Any CPU + {90DB65B4-8F6E-FB8E-0281-505AD8BC6BA6}.Release|x64.ActiveCfg = Release|Any CPU + {90DB65B4-8F6E-FB8E-0281-505AD8BC6BA6}.Release|x64.Build.0 = Release|Any CPU + {90DB65B4-8F6E-FB8E-0281-505AD8BC6BA6}.Release|x86.ActiveCfg = Release|Any CPU + {90DB65B4-8F6E-FB8E-0281-505AD8BC6BA6}.Release|x86.Build.0 = Release|Any CPU + {059FBB86-DEE6-8207-3F23-2A1A3EC00DEA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {059FBB86-DEE6-8207-3F23-2A1A3EC00DEA}.Debug|Any CPU.Build.0 = Debug|Any CPU + {059FBB86-DEE6-8207-3F23-2A1A3EC00DEA}.Debug|x64.ActiveCfg = Debug|Any CPU + {059FBB86-DEE6-8207-3F23-2A1A3EC00DEA}.Debug|x64.Build.0 = Debug|Any CPU + {059FBB86-DEE6-8207-3F23-2A1A3EC00DEA}.Debug|x86.ActiveCfg = Debug|Any CPU + {059FBB86-DEE6-8207-3F23-2A1A3EC00DEA}.Debug|x86.Build.0 = Debug|Any CPU + {059FBB86-DEE6-8207-3F23-2A1A3EC00DEA}.Release|Any CPU.ActiveCfg = Release|Any CPU + {059FBB86-DEE6-8207-3F23-2A1A3EC00DEA}.Release|Any CPU.Build.0 = Release|Any CPU + {059FBB86-DEE6-8207-3F23-2A1A3EC00DEA}.Release|x64.ActiveCfg = Release|Any CPU + {059FBB86-DEE6-8207-3F23-2A1A3EC00DEA}.Release|x64.Build.0 = Release|Any CPU + {059FBB86-DEE6-8207-3F23-2A1A3EC00DEA}.Release|x86.ActiveCfg = Release|Any CPU + {059FBB86-DEE6-8207-3F23-2A1A3EC00DEA}.Release|x86.Build.0 = Release|Any CPU + {8BBA3159-C4CC-F685-A28C-7FE6CBD3D2A1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {8BBA3159-C4CC-F685-A28C-7FE6CBD3D2A1}.Debug|Any CPU.Build.0 = Debug|Any CPU + {8BBA3159-C4CC-F685-A28C-7FE6CBD3D2A1}.Debug|x64.ActiveCfg = Debug|Any CPU + {8BBA3159-C4CC-F685-A28C-7FE6CBD3D2A1}.Debug|x64.Build.0 = Debug|Any CPU + {8BBA3159-C4CC-F685-A28C-7FE6CBD3D2A1}.Debug|x86.ActiveCfg = Debug|Any CPU + {8BBA3159-C4CC-F685-A28C-7FE6CBD3D2A1}.Debug|x86.Build.0 = Debug|Any CPU + {8BBA3159-C4CC-F685-A28C-7FE6CBD3D2A1}.Release|Any CPU.ActiveCfg = Release|Any CPU + {8BBA3159-C4CC-F685-A28C-7FE6CBD3D2A1}.Release|Any CPU.Build.0 = Release|Any CPU + {8BBA3159-C4CC-F685-A28C-7FE6CBD3D2A1}.Release|x64.ActiveCfg = Release|Any CPU + {8BBA3159-C4CC-F685-A28C-7FE6CBD3D2A1}.Release|x64.Build.0 = Release|Any CPU + {8BBA3159-C4CC-F685-A28C-7FE6CBD3D2A1}.Release|x86.ActiveCfg = Release|Any CPU + {8BBA3159-C4CC-F685-A28C-7FE6CBD3D2A1}.Release|x86.Build.0 = Release|Any CPU + {632A1F0D-1BA5-C84B-B716-2BE638A92780}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {632A1F0D-1BA5-C84B-B716-2BE638A92780}.Debug|Any CPU.Build.0 = Debug|Any CPU + {632A1F0D-1BA5-C84B-B716-2BE638A92780}.Debug|x64.ActiveCfg = Debug|Any CPU + {632A1F0D-1BA5-C84B-B716-2BE638A92780}.Debug|x64.Build.0 = Debug|Any CPU + {632A1F0D-1BA5-C84B-B716-2BE638A92780}.Debug|x86.ActiveCfg = Debug|Any CPU + {632A1F0D-1BA5-C84B-B716-2BE638A92780}.Debug|x86.Build.0 = Debug|Any CPU + {632A1F0D-1BA5-C84B-B716-2BE638A92780}.Release|Any CPU.ActiveCfg = Release|Any CPU + {632A1F0D-1BA5-C84B-B716-2BE638A92780}.Release|Any CPU.Build.0 = Release|Any CPU + {632A1F0D-1BA5-C84B-B716-2BE638A92780}.Release|x64.ActiveCfg = Release|Any CPU + {632A1F0D-1BA5-C84B-B716-2BE638A92780}.Release|x64.Build.0 = Release|Any CPU + {632A1F0D-1BA5-C84B-B716-2BE638A92780}.Release|x86.ActiveCfg = Release|Any CPU + {632A1F0D-1BA5-C84B-B716-2BE638A92780}.Release|x86.Build.0 = Release|Any CPU + {9DE7852B-7E2D-257E-B0F1-45D2687854ED}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {9DE7852B-7E2D-257E-B0F1-45D2687854ED}.Debug|Any CPU.Build.0 = Debug|Any CPU + {9DE7852B-7E2D-257E-B0F1-45D2687854ED}.Debug|x64.ActiveCfg = Debug|Any CPU + {9DE7852B-7E2D-257E-B0F1-45D2687854ED}.Debug|x64.Build.0 = Debug|Any CPU + {9DE7852B-7E2D-257E-B0F1-45D2687854ED}.Debug|x86.ActiveCfg = Debug|Any CPU + {9DE7852B-7E2D-257E-B0F1-45D2687854ED}.Debug|x86.Build.0 = Debug|Any CPU + {9DE7852B-7E2D-257E-B0F1-45D2687854ED}.Release|Any CPU.ActiveCfg = Release|Any CPU + {9DE7852B-7E2D-257E-B0F1-45D2687854ED}.Release|Any CPU.Build.0 = Release|Any CPU + {9DE7852B-7E2D-257E-B0F1-45D2687854ED}.Release|x64.ActiveCfg = Release|Any CPU + {9DE7852B-7E2D-257E-B0F1-45D2687854ED}.Release|x64.Build.0 = Release|Any CPU + {9DE7852B-7E2D-257E-B0F1-45D2687854ED}.Release|x86.ActiveCfg = Release|Any CPU + {9DE7852B-7E2D-257E-B0F1-45D2687854ED}.Release|x86.Build.0 = Release|Any CPU + {DC2AFC89-C3C8-4E9B-13A7-027EB6386EFA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {DC2AFC89-C3C8-4E9B-13A7-027EB6386EFA}.Debug|Any CPU.Build.0 = Debug|Any CPU + {DC2AFC89-C3C8-4E9B-13A7-027EB6386EFA}.Debug|x64.ActiveCfg = Debug|Any CPU + {DC2AFC89-C3C8-4E9B-13A7-027EB6386EFA}.Debug|x64.Build.0 = Debug|Any CPU + {DC2AFC89-C3C8-4E9B-13A7-027EB6386EFA}.Debug|x86.ActiveCfg = Debug|Any CPU + {DC2AFC89-C3C8-4E9B-13A7-027EB6386EFA}.Debug|x86.Build.0 = Debug|Any CPU + {DC2AFC89-C3C8-4E9B-13A7-027EB6386EFA}.Release|Any CPU.ActiveCfg = Release|Any CPU + {DC2AFC89-C3C8-4E9B-13A7-027EB6386EFA}.Release|Any CPU.Build.0 = Release|Any CPU + {DC2AFC89-C3C8-4E9B-13A7-027EB6386EFA}.Release|x64.ActiveCfg = Release|Any CPU + {DC2AFC89-C3C8-4E9B-13A7-027EB6386EFA}.Release|x64.Build.0 = Release|Any CPU + {DC2AFC89-C3C8-4E9B-13A7-027EB6386EFA}.Release|x86.ActiveCfg = Release|Any CPU + {DC2AFC89-C3C8-4E9B-13A7-027EB6386EFA}.Release|x86.Build.0 = Release|Any CPU + {CB296A20-2732-77C1-7F23-27D5BAEDD0C7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {CB296A20-2732-77C1-7F23-27D5BAEDD0C7}.Debug|Any CPU.Build.0 = Debug|Any CPU + {CB296A20-2732-77C1-7F23-27D5BAEDD0C7}.Debug|x64.ActiveCfg = Debug|Any CPU + {CB296A20-2732-77C1-7F23-27D5BAEDD0C7}.Debug|x64.Build.0 = Debug|Any CPU + {CB296A20-2732-77C1-7F23-27D5BAEDD0C7}.Debug|x86.ActiveCfg = Debug|Any CPU + {CB296A20-2732-77C1-7F23-27D5BAEDD0C7}.Debug|x86.Build.0 = Debug|Any CPU + {CB296A20-2732-77C1-7F23-27D5BAEDD0C7}.Release|Any CPU.ActiveCfg = Release|Any CPU + {CB296A20-2732-77C1-7F23-27D5BAEDD0C7}.Release|Any CPU.Build.0 = Release|Any CPU + {CB296A20-2732-77C1-7F23-27D5BAEDD0C7}.Release|x64.ActiveCfg = Release|Any CPU + {CB296A20-2732-77C1-7F23-27D5BAEDD0C7}.Release|x64.Build.0 = Release|Any CPU + {CB296A20-2732-77C1-7F23-27D5BAEDD0C7}.Release|x86.ActiveCfg = Release|Any CPU + {CB296A20-2732-77C1-7F23-27D5BAEDD0C7}.Release|x86.Build.0 = Release|Any CPU + {0DBEC9BA-FE1D-3898-B2C6-E4357DC23E0F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {0DBEC9BA-FE1D-3898-B2C6-E4357DC23E0F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {0DBEC9BA-FE1D-3898-B2C6-E4357DC23E0F}.Debug|x64.ActiveCfg = Debug|Any CPU + {0DBEC9BA-FE1D-3898-B2C6-E4357DC23E0F}.Debug|x64.Build.0 = Debug|Any CPU + {0DBEC9BA-FE1D-3898-B2C6-E4357DC23E0F}.Debug|x86.ActiveCfg = Debug|Any CPU + {0DBEC9BA-FE1D-3898-B2C6-E4357DC23E0F}.Debug|x86.Build.0 = Debug|Any CPU + {0DBEC9BA-FE1D-3898-B2C6-E4357DC23E0F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {0DBEC9BA-FE1D-3898-B2C6-E4357DC23E0F}.Release|Any CPU.Build.0 = Release|Any CPU + {0DBEC9BA-FE1D-3898-B2C6-E4357DC23E0F}.Release|x64.ActiveCfg = Release|Any CPU + {0DBEC9BA-FE1D-3898-B2C6-E4357DC23E0F}.Release|x64.Build.0 = Release|Any CPU + {0DBEC9BA-FE1D-3898-B2C6-E4357DC23E0F}.Release|x86.ActiveCfg = Release|Any CPU + {0DBEC9BA-FE1D-3898-B2C6-E4357DC23E0F}.Release|x86.Build.0 = Release|Any CPU + {A63897D9-9531-989B-7309-E384BCFC2BB9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A63897D9-9531-989B-7309-E384BCFC2BB9}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A63897D9-9531-989B-7309-E384BCFC2BB9}.Debug|x64.ActiveCfg = Debug|Any CPU + {A63897D9-9531-989B-7309-E384BCFC2BB9}.Debug|x64.Build.0 = Debug|Any CPU + {A63897D9-9531-989B-7309-E384BCFC2BB9}.Debug|x86.ActiveCfg = Debug|Any CPU + {A63897D9-9531-989B-7309-E384BCFC2BB9}.Debug|x86.Build.0 = Debug|Any CPU + {A63897D9-9531-989B-7309-E384BCFC2BB9}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A63897D9-9531-989B-7309-E384BCFC2BB9}.Release|Any CPU.Build.0 = Release|Any CPU + {A63897D9-9531-989B-7309-E384BCFC2BB9}.Release|x64.ActiveCfg = Release|Any CPU + {A63897D9-9531-989B-7309-E384BCFC2BB9}.Release|x64.Build.0 = Release|Any CPU + {A63897D9-9531-989B-7309-E384BCFC2BB9}.Release|x86.ActiveCfg = Release|Any CPU + {A63897D9-9531-989B-7309-E384BCFC2BB9}.Release|x86.Build.0 = Release|Any CPU + {8C594D82-3463-3367-4F06-900AC707753D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {8C594D82-3463-3367-4F06-900AC707753D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {8C594D82-3463-3367-4F06-900AC707753D}.Debug|x64.ActiveCfg = Debug|Any CPU + {8C594D82-3463-3367-4F06-900AC707753D}.Debug|x64.Build.0 = Debug|Any CPU + {8C594D82-3463-3367-4F06-900AC707753D}.Debug|x86.ActiveCfg = Debug|Any CPU + {8C594D82-3463-3367-4F06-900AC707753D}.Debug|x86.Build.0 = Debug|Any CPU + {8C594D82-3463-3367-4F06-900AC707753D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {8C594D82-3463-3367-4F06-900AC707753D}.Release|Any CPU.Build.0 = Release|Any CPU + {8C594D82-3463-3367-4F06-900AC707753D}.Release|x64.ActiveCfg = Release|Any CPU + {8C594D82-3463-3367-4F06-900AC707753D}.Release|x64.Build.0 = Release|Any CPU + {8C594D82-3463-3367-4F06-900AC707753D}.Release|x86.ActiveCfg = Release|Any CPU + {8C594D82-3463-3367-4F06-900AC707753D}.Release|x86.Build.0 = Release|Any CPU + {52F400CD-D473-7A1F-7986-89011CD2A887}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {52F400CD-D473-7A1F-7986-89011CD2A887}.Debug|Any CPU.Build.0 = Debug|Any CPU + {52F400CD-D473-7A1F-7986-89011CD2A887}.Debug|x64.ActiveCfg = Debug|Any CPU + {52F400CD-D473-7A1F-7986-89011CD2A887}.Debug|x64.Build.0 = Debug|Any CPU + {52F400CD-D473-7A1F-7986-89011CD2A887}.Debug|x86.ActiveCfg = Debug|Any CPU + {52F400CD-D473-7A1F-7986-89011CD2A887}.Debug|x86.Build.0 = Debug|Any CPU + {52F400CD-D473-7A1F-7986-89011CD2A887}.Release|Any CPU.ActiveCfg = Release|Any CPU + {52F400CD-D473-7A1F-7986-89011CD2A887}.Release|Any CPU.Build.0 = Release|Any CPU + {52F400CD-D473-7A1F-7986-89011CD2A887}.Release|x64.ActiveCfg = Release|Any CPU + {52F400CD-D473-7A1F-7986-89011CD2A887}.Release|x64.Build.0 = Release|Any CPU + {52F400CD-D473-7A1F-7986-89011CD2A887}.Release|x86.ActiveCfg = Release|Any CPU + {52F400CD-D473-7A1F-7986-89011CD2A887}.Release|x86.Build.0 = Release|Any CPU + {9588FBF9-C37E-D16E-2E8F-CFA226EAC01D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {9588FBF9-C37E-D16E-2E8F-CFA226EAC01D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {9588FBF9-C37E-D16E-2E8F-CFA226EAC01D}.Debug|x64.ActiveCfg = Debug|Any CPU + {9588FBF9-C37E-D16E-2E8F-CFA226EAC01D}.Debug|x64.Build.0 = Debug|Any CPU + {9588FBF9-C37E-D16E-2E8F-CFA226EAC01D}.Debug|x86.ActiveCfg = Debug|Any CPU + {9588FBF9-C37E-D16E-2E8F-CFA226EAC01D}.Debug|x86.Build.0 = Debug|Any CPU + {9588FBF9-C37E-D16E-2E8F-CFA226EAC01D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {9588FBF9-C37E-D16E-2E8F-CFA226EAC01D}.Release|Any CPU.Build.0 = Release|Any CPU + {9588FBF9-C37E-D16E-2E8F-CFA226EAC01D}.Release|x64.ActiveCfg = Release|Any CPU + {9588FBF9-C37E-D16E-2E8F-CFA226EAC01D}.Release|x64.Build.0 = Release|Any CPU + {9588FBF9-C37E-D16E-2E8F-CFA226EAC01D}.Release|x86.ActiveCfg = Release|Any CPU + {9588FBF9-C37E-D16E-2E8F-CFA226EAC01D}.Release|x86.Build.0 = Release|Any CPU + {97998C88-E6E1-D5E2-B632-537B58E00CBF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {97998C88-E6E1-D5E2-B632-537B58E00CBF}.Debug|Any CPU.Build.0 = Debug|Any CPU + {97998C88-E6E1-D5E2-B632-537B58E00CBF}.Debug|x64.ActiveCfg = Debug|Any CPU + {97998C88-E6E1-D5E2-B632-537B58E00CBF}.Debug|x64.Build.0 = Debug|Any CPU + {97998C88-E6E1-D5E2-B632-537B58E00CBF}.Debug|x86.ActiveCfg = Debug|Any CPU + {97998C88-E6E1-D5E2-B632-537B58E00CBF}.Debug|x86.Build.0 = Debug|Any CPU + {97998C88-E6E1-D5E2-B632-537B58E00CBF}.Release|Any CPU.ActiveCfg = Release|Any CPU + {97998C88-E6E1-D5E2-B632-537B58E00CBF}.Release|Any CPU.Build.0 = Release|Any CPU + {97998C88-E6E1-D5E2-B632-537B58E00CBF}.Release|x64.ActiveCfg = Release|Any CPU + {97998C88-E6E1-D5E2-B632-537B58E00CBF}.Release|x64.Build.0 = Release|Any CPU + {97998C88-E6E1-D5E2-B632-537B58E00CBF}.Release|x86.ActiveCfg = Release|Any CPU + {97998C88-E6E1-D5E2-B632-537B58E00CBF}.Release|x86.Build.0 = Release|Any CPU + {38A9EE9B-6FC8-93BC-0D43-2A906E678D66}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {38A9EE9B-6FC8-93BC-0D43-2A906E678D66}.Debug|Any CPU.Build.0 = Debug|Any CPU + {38A9EE9B-6FC8-93BC-0D43-2A906E678D66}.Debug|x64.ActiveCfg = Debug|Any CPU + {38A9EE9B-6FC8-93BC-0D43-2A906E678D66}.Debug|x64.Build.0 = Debug|Any CPU + {38A9EE9B-6FC8-93BC-0D43-2A906E678D66}.Debug|x86.ActiveCfg = Debug|Any CPU + {38A9EE9B-6FC8-93BC-0D43-2A906E678D66}.Debug|x86.Build.0 = Debug|Any CPU + {38A9EE9B-6FC8-93BC-0D43-2A906E678D66}.Release|Any CPU.ActiveCfg = Release|Any CPU + {38A9EE9B-6FC8-93BC-0D43-2A906E678D66}.Release|Any CPU.Build.0 = Release|Any CPU + {38A9EE9B-6FC8-93BC-0D43-2A906E678D66}.Release|x64.ActiveCfg = Release|Any CPU + {38A9EE9B-6FC8-93BC-0D43-2A906E678D66}.Release|x64.Build.0 = Release|Any CPU + {38A9EE9B-6FC8-93BC-0D43-2A906E678D66}.Release|x86.ActiveCfg = Release|Any CPU + {38A9EE9B-6FC8-93BC-0D43-2A906E678D66}.Release|x86.Build.0 = Release|Any CPU + {19868E2D-7163-2108-1094-F13887C4F070}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {19868E2D-7163-2108-1094-F13887C4F070}.Debug|Any CPU.Build.0 = Debug|Any CPU + {19868E2D-7163-2108-1094-F13887C4F070}.Debug|x64.ActiveCfg = Debug|Any CPU + {19868E2D-7163-2108-1094-F13887C4F070}.Debug|x64.Build.0 = Debug|Any CPU + {19868E2D-7163-2108-1094-F13887C4F070}.Debug|x86.ActiveCfg = Debug|Any CPU + {19868E2D-7163-2108-1094-F13887C4F070}.Debug|x86.Build.0 = Debug|Any CPU + {19868E2D-7163-2108-1094-F13887C4F070}.Release|Any CPU.ActiveCfg = Release|Any CPU + {19868E2D-7163-2108-1094-F13887C4F070}.Release|Any CPU.Build.0 = Release|Any CPU + {19868E2D-7163-2108-1094-F13887C4F070}.Release|x64.ActiveCfg = Release|Any CPU + {19868E2D-7163-2108-1094-F13887C4F070}.Release|x64.Build.0 = Release|Any CPU + {19868E2D-7163-2108-1094-F13887C4F070}.Release|x86.ActiveCfg = Release|Any CPU + {19868E2D-7163-2108-1094-F13887C4F070}.Release|x86.Build.0 = Release|Any CPU + {CC319FC5-F4B1-C3DD-7310-4DAD343E0125}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {CC319FC5-F4B1-C3DD-7310-4DAD343E0125}.Debug|Any CPU.Build.0 = Debug|Any CPU + {CC319FC5-F4B1-C3DD-7310-4DAD343E0125}.Debug|x64.ActiveCfg = Debug|Any CPU + {CC319FC5-F4B1-C3DD-7310-4DAD343E0125}.Debug|x64.Build.0 = Debug|Any CPU + {CC319FC5-F4B1-C3DD-7310-4DAD343E0125}.Debug|x86.ActiveCfg = Debug|Any CPU + {CC319FC5-F4B1-C3DD-7310-4DAD343E0125}.Debug|x86.Build.0 = Debug|Any CPU + {CC319FC5-F4B1-C3DD-7310-4DAD343E0125}.Release|Any CPU.ActiveCfg = Release|Any CPU + {CC319FC5-F4B1-C3DD-7310-4DAD343E0125}.Release|Any CPU.Build.0 = Release|Any CPU + {CC319FC5-F4B1-C3DD-7310-4DAD343E0125}.Release|x64.ActiveCfg = Release|Any CPU + {CC319FC5-F4B1-C3DD-7310-4DAD343E0125}.Release|x64.Build.0 = Release|Any CPU + {CC319FC5-F4B1-C3DD-7310-4DAD343E0125}.Release|x86.ActiveCfg = Release|Any CPU + {CC319FC5-F4B1-C3DD-7310-4DAD343E0125}.Release|x86.Build.0 = Release|Any CPU + {84F711C2-C210-28D2-F0D9-B13733FEE23D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {84F711C2-C210-28D2-F0D9-B13733FEE23D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {84F711C2-C210-28D2-F0D9-B13733FEE23D}.Debug|x64.ActiveCfg = Debug|Any CPU + {84F711C2-C210-28D2-F0D9-B13733FEE23D}.Debug|x64.Build.0 = Debug|Any CPU + {84F711C2-C210-28D2-F0D9-B13733FEE23D}.Debug|x86.ActiveCfg = Debug|Any CPU + {84F711C2-C210-28D2-F0D9-B13733FEE23D}.Debug|x86.Build.0 = Debug|Any CPU + {84F711C2-C210-28D2-F0D9-B13733FEE23D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {84F711C2-C210-28D2-F0D9-B13733FEE23D}.Release|Any CPU.Build.0 = Release|Any CPU + {84F711C2-C210-28D2-F0D9-B13733FEE23D}.Release|x64.ActiveCfg = Release|Any CPU + {84F711C2-C210-28D2-F0D9-B13733FEE23D}.Release|x64.Build.0 = Release|Any CPU + {84F711C2-C210-28D2-F0D9-B13733FEE23D}.Release|x86.ActiveCfg = Release|Any CPU + {84F711C2-C210-28D2-F0D9-B13733FEE23D}.Release|x86.Build.0 = Release|Any CPU + {CBB14B90-27F9-8DD6-DFC4-3507DBD1FBC6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {CBB14B90-27F9-8DD6-DFC4-3507DBD1FBC6}.Debug|Any CPU.Build.0 = Debug|Any CPU + {CBB14B90-27F9-8DD6-DFC4-3507DBD1FBC6}.Debug|x64.ActiveCfg = Debug|Any CPU + {CBB14B90-27F9-8DD6-DFC4-3507DBD1FBC6}.Debug|x64.Build.0 = Debug|Any CPU + {CBB14B90-27F9-8DD6-DFC4-3507DBD1FBC6}.Debug|x86.ActiveCfg = Debug|Any CPU + {CBB14B90-27F9-8DD6-DFC4-3507DBD1FBC6}.Debug|x86.Build.0 = Debug|Any CPU + {CBB14B90-27F9-8DD6-DFC4-3507DBD1FBC6}.Release|Any CPU.ActiveCfg = Release|Any CPU + {CBB14B90-27F9-8DD6-DFC4-3507DBD1FBC6}.Release|Any CPU.Build.0 = Release|Any CPU + {CBB14B90-27F9-8DD6-DFC4-3507DBD1FBC6}.Release|x64.ActiveCfg = Release|Any CPU + {CBB14B90-27F9-8DD6-DFC4-3507DBD1FBC6}.Release|x64.Build.0 = Release|Any CPU + {CBB14B90-27F9-8DD6-DFC4-3507DBD1FBC6}.Release|x86.ActiveCfg = Release|Any CPU + {CBB14B90-27F9-8DD6-DFC4-3507DBD1FBC6}.Release|x86.Build.0 = Release|Any CPU + {A78EBC0F-C62C-8F56-95C0-330E376242A2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A78EBC0F-C62C-8F56-95C0-330E376242A2}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A78EBC0F-C62C-8F56-95C0-330E376242A2}.Debug|x64.ActiveCfg = Debug|Any CPU + {A78EBC0F-C62C-8F56-95C0-330E376242A2}.Debug|x64.Build.0 = Debug|Any CPU + {A78EBC0F-C62C-8F56-95C0-330E376242A2}.Debug|x86.ActiveCfg = Debug|Any CPU + {A78EBC0F-C62C-8F56-95C0-330E376242A2}.Debug|x86.Build.0 = Debug|Any CPU + {A78EBC0F-C62C-8F56-95C0-330E376242A2}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A78EBC0F-C62C-8F56-95C0-330E376242A2}.Release|Any CPU.Build.0 = Release|Any CPU + {A78EBC0F-C62C-8F56-95C0-330E376242A2}.Release|x64.ActiveCfg = Release|Any CPU + {A78EBC0F-C62C-8F56-95C0-330E376242A2}.Release|x64.Build.0 = Release|Any CPU + {A78EBC0F-C62C-8F56-95C0-330E376242A2}.Release|x86.ActiveCfg = Release|Any CPU + {A78EBC0F-C62C-8F56-95C0-330E376242A2}.Release|x86.Build.0 = Release|Any CPU + {6D26FB21-7E48-024B-E5D4-E3F0F31976BB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {6D26FB21-7E48-024B-E5D4-E3F0F31976BB}.Debug|Any CPU.Build.0 = Debug|Any CPU + {6D26FB21-7E48-024B-E5D4-E3F0F31976BB}.Debug|x64.ActiveCfg = Debug|Any CPU + {6D26FB21-7E48-024B-E5D4-E3F0F31976BB}.Debug|x64.Build.0 = Debug|Any CPU + {6D26FB21-7E48-024B-E5D4-E3F0F31976BB}.Debug|x86.ActiveCfg = Debug|Any CPU + {6D26FB21-7E48-024B-E5D4-E3F0F31976BB}.Debug|x86.Build.0 = Debug|Any CPU + {6D26FB21-7E48-024B-E5D4-E3F0F31976BB}.Release|Any CPU.ActiveCfg = Release|Any CPU + {6D26FB21-7E48-024B-E5D4-E3F0F31976BB}.Release|Any CPU.Build.0 = Release|Any CPU + {6D26FB21-7E48-024B-E5D4-E3F0F31976BB}.Release|x64.ActiveCfg = Release|Any CPU + {6D26FB21-7E48-024B-E5D4-E3F0F31976BB}.Release|x64.Build.0 = Release|Any CPU + {6D26FB21-7E48-024B-E5D4-E3F0F31976BB}.Release|x86.ActiveCfg = Release|Any CPU + {6D26FB21-7E48-024B-E5D4-E3F0F31976BB}.Release|x86.Build.0 = Release|Any CPU + {28D91816-206C-576E-1A83-FD98E08C2E3C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {28D91816-206C-576E-1A83-FD98E08C2E3C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {28D91816-206C-576E-1A83-FD98E08C2E3C}.Debug|x64.ActiveCfg = Debug|Any CPU + {28D91816-206C-576E-1A83-FD98E08C2E3C}.Debug|x64.Build.0 = Debug|Any CPU + {28D91816-206C-576E-1A83-FD98E08C2E3C}.Debug|x86.ActiveCfg = Debug|Any CPU + {28D91816-206C-576E-1A83-FD98E08C2E3C}.Debug|x86.Build.0 = Debug|Any CPU + {28D91816-206C-576E-1A83-FD98E08C2E3C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {28D91816-206C-576E-1A83-FD98E08C2E3C}.Release|Any CPU.Build.0 = Release|Any CPU + {28D91816-206C-576E-1A83-FD98E08C2E3C}.Release|x64.ActiveCfg = Release|Any CPU + {28D91816-206C-576E-1A83-FD98E08C2E3C}.Release|x64.Build.0 = Release|Any CPU + {28D91816-206C-576E-1A83-FD98E08C2E3C}.Release|x86.ActiveCfg = Release|Any CPU + {28D91816-206C-576E-1A83-FD98E08C2E3C}.Release|x86.Build.0 = Release|Any CPU + {58D8630F-C0F4-B772-8572-BCC98FF0F0D8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {58D8630F-C0F4-B772-8572-BCC98FF0F0D8}.Debug|Any CPU.Build.0 = Debug|Any CPU + {58D8630F-C0F4-B772-8572-BCC98FF0F0D8}.Debug|x64.ActiveCfg = Debug|Any CPU + {58D8630F-C0F4-B772-8572-BCC98FF0F0D8}.Debug|x64.Build.0 = Debug|Any CPU + {58D8630F-C0F4-B772-8572-BCC98FF0F0D8}.Debug|x86.ActiveCfg = Debug|Any CPU + {58D8630F-C0F4-B772-8572-BCC98FF0F0D8}.Debug|x86.Build.0 = Debug|Any CPU + {58D8630F-C0F4-B772-8572-BCC98FF0F0D8}.Release|Any CPU.ActiveCfg = Release|Any CPU + {58D8630F-C0F4-B772-8572-BCC98FF0F0D8}.Release|Any CPU.Build.0 = Release|Any CPU + {58D8630F-C0F4-B772-8572-BCC98FF0F0D8}.Release|x64.ActiveCfg = Release|Any CPU + {58D8630F-C0F4-B772-8572-BCC98FF0F0D8}.Release|x64.Build.0 = Release|Any CPU + {58D8630F-C0F4-B772-8572-BCC98FF0F0D8}.Release|x86.ActiveCfg = Release|Any CPU + {58D8630F-C0F4-B772-8572-BCC98FF0F0D8}.Release|x86.Build.0 = Release|Any CPU + {7CB7FEA8-8A12-A5D6-0057-AA65DB328617}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {7CB7FEA8-8A12-A5D6-0057-AA65DB328617}.Debug|Any CPU.Build.0 = Debug|Any CPU + {7CB7FEA8-8A12-A5D6-0057-AA65DB328617}.Debug|x64.ActiveCfg = Debug|Any CPU + {7CB7FEA8-8A12-A5D6-0057-AA65DB328617}.Debug|x64.Build.0 = Debug|Any CPU + {7CB7FEA8-8A12-A5D6-0057-AA65DB328617}.Debug|x86.ActiveCfg = Debug|Any CPU + {7CB7FEA8-8A12-A5D6-0057-AA65DB328617}.Debug|x86.Build.0 = Debug|Any CPU + {7CB7FEA8-8A12-A5D6-0057-AA65DB328617}.Release|Any CPU.ActiveCfg = Release|Any CPU + {7CB7FEA8-8A12-A5D6-0057-AA65DB328617}.Release|Any CPU.Build.0 = Release|Any CPU + {7CB7FEA8-8A12-A5D6-0057-AA65DB328617}.Release|x64.ActiveCfg = Release|Any CPU + {7CB7FEA8-8A12-A5D6-0057-AA65DB328617}.Release|x64.Build.0 = Release|Any CPU + {7CB7FEA8-8A12-A5D6-0057-AA65DB328617}.Release|x86.ActiveCfg = Release|Any CPU + {7CB7FEA8-8A12-A5D6-0057-AA65DB328617}.Release|x86.Build.0 = Release|Any CPU + {52698305-D6F8-C13C-0882-48FC37726404}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {52698305-D6F8-C13C-0882-48FC37726404}.Debug|Any CPU.Build.0 = Debug|Any CPU + {52698305-D6F8-C13C-0882-48FC37726404}.Debug|x64.ActiveCfg = Debug|Any CPU + {52698305-D6F8-C13C-0882-48FC37726404}.Debug|x64.Build.0 = Debug|Any CPU + {52698305-D6F8-C13C-0882-48FC37726404}.Debug|x86.ActiveCfg = Debug|Any CPU + {52698305-D6F8-C13C-0882-48FC37726404}.Debug|x86.Build.0 = Debug|Any CPU + {52698305-D6F8-C13C-0882-48FC37726404}.Release|Any CPU.ActiveCfg = Release|Any CPU + {52698305-D6F8-C13C-0882-48FC37726404}.Release|Any CPU.Build.0 = Release|Any CPU + {52698305-D6F8-C13C-0882-48FC37726404}.Release|x64.ActiveCfg = Release|Any CPU + {52698305-D6F8-C13C-0882-48FC37726404}.Release|x64.Build.0 = Release|Any CPU + {52698305-D6F8-C13C-0882-48FC37726404}.Release|x86.ActiveCfg = Release|Any CPU + {52698305-D6F8-C13C-0882-48FC37726404}.Release|x86.Build.0 = Release|Any CPU + {5567139C-0365-B6A0-5DD0-978A09B9F176}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {5567139C-0365-B6A0-5DD0-978A09B9F176}.Debug|Any CPU.Build.0 = Debug|Any CPU + {5567139C-0365-B6A0-5DD0-978A09B9F176}.Debug|x64.ActiveCfg = Debug|Any CPU + {5567139C-0365-B6A0-5DD0-978A09B9F176}.Debug|x64.Build.0 = Debug|Any CPU + {5567139C-0365-B6A0-5DD0-978A09B9F176}.Debug|x86.ActiveCfg = Debug|Any CPU + {5567139C-0365-B6A0-5DD0-978A09B9F176}.Debug|x86.Build.0 = Debug|Any CPU + {5567139C-0365-B6A0-5DD0-978A09B9F176}.Release|Any CPU.ActiveCfg = Release|Any CPU + {5567139C-0365-B6A0-5DD0-978A09B9F176}.Release|Any CPU.Build.0 = Release|Any CPU + {5567139C-0365-B6A0-5DD0-978A09B9F176}.Release|x64.ActiveCfg = Release|Any CPU + {5567139C-0365-B6A0-5DD0-978A09B9F176}.Release|x64.Build.0 = Release|Any CPU + {5567139C-0365-B6A0-5DD0-978A09B9F176}.Release|x86.ActiveCfg = Release|Any CPU + {5567139C-0365-B6A0-5DD0-978A09B9F176}.Release|x86.Build.0 = Release|Any CPU + {256D269B-35EA-F833-2F1D-8E0058908DEE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {256D269B-35EA-F833-2F1D-8E0058908DEE}.Debug|Any CPU.Build.0 = Debug|Any CPU + {256D269B-35EA-F833-2F1D-8E0058908DEE}.Debug|x64.ActiveCfg = Debug|Any CPU + {256D269B-35EA-F833-2F1D-8E0058908DEE}.Debug|x64.Build.0 = Debug|Any CPU + {256D269B-35EA-F833-2F1D-8E0058908DEE}.Debug|x86.ActiveCfg = Debug|Any CPU + {256D269B-35EA-F833-2F1D-8E0058908DEE}.Debug|x86.Build.0 = Debug|Any CPU + {256D269B-35EA-F833-2F1D-8E0058908DEE}.Release|Any CPU.ActiveCfg = Release|Any CPU + {256D269B-35EA-F833-2F1D-8E0058908DEE}.Release|Any CPU.Build.0 = Release|Any CPU + {256D269B-35EA-F833-2F1D-8E0058908DEE}.Release|x64.ActiveCfg = Release|Any CPU + {256D269B-35EA-F833-2F1D-8E0058908DEE}.Release|x64.Build.0 = Release|Any CPU + {256D269B-35EA-F833-2F1D-8E0058908DEE}.Release|x86.ActiveCfg = Release|Any CPU + {256D269B-35EA-F833-2F1D-8E0058908DEE}.Release|x86.Build.0 = Release|Any CPU + {1F372AB9-D8DD-D295-1D5E-CB5D454CBB24}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {1F372AB9-D8DD-D295-1D5E-CB5D454CBB24}.Debug|Any CPU.Build.0 = Debug|Any CPU + {1F372AB9-D8DD-D295-1D5E-CB5D454CBB24}.Debug|x64.ActiveCfg = Debug|Any CPU + {1F372AB9-D8DD-D295-1D5E-CB5D454CBB24}.Debug|x64.Build.0 = Debug|Any CPU + {1F372AB9-D8DD-D295-1D5E-CB5D454CBB24}.Debug|x86.ActiveCfg = Debug|Any CPU + {1F372AB9-D8DD-D295-1D5E-CB5D454CBB24}.Debug|x86.Build.0 = Debug|Any CPU + {1F372AB9-D8DD-D295-1D5E-CB5D454CBB24}.Release|Any CPU.ActiveCfg = Release|Any CPU + {1F372AB9-D8DD-D295-1D5E-CB5D454CBB24}.Release|Any CPU.Build.0 = Release|Any CPU + {1F372AB9-D8DD-D295-1D5E-CB5D454CBB24}.Release|x64.ActiveCfg = Release|Any CPU + {1F372AB9-D8DD-D295-1D5E-CB5D454CBB24}.Release|x64.Build.0 = Release|Any CPU + {1F372AB9-D8DD-D295-1D5E-CB5D454CBB24}.Release|x86.ActiveCfg = Release|Any CPU + {1F372AB9-D8DD-D295-1D5E-CB5D454CBB24}.Release|x86.Build.0 = Release|Any CPU + {0AF13355-173C-3128-5AFC-D32E540DA3EF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {0AF13355-173C-3128-5AFC-D32E540DA3EF}.Debug|Any CPU.Build.0 = Debug|Any CPU + {0AF13355-173C-3128-5AFC-D32E540DA3EF}.Debug|x64.ActiveCfg = Debug|Any CPU + {0AF13355-173C-3128-5AFC-D32E540DA3EF}.Debug|x64.Build.0 = Debug|Any CPU + {0AF13355-173C-3128-5AFC-D32E540DA3EF}.Debug|x86.ActiveCfg = Debug|Any CPU + {0AF13355-173C-3128-5AFC-D32E540DA3EF}.Debug|x86.Build.0 = Debug|Any CPU + {0AF13355-173C-3128-5AFC-D32E540DA3EF}.Release|Any CPU.ActiveCfg = Release|Any CPU + {0AF13355-173C-3128-5AFC-D32E540DA3EF}.Release|Any CPU.Build.0 = Release|Any CPU + {0AF13355-173C-3128-5AFC-D32E540DA3EF}.Release|x64.ActiveCfg = Release|Any CPU + {0AF13355-173C-3128-5AFC-D32E540DA3EF}.Release|x64.Build.0 = Release|Any CPU + {0AF13355-173C-3128-5AFC-D32E540DA3EF}.Release|x86.ActiveCfg = Release|Any CPU + {0AF13355-173C-3128-5AFC-D32E540DA3EF}.Release|x86.Build.0 = Release|Any CPU + {1D761F8B-921C-53BF-DCF5-5ABD329EEB0C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {1D761F8B-921C-53BF-DCF5-5ABD329EEB0C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {1D761F8B-921C-53BF-DCF5-5ABD329EEB0C}.Debug|x64.ActiveCfg = Debug|Any CPU + {1D761F8B-921C-53BF-DCF5-5ABD329EEB0C}.Debug|x64.Build.0 = Debug|Any CPU + {1D761F8B-921C-53BF-DCF5-5ABD329EEB0C}.Debug|x86.ActiveCfg = Debug|Any CPU + {1D761F8B-921C-53BF-DCF5-5ABD329EEB0C}.Debug|x86.Build.0 = Debug|Any CPU + {1D761F8B-921C-53BF-DCF5-5ABD329EEB0C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {1D761F8B-921C-53BF-DCF5-5ABD329EEB0C}.Release|Any CPU.Build.0 = Release|Any CPU + {1D761F8B-921C-53BF-DCF5-5ABD329EEB0C}.Release|x64.ActiveCfg = Release|Any CPU + {1D761F8B-921C-53BF-DCF5-5ABD329EEB0C}.Release|x64.Build.0 = Release|Any CPU + {1D761F8B-921C-53BF-DCF5-5ABD329EEB0C}.Release|x86.ActiveCfg = Release|Any CPU + {1D761F8B-921C-53BF-DCF5-5ABD329EEB0C}.Release|x86.Build.0 = Release|Any CPU + {50FA7781-4439-465A-8061-BEC5C3469814}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {50FA7781-4439-465A-8061-BEC5C3469814}.Debug|Any CPU.Build.0 = Debug|Any CPU + {50FA7781-4439-465A-8061-BEC5C3469814}.Debug|x64.ActiveCfg = Debug|Any CPU + {50FA7781-4439-465A-8061-BEC5C3469814}.Debug|x64.Build.0 = Debug|Any CPU + {50FA7781-4439-465A-8061-BEC5C3469814}.Debug|x86.ActiveCfg = Debug|Any CPU + {50FA7781-4439-465A-8061-BEC5C3469814}.Debug|x86.Build.0 = Debug|Any CPU + {50FA7781-4439-465A-8061-BEC5C3469814}.Release|Any CPU.ActiveCfg = Release|Any CPU + {50FA7781-4439-465A-8061-BEC5C3469814}.Release|Any CPU.Build.0 = Release|Any CPU + {50FA7781-4439-465A-8061-BEC5C3469814}.Release|x64.ActiveCfg = Release|Any CPU + {50FA7781-4439-465A-8061-BEC5C3469814}.Release|x64.Build.0 = Release|Any CPU + {50FA7781-4439-465A-8061-BEC5C3469814}.Release|x86.ActiveCfg = Release|Any CPU + {50FA7781-4439-465A-8061-BEC5C3469814}.Release|x86.Build.0 = Release|Any CPU + {32FE4D0A-D516-4DF2-80C0-E5211D95B0AD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {32FE4D0A-D516-4DF2-80C0-E5211D95B0AD}.Debug|Any CPU.Build.0 = Debug|Any CPU + {32FE4D0A-D516-4DF2-80C0-E5211D95B0AD}.Debug|x64.ActiveCfg = Debug|Any CPU + {32FE4D0A-D516-4DF2-80C0-E5211D95B0AD}.Debug|x64.Build.0 = Debug|Any CPU + {32FE4D0A-D516-4DF2-80C0-E5211D95B0AD}.Debug|x86.ActiveCfg = Debug|Any CPU + {32FE4D0A-D516-4DF2-80C0-E5211D95B0AD}.Debug|x86.Build.0 = Debug|Any CPU + {32FE4D0A-D516-4DF2-80C0-E5211D95B0AD}.Release|Any CPU.ActiveCfg = Release|Any CPU + {32FE4D0A-D516-4DF2-80C0-E5211D95B0AD}.Release|Any CPU.Build.0 = Release|Any CPU + {32FE4D0A-D516-4DF2-80C0-E5211D95B0AD}.Release|x64.ActiveCfg = Release|Any CPU + {32FE4D0A-D516-4DF2-80C0-E5211D95B0AD}.Release|x64.Build.0 = Release|Any CPU + {32FE4D0A-D516-4DF2-80C0-E5211D95B0AD}.Release|x86.ActiveCfg = Release|Any CPU + {32FE4D0A-D516-4DF2-80C0-E5211D95B0AD}.Release|x86.Build.0 = Release|Any CPU + {E15C7277-1131-4998-9D78-6156B53C2225}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E15C7277-1131-4998-9D78-6156B53C2225}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E15C7277-1131-4998-9D78-6156B53C2225}.Debug|x64.ActiveCfg = Debug|Any CPU + {E15C7277-1131-4998-9D78-6156B53C2225}.Debug|x64.Build.0 = Debug|Any CPU + {E15C7277-1131-4998-9D78-6156B53C2225}.Debug|x86.ActiveCfg = Debug|Any CPU + {E15C7277-1131-4998-9D78-6156B53C2225}.Debug|x86.Build.0 = Debug|Any CPU + {E15C7277-1131-4998-9D78-6156B53C2225}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E15C7277-1131-4998-9D78-6156B53C2225}.Release|Any CPU.Build.0 = Release|Any CPU + {E15C7277-1131-4998-9D78-6156B53C2225}.Release|x64.ActiveCfg = Release|Any CPU + {E15C7277-1131-4998-9D78-6156B53C2225}.Release|x64.Build.0 = Release|Any CPU + {E15C7277-1131-4998-9D78-6156B53C2225}.Release|x86.ActiveCfg = Release|Any CPU + {E15C7277-1131-4998-9D78-6156B53C2225}.Release|x86.Build.0 = Release|Any CPU + {9D9555C1-9A99-4F48-B0FB-1E24DFD53680}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {9D9555C1-9A99-4F48-B0FB-1E24DFD53680}.Debug|Any CPU.Build.0 = Debug|Any CPU + {9D9555C1-9A99-4F48-B0FB-1E24DFD53680}.Debug|x64.ActiveCfg = Debug|Any CPU + {9D9555C1-9A99-4F48-B0FB-1E24DFD53680}.Debug|x64.Build.0 = Debug|Any CPU + {9D9555C1-9A99-4F48-B0FB-1E24DFD53680}.Debug|x86.ActiveCfg = Debug|Any CPU + {9D9555C1-9A99-4F48-B0FB-1E24DFD53680}.Debug|x86.Build.0 = Debug|Any CPU + {9D9555C1-9A99-4F48-B0FB-1E24DFD53680}.Release|Any CPU.ActiveCfg = Release|Any CPU + {9D9555C1-9A99-4F48-B0FB-1E24DFD53680}.Release|Any CPU.Build.0 = Release|Any CPU + {9D9555C1-9A99-4F48-B0FB-1E24DFD53680}.Release|x64.ActiveCfg = Release|Any CPU + {9D9555C1-9A99-4F48-B0FB-1E24DFD53680}.Release|x64.Build.0 = Release|Any CPU + {9D9555C1-9A99-4F48-B0FB-1E24DFD53680}.Release|x86.ActiveCfg = Release|Any CPU + {9D9555C1-9A99-4F48-B0FB-1E24DFD53680}.Release|x86.Build.0 = Release|Any CPU + {8949E7C3-DC37-4317-9DE0-E7828DA27E14}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {8949E7C3-DC37-4317-9DE0-E7828DA27E14}.Debug|Any CPU.Build.0 = Debug|Any CPU + {8949E7C3-DC37-4317-9DE0-E7828DA27E14}.Debug|x64.ActiveCfg = Debug|Any CPU + {8949E7C3-DC37-4317-9DE0-E7828DA27E14}.Debug|x64.Build.0 = Debug|Any CPU + {8949E7C3-DC37-4317-9DE0-E7828DA27E14}.Debug|x86.ActiveCfg = Debug|Any CPU + {8949E7C3-DC37-4317-9DE0-E7828DA27E14}.Debug|x86.Build.0 = Debug|Any CPU + {8949E7C3-DC37-4317-9DE0-E7828DA27E14}.Release|Any CPU.ActiveCfg = Release|Any CPU + {8949E7C3-DC37-4317-9DE0-E7828DA27E14}.Release|Any CPU.Build.0 = Release|Any CPU + {8949E7C3-DC37-4317-9DE0-E7828DA27E14}.Release|x64.ActiveCfg = Release|Any CPU + {8949E7C3-DC37-4317-9DE0-E7828DA27E14}.Release|x64.Build.0 = Release|Any CPU + {8949E7C3-DC37-4317-9DE0-E7828DA27E14}.Release|x86.ActiveCfg = Release|Any CPU + {8949E7C3-DC37-4317-9DE0-E7828DA27E14}.Release|x86.Build.0 = Release|Any CPU + {9D5F9801-96AC-44D5-ABC2-13265AC3E9BD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {9D5F9801-96AC-44D5-ABC2-13265AC3E9BD}.Debug|Any CPU.Build.0 = Debug|Any CPU + {9D5F9801-96AC-44D5-ABC2-13265AC3E9BD}.Debug|x64.ActiveCfg = Debug|Any CPU + {9D5F9801-96AC-44D5-ABC2-13265AC3E9BD}.Debug|x64.Build.0 = Debug|Any CPU + {9D5F9801-96AC-44D5-ABC2-13265AC3E9BD}.Debug|x86.ActiveCfg = Debug|Any CPU + {9D5F9801-96AC-44D5-ABC2-13265AC3E9BD}.Debug|x86.Build.0 = Debug|Any CPU + {9D5F9801-96AC-44D5-ABC2-13265AC3E9BD}.Release|Any CPU.ActiveCfg = Release|Any CPU + {9D5F9801-96AC-44D5-ABC2-13265AC3E9BD}.Release|Any CPU.Build.0 = Release|Any CPU + {9D5F9801-96AC-44D5-ABC2-13265AC3E9BD}.Release|x64.ActiveCfg = Release|Any CPU + {9D5F9801-96AC-44D5-ABC2-13265AC3E9BD}.Release|x64.Build.0 = Release|Any CPU + {9D5F9801-96AC-44D5-ABC2-13265AC3E9BD}.Release|x86.ActiveCfg = Release|Any CPU + {9D5F9801-96AC-44D5-ABC2-13265AC3E9BD}.Release|x86.Build.0 = Release|Any CPU + {3A932381-572C-4DBD-8C4C-53AEA8673697}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {3A932381-572C-4DBD-8C4C-53AEA8673697}.Debug|Any CPU.Build.0 = Debug|Any CPU + {3A932381-572C-4DBD-8C4C-53AEA8673697}.Debug|x64.ActiveCfg = Debug|Any CPU + {3A932381-572C-4DBD-8C4C-53AEA8673697}.Debug|x64.Build.0 = Debug|Any CPU + {3A932381-572C-4DBD-8C4C-53AEA8673697}.Debug|x86.ActiveCfg = Debug|Any CPU + {3A932381-572C-4DBD-8C4C-53AEA8673697}.Debug|x86.Build.0 = Debug|Any CPU + {3A932381-572C-4DBD-8C4C-53AEA8673697}.Release|Any CPU.ActiveCfg = Release|Any CPU + {3A932381-572C-4DBD-8C4C-53AEA8673697}.Release|Any CPU.Build.0 = Release|Any CPU + {3A932381-572C-4DBD-8C4C-53AEA8673697}.Release|x64.ActiveCfg = Release|Any CPU + {3A932381-572C-4DBD-8C4C-53AEA8673697}.Release|x64.Build.0 = Release|Any CPU + {3A932381-572C-4DBD-8C4C-53AEA8673697}.Release|x86.ActiveCfg = Release|Any CPU + {3A932381-572C-4DBD-8C4C-53AEA8673697}.Release|x86.Build.0 = Release|Any CPU + {5DDFB053-7DA2-47AB-B4D3-7EBF0720E7BB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {5DDFB053-7DA2-47AB-B4D3-7EBF0720E7BB}.Debug|Any CPU.Build.0 = Debug|Any CPU + {5DDFB053-7DA2-47AB-B4D3-7EBF0720E7BB}.Debug|x64.ActiveCfg = Debug|Any CPU + {5DDFB053-7DA2-47AB-B4D3-7EBF0720E7BB}.Debug|x64.Build.0 = Debug|Any CPU + {5DDFB053-7DA2-47AB-B4D3-7EBF0720E7BB}.Debug|x86.ActiveCfg = Debug|Any CPU + {5DDFB053-7DA2-47AB-B4D3-7EBF0720E7BB}.Debug|x86.Build.0 = Debug|Any CPU + {5DDFB053-7DA2-47AB-B4D3-7EBF0720E7BB}.Release|Any CPU.ActiveCfg = Release|Any CPU + {5DDFB053-7DA2-47AB-B4D3-7EBF0720E7BB}.Release|Any CPU.Build.0 = Release|Any CPU + {5DDFB053-7DA2-47AB-B4D3-7EBF0720E7BB}.Release|x64.ActiveCfg = Release|Any CPU + {5DDFB053-7DA2-47AB-B4D3-7EBF0720E7BB}.Release|x64.Build.0 = Release|Any CPU + {5DDFB053-7DA2-47AB-B4D3-7EBF0720E7BB}.Release|x86.ActiveCfg = Release|Any CPU + {5DDFB053-7DA2-47AB-B4D3-7EBF0720E7BB}.Release|x86.Build.0 = Release|Any CPU + {847728D6-7CF8-40DC-899B-17BBA288A2AC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {847728D6-7CF8-40DC-899B-17BBA288A2AC}.Debug|Any CPU.Build.0 = Debug|Any CPU + {847728D6-7CF8-40DC-899B-17BBA288A2AC}.Debug|x64.ActiveCfg = Debug|Any CPU + {847728D6-7CF8-40DC-899B-17BBA288A2AC}.Debug|x64.Build.0 = Debug|Any CPU + {847728D6-7CF8-40DC-899B-17BBA288A2AC}.Debug|x86.ActiveCfg = Debug|Any CPU + {847728D6-7CF8-40DC-899B-17BBA288A2AC}.Debug|x86.Build.0 = Debug|Any CPU + {847728D6-7CF8-40DC-899B-17BBA288A2AC}.Release|Any CPU.ActiveCfg = Release|Any CPU + {847728D6-7CF8-40DC-899B-17BBA288A2AC}.Release|Any CPU.Build.0 = Release|Any CPU + {847728D6-7CF8-40DC-899B-17BBA288A2AC}.Release|x64.ActiveCfg = Release|Any CPU + {847728D6-7CF8-40DC-899B-17BBA288A2AC}.Release|x64.Build.0 = Release|Any CPU + {847728D6-7CF8-40DC-899B-17BBA288A2AC}.Release|x86.ActiveCfg = Release|Any CPU + {847728D6-7CF8-40DC-899B-17BBA288A2AC}.Release|x86.Build.0 = Release|Any CPU + {221D52DD-5DCB-4B44-AD14-ED5924155D1E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {221D52DD-5DCB-4B44-AD14-ED5924155D1E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {221D52DD-5DCB-4B44-AD14-ED5924155D1E}.Debug|x64.ActiveCfg = Debug|Any CPU + {221D52DD-5DCB-4B44-AD14-ED5924155D1E}.Debug|x64.Build.0 = Debug|Any CPU + {221D52DD-5DCB-4B44-AD14-ED5924155D1E}.Debug|x86.ActiveCfg = Debug|Any CPU + {221D52DD-5DCB-4B44-AD14-ED5924155D1E}.Debug|x86.Build.0 = Debug|Any CPU + {221D52DD-5DCB-4B44-AD14-ED5924155D1E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {221D52DD-5DCB-4B44-AD14-ED5924155D1E}.Release|Any CPU.Build.0 = Release|Any CPU + {221D52DD-5DCB-4B44-AD14-ED5924155D1E}.Release|x64.ActiveCfg = Release|Any CPU + {221D52DD-5DCB-4B44-AD14-ED5924155D1E}.Release|x64.Build.0 = Release|Any CPU + {221D52DD-5DCB-4B44-AD14-ED5924155D1E}.Release|x86.ActiveCfg = Release|Any CPU + {221D52DD-5DCB-4B44-AD14-ED5924155D1E}.Release|x86.Build.0 = Release|Any CPU + {12D822DC-8CA8-46A4-89FD-1491A4649B39}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {12D822DC-8CA8-46A4-89FD-1491A4649B39}.Debug|Any CPU.Build.0 = Debug|Any CPU + {12D822DC-8CA8-46A4-89FD-1491A4649B39}.Debug|x64.ActiveCfg = Debug|Any CPU + {12D822DC-8CA8-46A4-89FD-1491A4649B39}.Debug|x64.Build.0 = Debug|Any CPU + {12D822DC-8CA8-46A4-89FD-1491A4649B39}.Debug|x86.ActiveCfg = Debug|Any CPU + {12D822DC-8CA8-46A4-89FD-1491A4649B39}.Debug|x86.Build.0 = Debug|Any CPU + {12D822DC-8CA8-46A4-89FD-1491A4649B39}.Release|Any CPU.ActiveCfg = Release|Any CPU + {12D822DC-8CA8-46A4-89FD-1491A4649B39}.Release|Any CPU.Build.0 = Release|Any CPU + {12D822DC-8CA8-46A4-89FD-1491A4649B39}.Release|x64.ActiveCfg = Release|Any CPU + {12D822DC-8CA8-46A4-89FD-1491A4649B39}.Release|x64.Build.0 = Release|Any CPU + {12D822DC-8CA8-46A4-89FD-1491A4649B39}.Release|x86.ActiveCfg = Release|Any CPU + {12D822DC-8CA8-46A4-89FD-1491A4649B39}.Release|x86.Build.0 = Release|Any CPU + {C8753162-F434-4C46-91AE-C4CC05AAEAD4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C8753162-F434-4C46-91AE-C4CC05AAEAD4}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C8753162-F434-4C46-91AE-C4CC05AAEAD4}.Debug|x64.ActiveCfg = Debug|Any CPU + {C8753162-F434-4C46-91AE-C4CC05AAEAD4}.Debug|x64.Build.0 = Debug|Any CPU + {C8753162-F434-4C46-91AE-C4CC05AAEAD4}.Debug|x86.ActiveCfg = Debug|Any CPU + {C8753162-F434-4C46-91AE-C4CC05AAEAD4}.Debug|x86.Build.0 = Debug|Any CPU + {C8753162-F434-4C46-91AE-C4CC05AAEAD4}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C8753162-F434-4C46-91AE-C4CC05AAEAD4}.Release|Any CPU.Build.0 = Release|Any CPU + {C8753162-F434-4C46-91AE-C4CC05AAEAD4}.Release|x64.ActiveCfg = Release|Any CPU + {C8753162-F434-4C46-91AE-C4CC05AAEAD4}.Release|x64.Build.0 = Release|Any CPU + {C8753162-F434-4C46-91AE-C4CC05AAEAD4}.Release|x86.ActiveCfg = Release|Any CPU + {C8753162-F434-4C46-91AE-C4CC05AAEAD4}.Release|x86.Build.0 = Release|Any CPU + {85117726-9F80-43F5-806A-38D41653E963}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {85117726-9F80-43F5-806A-38D41653E963}.Debug|Any CPU.Build.0 = Debug|Any CPU + {85117726-9F80-43F5-806A-38D41653E963}.Debug|x64.ActiveCfg = Debug|Any CPU + {85117726-9F80-43F5-806A-38D41653E963}.Debug|x64.Build.0 = Debug|Any CPU + {85117726-9F80-43F5-806A-38D41653E963}.Debug|x86.ActiveCfg = Debug|Any CPU + {85117726-9F80-43F5-806A-38D41653E963}.Debug|x86.Build.0 = Debug|Any CPU + {85117726-9F80-43F5-806A-38D41653E963}.Release|Any CPU.ActiveCfg = Release|Any CPU + {85117726-9F80-43F5-806A-38D41653E963}.Release|Any CPU.Build.0 = Release|Any CPU + {85117726-9F80-43F5-806A-38D41653E963}.Release|x64.ActiveCfg = Release|Any CPU + {85117726-9F80-43F5-806A-38D41653E963}.Release|x64.Build.0 = Release|Any CPU + {85117726-9F80-43F5-806A-38D41653E963}.Release|x86.ActiveCfg = Release|Any CPU + {85117726-9F80-43F5-806A-38D41653E963}.Release|x86.Build.0 = Release|Any CPU + {67BB82D9-06BE-450D-B956-6350C5EDBFBB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {67BB82D9-06BE-450D-B956-6350C5EDBFBB}.Debug|Any CPU.Build.0 = Debug|Any CPU + {67BB82D9-06BE-450D-B956-6350C5EDBFBB}.Debug|x64.ActiveCfg = Debug|Any CPU + {67BB82D9-06BE-450D-B956-6350C5EDBFBB}.Debug|x64.Build.0 = Debug|Any CPU + {67BB82D9-06BE-450D-B956-6350C5EDBFBB}.Debug|x86.ActiveCfg = Debug|Any CPU + {67BB82D9-06BE-450D-B956-6350C5EDBFBB}.Debug|x86.Build.0 = Debug|Any CPU + {67BB82D9-06BE-450D-B956-6350C5EDBFBB}.Release|Any CPU.ActiveCfg = Release|Any CPU + {67BB82D9-06BE-450D-B956-6350C5EDBFBB}.Release|Any CPU.Build.0 = Release|Any CPU + {67BB82D9-06BE-450D-B956-6350C5EDBFBB}.Release|x64.ActiveCfg = Release|Any CPU + {67BB82D9-06BE-450D-B956-6350C5EDBFBB}.Release|x64.Build.0 = Release|Any CPU + {67BB82D9-06BE-450D-B956-6350C5EDBFBB}.Release|x86.ActiveCfg = Release|Any CPU + {67BB82D9-06BE-450D-B956-6350C5EDBFBB}.Release|x86.Build.0 = Release|Any CPU + {8F7C01D1-2573-4FC0-8390-516A4F8310DA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {8F7C01D1-2573-4FC0-8390-516A4F8310DA}.Debug|Any CPU.Build.0 = Debug|Any CPU + {8F7C01D1-2573-4FC0-8390-516A4F8310DA}.Debug|x64.ActiveCfg = Debug|Any CPU + {8F7C01D1-2573-4FC0-8390-516A4F8310DA}.Debug|x64.Build.0 = Debug|Any CPU + {8F7C01D1-2573-4FC0-8390-516A4F8310DA}.Debug|x86.ActiveCfg = Debug|Any CPU + {8F7C01D1-2573-4FC0-8390-516A4F8310DA}.Debug|x86.Build.0 = Debug|Any CPU + {8F7C01D1-2573-4FC0-8390-516A4F8310DA}.Release|Any CPU.ActiveCfg = Release|Any CPU + {8F7C01D1-2573-4FC0-8390-516A4F8310DA}.Release|Any CPU.Build.0 = Release|Any CPU + {8F7C01D1-2573-4FC0-8390-516A4F8310DA}.Release|x64.ActiveCfg = Release|Any CPU + {8F7C01D1-2573-4FC0-8390-516A4F8310DA}.Release|x64.Build.0 = Release|Any CPU + {8F7C01D1-2573-4FC0-8390-516A4F8310DA}.Release|x86.ActiveCfg = Release|Any CPU + {8F7C01D1-2573-4FC0-8390-516A4F8310DA}.Release|x86.Build.0 = Release|Any CPU + {B8FB2391-7A43-451A-90EF-340E157F1C69}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B8FB2391-7A43-451A-90EF-340E157F1C69}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B8FB2391-7A43-451A-90EF-340E157F1C69}.Debug|x64.ActiveCfg = Debug|Any CPU + {B8FB2391-7A43-451A-90EF-340E157F1C69}.Debug|x64.Build.0 = Debug|Any CPU + {B8FB2391-7A43-451A-90EF-340E157F1C69}.Debug|x86.ActiveCfg = Debug|Any CPU + {B8FB2391-7A43-451A-90EF-340E157F1C69}.Debug|x86.Build.0 = Debug|Any CPU + {B8FB2391-7A43-451A-90EF-340E157F1C69}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B8FB2391-7A43-451A-90EF-340E157F1C69}.Release|Any CPU.Build.0 = Release|Any CPU + {B8FB2391-7A43-451A-90EF-340E157F1C69}.Release|x64.ActiveCfg = Release|Any CPU + {B8FB2391-7A43-451A-90EF-340E157F1C69}.Release|x64.Build.0 = Release|Any CPU + {B8FB2391-7A43-451A-90EF-340E157F1C69}.Release|x86.ActiveCfg = Release|Any CPU + {B8FB2391-7A43-451A-90EF-340E157F1C69}.Release|x86.Build.0 = Release|Any CPU + {C374DB33-2508-4F49-9216-35EF02F78128}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C374DB33-2508-4F49-9216-35EF02F78128}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C374DB33-2508-4F49-9216-35EF02F78128}.Debug|x64.ActiveCfg = Debug|Any CPU + {C374DB33-2508-4F49-9216-35EF02F78128}.Debug|x64.Build.0 = Debug|Any CPU + {C374DB33-2508-4F49-9216-35EF02F78128}.Debug|x86.ActiveCfg = Debug|Any CPU + {C374DB33-2508-4F49-9216-35EF02F78128}.Debug|x86.Build.0 = Debug|Any CPU + {C374DB33-2508-4F49-9216-35EF02F78128}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C374DB33-2508-4F49-9216-35EF02F78128}.Release|Any CPU.Build.0 = Release|Any CPU + {C374DB33-2508-4F49-9216-35EF02F78128}.Release|x64.ActiveCfg = Release|Any CPU + {C374DB33-2508-4F49-9216-35EF02F78128}.Release|x64.Build.0 = Release|Any CPU + {C374DB33-2508-4F49-9216-35EF02F78128}.Release|x86.ActiveCfg = Release|Any CPU + {C374DB33-2508-4F49-9216-35EF02F78128}.Release|x86.Build.0 = Release|Any CPU + {40D2202C-F62E-42F4-8C96-36C0990E3316}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {40D2202C-F62E-42F4-8C96-36C0990E3316}.Debug|Any CPU.Build.0 = Debug|Any CPU + {40D2202C-F62E-42F4-8C96-36C0990E3316}.Debug|x64.ActiveCfg = Debug|Any CPU + {40D2202C-F62E-42F4-8C96-36C0990E3316}.Debug|x64.Build.0 = Debug|Any CPU + {40D2202C-F62E-42F4-8C96-36C0990E3316}.Debug|x86.ActiveCfg = Debug|Any CPU + {40D2202C-F62E-42F4-8C96-36C0990E3316}.Debug|x86.Build.0 = Debug|Any CPU + {40D2202C-F62E-42F4-8C96-36C0990E3316}.Release|Any CPU.ActiveCfg = Release|Any CPU + {40D2202C-F62E-42F4-8C96-36C0990E3316}.Release|Any CPU.Build.0 = Release|Any CPU + {40D2202C-F62E-42F4-8C96-36C0990E3316}.Release|x64.ActiveCfg = Release|Any CPU + {40D2202C-F62E-42F4-8C96-36C0990E3316}.Release|x64.Build.0 = Release|Any CPU + {40D2202C-F62E-42F4-8C96-36C0990E3316}.Release|x86.ActiveCfg = Release|Any CPU + {40D2202C-F62E-42F4-8C96-36C0990E3316}.Release|x86.Build.0 = Release|Any CPU + {03143416-8B17-445B-B9FB-8753B9997D39}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {03143416-8B17-445B-B9FB-8753B9997D39}.Debug|Any CPU.Build.0 = Debug|Any CPU + {03143416-8B17-445B-B9FB-8753B9997D39}.Debug|x64.ActiveCfg = Debug|Any CPU + {03143416-8B17-445B-B9FB-8753B9997D39}.Debug|x64.Build.0 = Debug|Any CPU + {03143416-8B17-445B-B9FB-8753B9997D39}.Debug|x86.ActiveCfg = Debug|Any CPU + {03143416-8B17-445B-B9FB-8753B9997D39}.Debug|x86.Build.0 = Debug|Any CPU + {03143416-8B17-445B-B9FB-8753B9997D39}.Release|Any CPU.ActiveCfg = Release|Any CPU + {03143416-8B17-445B-B9FB-8753B9997D39}.Release|Any CPU.Build.0 = Release|Any CPU + {03143416-8B17-445B-B9FB-8753B9997D39}.Release|x64.ActiveCfg = Release|Any CPU + {03143416-8B17-445B-B9FB-8753B9997D39}.Release|x64.Build.0 = Release|Any CPU + {03143416-8B17-445B-B9FB-8753B9997D39}.Release|x86.ActiveCfg = Release|Any CPU + {03143416-8B17-445B-B9FB-8753B9997D39}.Release|x86.Build.0 = Release|Any CPU + {61769CBA-A534-449C-8E65-8FF763F82851}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {61769CBA-A534-449C-8E65-8FF763F82851}.Debug|Any CPU.Build.0 = Debug|Any CPU + {61769CBA-A534-449C-8E65-8FF763F82851}.Debug|x64.ActiveCfg = Debug|Any CPU + {61769CBA-A534-449C-8E65-8FF763F82851}.Debug|x64.Build.0 = Debug|Any CPU + {61769CBA-A534-449C-8E65-8FF763F82851}.Debug|x86.ActiveCfg = Debug|Any CPU + {61769CBA-A534-449C-8E65-8FF763F82851}.Debug|x86.Build.0 = Debug|Any CPU + {61769CBA-A534-449C-8E65-8FF763F82851}.Release|Any CPU.ActiveCfg = Release|Any CPU + {61769CBA-A534-449C-8E65-8FF763F82851}.Release|Any CPU.Build.0 = Release|Any CPU + {61769CBA-A534-449C-8E65-8FF763F82851}.Release|x64.ActiveCfg = Release|Any CPU + {61769CBA-A534-449C-8E65-8FF763F82851}.Release|x64.Build.0 = Release|Any CPU + {61769CBA-A534-449C-8E65-8FF763F82851}.Release|x86.ActiveCfg = Release|Any CPU + {61769CBA-A534-449C-8E65-8FF763F82851}.Release|x86.Build.0 = Release|Any CPU + {B2B8D3BF-A764-42F7-BFBE-8F266D457B49}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B2B8D3BF-A764-42F7-BFBE-8F266D457B49}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B2B8D3BF-A764-42F7-BFBE-8F266D457B49}.Debug|x64.ActiveCfg = Debug|Any CPU + {B2B8D3BF-A764-42F7-BFBE-8F266D457B49}.Debug|x64.Build.0 = Debug|Any CPU + {B2B8D3BF-A764-42F7-BFBE-8F266D457B49}.Debug|x86.ActiveCfg = Debug|Any CPU + {B2B8D3BF-A764-42F7-BFBE-8F266D457B49}.Debug|x86.Build.0 = Debug|Any CPU + {B2B8D3BF-A764-42F7-BFBE-8F266D457B49}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B2B8D3BF-A764-42F7-BFBE-8F266D457B49}.Release|Any CPU.Build.0 = Release|Any CPU + {B2B8D3BF-A764-42F7-BFBE-8F266D457B49}.Release|x64.ActiveCfg = Release|Any CPU + {B2B8D3BF-A764-42F7-BFBE-8F266D457B49}.Release|x64.Build.0 = Release|Any CPU + {B2B8D3BF-A764-42F7-BFBE-8F266D457B49}.Release|x86.ActiveCfg = Release|Any CPU + {B2B8D3BF-A764-42F7-BFBE-8F266D457B49}.Release|x86.Build.0 = Release|Any CPU + {DF2F93A8-0514-42DE-9C19-0C564036BF13}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {DF2F93A8-0514-42DE-9C19-0C564036BF13}.Debug|Any CPU.Build.0 = Debug|Any CPU + {DF2F93A8-0514-42DE-9C19-0C564036BF13}.Debug|x64.ActiveCfg = Debug|Any CPU + {DF2F93A8-0514-42DE-9C19-0C564036BF13}.Debug|x64.Build.0 = Debug|Any CPU + {DF2F93A8-0514-42DE-9C19-0C564036BF13}.Debug|x86.ActiveCfg = Debug|Any CPU + {DF2F93A8-0514-42DE-9C19-0C564036BF13}.Debug|x86.Build.0 = Debug|Any CPU + {DF2F93A8-0514-42DE-9C19-0C564036BF13}.Release|Any CPU.ActiveCfg = Release|Any CPU + {DF2F93A8-0514-42DE-9C19-0C564036BF13}.Release|Any CPU.Build.0 = Release|Any CPU + {DF2F93A8-0514-42DE-9C19-0C564036BF13}.Release|x64.ActiveCfg = Release|Any CPU + {DF2F93A8-0514-42DE-9C19-0C564036BF13}.Release|x64.Build.0 = Release|Any CPU + {DF2F93A8-0514-42DE-9C19-0C564036BF13}.Release|x86.ActiveCfg = Release|Any CPU + {DF2F93A8-0514-42DE-9C19-0C564036BF13}.Release|x86.Build.0 = Release|Any CPU + {B910025A-7D54-480E-A036-4B85582F458C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B910025A-7D54-480E-A036-4B85582F458C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B910025A-7D54-480E-A036-4B85582F458C}.Debug|x64.ActiveCfg = Debug|Any CPU + {B910025A-7D54-480E-A036-4B85582F458C}.Debug|x64.Build.0 = Debug|Any CPU + {B910025A-7D54-480E-A036-4B85582F458C}.Debug|x86.ActiveCfg = Debug|Any CPU + {B910025A-7D54-480E-A036-4B85582F458C}.Debug|x86.Build.0 = Debug|Any CPU + {B910025A-7D54-480E-A036-4B85582F458C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B910025A-7D54-480E-A036-4B85582F458C}.Release|Any CPU.Build.0 = Release|Any CPU + {B910025A-7D54-480E-A036-4B85582F458C}.Release|x64.ActiveCfg = Release|Any CPU + {B910025A-7D54-480E-A036-4B85582F458C}.Release|x64.Build.0 = Release|Any CPU + {B910025A-7D54-480E-A036-4B85582F458C}.Release|x86.ActiveCfg = Release|Any CPU + {B910025A-7D54-480E-A036-4B85582F458C}.Release|x86.Build.0 = Release|Any CPU + {00D7AFF4-5400-441D-BA15-CDB52A0C0654}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {00D7AFF4-5400-441D-BA15-CDB52A0C0654}.Debug|Any CPU.Build.0 = Debug|Any CPU + {00D7AFF4-5400-441D-BA15-CDB52A0C0654}.Debug|x64.ActiveCfg = Debug|Any CPU + {00D7AFF4-5400-441D-BA15-CDB52A0C0654}.Debug|x64.Build.0 = Debug|Any CPU + {00D7AFF4-5400-441D-BA15-CDB52A0C0654}.Debug|x86.ActiveCfg = Debug|Any CPU + {00D7AFF4-5400-441D-BA15-CDB52A0C0654}.Debug|x86.Build.0 = Debug|Any CPU + {00D7AFF4-5400-441D-BA15-CDB52A0C0654}.Release|Any CPU.ActiveCfg = Release|Any CPU + {00D7AFF4-5400-441D-BA15-CDB52A0C0654}.Release|Any CPU.Build.0 = Release|Any CPU + {00D7AFF4-5400-441D-BA15-CDB52A0C0654}.Release|x64.ActiveCfg = Release|Any CPU + {00D7AFF4-5400-441D-BA15-CDB52A0C0654}.Release|x64.Build.0 = Release|Any CPU + {00D7AFF4-5400-441D-BA15-CDB52A0C0654}.Release|x86.ActiveCfg = Release|Any CPU + {00D7AFF4-5400-441D-BA15-CDB52A0C0654}.Release|x86.Build.0 = Release|Any CPU + {756624C1-CEDE-4CF2-B5D4-5B22C0C9F131}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {756624C1-CEDE-4CF2-B5D4-5B22C0C9F131}.Debug|Any CPU.Build.0 = Debug|Any CPU + {756624C1-CEDE-4CF2-B5D4-5B22C0C9F131}.Debug|x64.ActiveCfg = Debug|Any CPU + {756624C1-CEDE-4CF2-B5D4-5B22C0C9F131}.Debug|x64.Build.0 = Debug|Any CPU + {756624C1-CEDE-4CF2-B5D4-5B22C0C9F131}.Debug|x86.ActiveCfg = Debug|Any CPU + {756624C1-CEDE-4CF2-B5D4-5B22C0C9F131}.Debug|x86.Build.0 = Debug|Any CPU + {756624C1-CEDE-4CF2-B5D4-5B22C0C9F131}.Release|Any CPU.ActiveCfg = Release|Any CPU + {756624C1-CEDE-4CF2-B5D4-5B22C0C9F131}.Release|Any CPU.Build.0 = Release|Any CPU + {756624C1-CEDE-4CF2-B5D4-5B22C0C9F131}.Release|x64.ActiveCfg = Release|Any CPU + {756624C1-CEDE-4CF2-B5D4-5B22C0C9F131}.Release|x64.Build.0 = Release|Any CPU + {756624C1-CEDE-4CF2-B5D4-5B22C0C9F131}.Release|x86.ActiveCfg = Release|Any CPU + {756624C1-CEDE-4CF2-B5D4-5B22C0C9F131}.Release|x86.Build.0 = Release|Any CPU + {F5DECABB-33AB-409B-B330-AE8F4C1AEA43}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F5DECABB-33AB-409B-B330-AE8F4C1AEA43}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F5DECABB-33AB-409B-B330-AE8F4C1AEA43}.Debug|x64.ActiveCfg = Debug|Any CPU + {F5DECABB-33AB-409B-B330-AE8F4C1AEA43}.Debug|x64.Build.0 = Debug|Any CPU + {F5DECABB-33AB-409B-B330-AE8F4C1AEA43}.Debug|x86.ActiveCfg = Debug|Any CPU + {F5DECABB-33AB-409B-B330-AE8F4C1AEA43}.Debug|x86.Build.0 = Debug|Any CPU + {F5DECABB-33AB-409B-B330-AE8F4C1AEA43}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F5DECABB-33AB-409B-B330-AE8F4C1AEA43}.Release|Any CPU.Build.0 = Release|Any CPU + {F5DECABB-33AB-409B-B330-AE8F4C1AEA43}.Release|x64.ActiveCfg = Release|Any CPU + {F5DECABB-33AB-409B-B330-AE8F4C1AEA43}.Release|x64.Build.0 = Release|Any CPU + {F5DECABB-33AB-409B-B330-AE8F4C1AEA43}.Release|x86.ActiveCfg = Release|Any CPU + {F5DECABB-33AB-409B-B330-AE8F4C1AEA43}.Release|x86.Build.0 = Release|Any CPU + {A57E60A4-3EF4-4A44-A5AE-8BCCED3BCEA5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A57E60A4-3EF4-4A44-A5AE-8BCCED3BCEA5}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A57E60A4-3EF4-4A44-A5AE-8BCCED3BCEA5}.Debug|x64.ActiveCfg = Debug|Any CPU + {A57E60A4-3EF4-4A44-A5AE-8BCCED3BCEA5}.Debug|x64.Build.0 = Debug|Any CPU + {A57E60A4-3EF4-4A44-A5AE-8BCCED3BCEA5}.Debug|x86.ActiveCfg = Debug|Any CPU + {A57E60A4-3EF4-4A44-A5AE-8BCCED3BCEA5}.Debug|x86.Build.0 = Debug|Any CPU + {A57E60A4-3EF4-4A44-A5AE-8BCCED3BCEA5}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A57E60A4-3EF4-4A44-A5AE-8BCCED3BCEA5}.Release|Any CPU.Build.0 = Release|Any CPU + {A57E60A4-3EF4-4A44-A5AE-8BCCED3BCEA5}.Release|x64.ActiveCfg = Release|Any CPU + {A57E60A4-3EF4-4A44-A5AE-8BCCED3BCEA5}.Release|x64.Build.0 = Release|Any CPU + {A57E60A4-3EF4-4A44-A5AE-8BCCED3BCEA5}.Release|x86.ActiveCfg = Release|Any CPU + {A57E60A4-3EF4-4A44-A5AE-8BCCED3BCEA5}.Release|x86.Build.0 = Release|Any CPU + {A8D09907-03D7-41DE-B225-3D52AFC1B29A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A8D09907-03D7-41DE-B225-3D52AFC1B29A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A8D09907-03D7-41DE-B225-3D52AFC1B29A}.Debug|x64.ActiveCfg = Debug|Any CPU + {A8D09907-03D7-41DE-B225-3D52AFC1B29A}.Debug|x64.Build.0 = Debug|Any CPU + {A8D09907-03D7-41DE-B225-3D52AFC1B29A}.Debug|x86.ActiveCfg = Debug|Any CPU + {A8D09907-03D7-41DE-B225-3D52AFC1B29A}.Debug|x86.Build.0 = Debug|Any CPU + {A8D09907-03D7-41DE-B225-3D52AFC1B29A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A8D09907-03D7-41DE-B225-3D52AFC1B29A}.Release|Any CPU.Build.0 = Release|Any CPU + {A8D09907-03D7-41DE-B225-3D52AFC1B29A}.Release|x64.ActiveCfg = Release|Any CPU + {A8D09907-03D7-41DE-B225-3D52AFC1B29A}.Release|x64.Build.0 = Release|Any CPU + {A8D09907-03D7-41DE-B225-3D52AFC1B29A}.Release|x86.ActiveCfg = Release|Any CPU + {A8D09907-03D7-41DE-B225-3D52AFC1B29A}.Release|x86.Build.0 = Release|Any CPU + {9E59CBEF-FAC9-4060-96E2-D7C5AB73722D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {9E59CBEF-FAC9-4060-96E2-D7C5AB73722D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {9E59CBEF-FAC9-4060-96E2-D7C5AB73722D}.Debug|x64.ActiveCfg = Debug|Any CPU + {9E59CBEF-FAC9-4060-96E2-D7C5AB73722D}.Debug|x64.Build.0 = Debug|Any CPU + {9E59CBEF-FAC9-4060-96E2-D7C5AB73722D}.Debug|x86.ActiveCfg = Debug|Any CPU + {9E59CBEF-FAC9-4060-96E2-D7C5AB73722D}.Debug|x86.Build.0 = Debug|Any CPU + {9E59CBEF-FAC9-4060-96E2-D7C5AB73722D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {9E59CBEF-FAC9-4060-96E2-D7C5AB73722D}.Release|Any CPU.Build.0 = Release|Any CPU + {9E59CBEF-FAC9-4060-96E2-D7C5AB73722D}.Release|x64.ActiveCfg = Release|Any CPU + {9E59CBEF-FAC9-4060-96E2-D7C5AB73722D}.Release|x64.Build.0 = Release|Any CPU + {9E59CBEF-FAC9-4060-96E2-D7C5AB73722D}.Release|x86.ActiveCfg = Release|Any CPU + {9E59CBEF-FAC9-4060-96E2-D7C5AB73722D}.Release|x86.Build.0 = Release|Any CPU + {2F60D283-D878-454D-8A2B-7E79A2D94916}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {2F60D283-D878-454D-8A2B-7E79A2D94916}.Debug|Any CPU.Build.0 = Debug|Any CPU + {2F60D283-D878-454D-8A2B-7E79A2D94916}.Debug|x64.ActiveCfg = Debug|Any CPU + {2F60D283-D878-454D-8A2B-7E79A2D94916}.Debug|x64.Build.0 = Debug|Any CPU + {2F60D283-D878-454D-8A2B-7E79A2D94916}.Debug|x86.ActiveCfg = Debug|Any CPU + {2F60D283-D878-454D-8A2B-7E79A2D94916}.Debug|x86.Build.0 = Debug|Any CPU + {2F60D283-D878-454D-8A2B-7E79A2D94916}.Release|Any CPU.ActiveCfg = Release|Any CPU + {2F60D283-D878-454D-8A2B-7E79A2D94916}.Release|Any CPU.Build.0 = Release|Any CPU + {2F60D283-D878-454D-8A2B-7E79A2D94916}.Release|x64.ActiveCfg = Release|Any CPU + {2F60D283-D878-454D-8A2B-7E79A2D94916}.Release|x64.Build.0 = Release|Any CPU + {2F60D283-D878-454D-8A2B-7E79A2D94916}.Release|x86.ActiveCfg = Release|Any CPU + {2F60D283-D878-454D-8A2B-7E79A2D94916}.Release|x86.Build.0 = Release|Any CPU + {F557A6F0-03F6-4687-9FDA-7BEBC8969391}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F557A6F0-03F6-4687-9FDA-7BEBC8969391}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F557A6F0-03F6-4687-9FDA-7BEBC8969391}.Debug|x64.ActiveCfg = Debug|Any CPU + {F557A6F0-03F6-4687-9FDA-7BEBC8969391}.Debug|x64.Build.0 = Debug|Any CPU + {F557A6F0-03F6-4687-9FDA-7BEBC8969391}.Debug|x86.ActiveCfg = Debug|Any CPU + {F557A6F0-03F6-4687-9FDA-7BEBC8969391}.Debug|x86.Build.0 = Debug|Any CPU + {F557A6F0-03F6-4687-9FDA-7BEBC8969391}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F557A6F0-03F6-4687-9FDA-7BEBC8969391}.Release|Any CPU.Build.0 = Release|Any CPU + {F557A6F0-03F6-4687-9FDA-7BEBC8969391}.Release|x64.ActiveCfg = Release|Any CPU + {F557A6F0-03F6-4687-9FDA-7BEBC8969391}.Release|x64.Build.0 = Release|Any CPU + {F557A6F0-03F6-4687-9FDA-7BEBC8969391}.Release|x86.ActiveCfg = Release|Any CPU + {F557A6F0-03F6-4687-9FDA-7BEBC8969391}.Release|x86.Build.0 = Release|Any CPU + {0B67426D-5E0E-40A2-B3B1-9C3466795149}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {0B67426D-5E0E-40A2-B3B1-9C3466795149}.Debug|Any CPU.Build.0 = Debug|Any CPU + {0B67426D-5E0E-40A2-B3B1-9C3466795149}.Debug|x64.ActiveCfg = Debug|Any CPU + {0B67426D-5E0E-40A2-B3B1-9C3466795149}.Debug|x64.Build.0 = Debug|Any CPU + {0B67426D-5E0E-40A2-B3B1-9C3466795149}.Debug|x86.ActiveCfg = Debug|Any CPU + {0B67426D-5E0E-40A2-B3B1-9C3466795149}.Debug|x86.Build.0 = Debug|Any CPU + {0B67426D-5E0E-40A2-B3B1-9C3466795149}.Release|Any CPU.ActiveCfg = Release|Any CPU + {0B67426D-5E0E-40A2-B3B1-9C3466795149}.Release|Any CPU.Build.0 = Release|Any CPU + {0B67426D-5E0E-40A2-B3B1-9C3466795149}.Release|x64.ActiveCfg = Release|Any CPU + {0B67426D-5E0E-40A2-B3B1-9C3466795149}.Release|x64.Build.0 = Release|Any CPU + {0B67426D-5E0E-40A2-B3B1-9C3466795149}.Release|x86.ActiveCfg = Release|Any CPU + {0B67426D-5E0E-40A2-B3B1-9C3466795149}.Release|x86.Build.0 = Release|Any CPU + {F2181DC4-43EB-4F3A-BD3E-03AD1F9CE3C5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F2181DC4-43EB-4F3A-BD3E-03AD1F9CE3C5}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F2181DC4-43EB-4F3A-BD3E-03AD1F9CE3C5}.Debug|x64.ActiveCfg = Debug|Any CPU + {F2181DC4-43EB-4F3A-BD3E-03AD1F9CE3C5}.Debug|x64.Build.0 = Debug|Any CPU + {F2181DC4-43EB-4F3A-BD3E-03AD1F9CE3C5}.Debug|x86.ActiveCfg = Debug|Any CPU + {F2181DC4-43EB-4F3A-BD3E-03AD1F9CE3C5}.Debug|x86.Build.0 = Debug|Any CPU + {F2181DC4-43EB-4F3A-BD3E-03AD1F9CE3C5}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F2181DC4-43EB-4F3A-BD3E-03AD1F9CE3C5}.Release|Any CPU.Build.0 = Release|Any CPU + {F2181DC4-43EB-4F3A-BD3E-03AD1F9CE3C5}.Release|x64.ActiveCfg = Release|Any CPU + {F2181DC4-43EB-4F3A-BD3E-03AD1F9CE3C5}.Release|x64.Build.0 = Release|Any CPU + {F2181DC4-43EB-4F3A-BD3E-03AD1F9CE3C5}.Release|x86.ActiveCfg = Release|Any CPU + {F2181DC4-43EB-4F3A-BD3E-03AD1F9CE3C5}.Release|x86.Build.0 = Release|Any CPU + {321594DF-0087-4FD9-8421-C17C749FF742}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {321594DF-0087-4FD9-8421-C17C749FF742}.Debug|Any CPU.Build.0 = Debug|Any CPU + {321594DF-0087-4FD9-8421-C17C749FF742}.Debug|x64.ActiveCfg = Debug|Any CPU + {321594DF-0087-4FD9-8421-C17C749FF742}.Debug|x64.Build.0 = Debug|Any CPU + {321594DF-0087-4FD9-8421-C17C749FF742}.Debug|x86.ActiveCfg = Debug|Any CPU + {321594DF-0087-4FD9-8421-C17C749FF742}.Debug|x86.Build.0 = Debug|Any CPU + {321594DF-0087-4FD9-8421-C17C749FF742}.Release|Any CPU.ActiveCfg = Release|Any CPU + {321594DF-0087-4FD9-8421-C17C749FF742}.Release|Any CPU.Build.0 = Release|Any CPU + {321594DF-0087-4FD9-8421-C17C749FF742}.Release|x64.ActiveCfg = Release|Any CPU + {321594DF-0087-4FD9-8421-C17C749FF742}.Release|x64.Build.0 = Release|Any CPU + {321594DF-0087-4FD9-8421-C17C749FF742}.Release|x86.ActiveCfg = Release|Any CPU + {321594DF-0087-4FD9-8421-C17C749FF742}.Release|x86.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {F310596E-88BB-9E54-885E-21C61971917E} = {5B52EF8A-3661-DCFF-797D-BC4D6AC60BDA} + {D9492ED1-A812-924B-65E4-F518592B49BB} = {F310596E-88BB-9E54-885E-21C61971917E} + {3823DE1E-2ACE-C956-99E1-00DB786D9E1D} = {D9492ED1-A812-924B-65E4-F518592B49BB} + {03DFF14F-7321-1784-D4C7-4E99D4120F48} = {5B52EF8A-3661-DCFF-797D-BC4D6AC60BDA} + {BDD326D6-7616-84F0-B914-74743BFBA520} = {03DFF14F-7321-1784-D4C7-4E99D4120F48} + {EC506DBE-AB6D-492E-786E-8B176021BF2E} = {BDD326D6-7616-84F0-B914-74743BFBA520} + {5AC09D9A-F2A5-9CFA-B3C5-8D25F257651C} = {5B52EF8A-3661-DCFF-797D-BC4D6AC60BDA} + {33B1AE27-692A-1778-48C1-CCEC2B9BC78F} = {5AC09D9A-F2A5-9CFA-B3C5-8D25F257651C} + {018E0E11-1CCE-A2BE-641D-21EE14D2E90D} = {5AC09D9A-F2A5-9CFA-B3C5-8D25F257651C} + {5F27FB4E-CF09-3A6B-F5B4-BF5A709FA609} = {33B1AE27-692A-1778-48C1-CCEC2B9BC78F} + {AB67BDB9-D701-3AC9-9CDF-ECCDCCD8DB6D} = {5AC09D9A-F2A5-9CFA-B3C5-8D25F257651C} + {3F605548-87E2-8A1D-306D-0CE6960B8242} = {AB67BDB9-D701-3AC9-9CDF-ECCDCCD8DB6D} + {45F7FA87-7451-6970-7F6E-F8BAE45E081B} = {AB67BDB9-D701-3AC9-9CDF-ECCDCCD8DB6D} + {C1DCEFBD-12A5-EAAE-632E-8EEB9BE491B6} = {5B52EF8A-3661-DCFF-797D-BC4D6AC60BDA} + {A6928CBA-4D4D-AB2B-CA19-FEE6E73ECE70} = {C1DCEFBD-12A5-EAAE-632E-8EEB9BE491B6} + {F2E6CB0E-DF77-1FAA-582B-62B040DF3848} = {A6928CBA-4D4D-AB2B-CA19-FEE6E73ECE70} + {C494ECBE-DEA5-3576-D2AF-200FF12BC144} = {A6928CBA-4D4D-AB2B-CA19-FEE6E73ECE70} + {64689413-46D7-8499-68A6-B6367ACBC597} = {A6928CBA-4D4D-AB2B-CA19-FEE6E73ECE70} + {157C3671-CA0B-69FA-A7C9-74A1FDA97B99} = {5B52EF8A-3661-DCFF-797D-BC4D6AC60BDA} + {F39E09D6-BF93-B64A-CFE7-2BA92815C0FE} = {157C3671-CA0B-69FA-A7C9-74A1FDA97B99} + {39EFDA5B-F5EE-8212-D5BA-90E1B82013E7} = {F39E09D6-BF93-B64A-CFE7-2BA92815C0FE} + {3B82DBF3-3DAE-EA97-85F4-6DCFA09940DF} = {F39E09D6-BF93-B64A-CFE7-2BA92815C0FE} + {A4FEB09C-E55C-03AE-8FC2-BF6D4F6C9FD7} = {F39E09D6-BF93-B64A-CFE7-2BA92815C0FE} + {67E71A20-7221-A495-BBCA-9B40D5193448} = {F39E09D6-BF93-B64A-CFE7-2BA92815C0FE} + {3FC9AD6C-AF2C-E557-4D34-8E52BA6AD9E8} = {F39E09D6-BF93-B64A-CFE7-2BA92815C0FE} + {6844B539-C2A3-9D4F-139D-9D533BCABADA} = {F39E09D6-BF93-B64A-CFE7-2BA92815C0FE} + {4263AA71-0335-3F44-9A9B-423C3A3D05E6} = {F39E09D6-BF93-B64A-CFE7-2BA92815C0FE} + {F1B1DB47-D2D7-59CB-679B-23E4928E8328} = {F39E09D6-BF93-B64A-CFE7-2BA92815C0FE} + {BC35DE94-4F04-3436-27A3-F11647FEDD5C} = {F39E09D6-BF93-B64A-CFE7-2BA92815C0FE} + {864C8B80-771A-0C15-30A5-558F99006E0D} = {F39E09D6-BF93-B64A-CFE7-2BA92815C0FE} + {603E7A23-1D6B-D3A9-B0E6-3E332B13ED5C} = {F39E09D6-BF93-B64A-CFE7-2BA92815C0FE} + {D2F7E58B-47D4-5205-D917-144CA1CFF4F1} = {F39E09D6-BF93-B64A-CFE7-2BA92815C0FE} + {1DCF4EBB-DBC4-752C-13D4-D1EECE4E8907} = {F39E09D6-BF93-B64A-CFE7-2BA92815C0FE} + {1B37A859-E733-60CB-4806-1A24B6F10E05} = {F39E09D6-BF93-B64A-CFE7-2BA92815C0FE} + {F2B58F4E-6F28-A25F-5BFB-CDEBAD6B9A3E} = {F39E09D6-BF93-B64A-CFE7-2BA92815C0FE} + {C4A90603-BE42-0044-CAB4-3EB910AD51A5} = {5B52EF8A-3661-DCFF-797D-BC4D6AC60BDA} + {054761F9-16D3-B2F8-6F4D-EFC2248805CD} = {C4A90603-BE42-0044-CAB4-3EB910AD51A5} + {B54CE64C-4167-1DD1-B7D6-2FD7A5AEF715} = {C4A90603-BE42-0044-CAB4-3EB910AD51A5} + {8E6B774C-CC4E-CE7C-AD4B-8AF7C92889A6} = {5B52EF8A-3661-DCFF-797D-BC4D6AC60BDA} + {BC12ED55-6015-7C8B-8384-B39CE93C76D6} = {8E6B774C-CC4E-CE7C-AD4B-8AF7C92889A6} + {FF70543D-AFF9-1D38-4950-4F8EE18D60BB} = {8E6B774C-CC4E-CE7C-AD4B-8AF7C92889A6} + {831265B0-8896-9C95-3488-E12FD9F6DC53} = {FF70543D-AFF9-1D38-4950-4F8EE18D60BB} + {316BBD0A-04D2-85C9-52EA-7993CC6C8930} = {5B52EF8A-3661-DCFF-797D-BC4D6AC60BDA} + {9D6AB85A-85EA-D85A-5566-A121D34016E6} = {316BBD0A-04D2-85C9-52EA-7993CC6C8930} + {FC018E5B-1E2F-DE19-1E97-0C845058C469} = {5B52EF8A-3661-DCFF-797D-BC4D6AC60BDA} + {1BE5B76C-B486-560B-6CB2-44C6537249AA} = {FC018E5B-1E2F-DE19-1E97-0C845058C469} + {F4F1CBE2-1CDD-CAA4-41F0-266DB4677C05} = {1BE5B76C-B486-560B-6CB2-44C6537249AA} + {5896C4B3-31D1-1EDD-11D0-C46DB178DC12} = {5B52EF8A-3661-DCFF-797D-BC4D6AC60BDA} + {D4D193A8-47D7-0B1A-1327-F9C580E7AD07} = {5896C4B3-31D1-1EDD-11D0-C46DB178DC12} + {69C91AE6-4555-7B2C-AD32-F7F11B9C605A} = {D4D193A8-47D7-0B1A-1327-F9C580E7AD07} + {C9BCCEDF-7B8A-BCD8-A6B4-75EB25689FE8} = {D4D193A8-47D7-0B1A-1327-F9C580E7AD07} + {9F30DC58-7747-31D8-2403-D7D0F5454C87} = {D4D193A8-47D7-0B1A-1327-F9C580E7AD07} + {336213F7-1241-D268-8EA5-1C73F0040714} = {D4D193A8-47D7-0B1A-1327-F9C580E7AD07} + {5693F73D-6707-6F86-65D6-654023205615} = {D4D193A8-47D7-0B1A-1327-F9C580E7AD07} + {593308D7-2453-DC66-4151-E983E4B3F422} = {D4D193A8-47D7-0B1A-1327-F9C580E7AD07} + {B24B448A-28D8-778E-DCC1-FCF4A0916DF5} = {5B52EF8A-3661-DCFF-797D-BC4D6AC60BDA} + {BF1AF1AB-97A8-BD70-63F2-E028DE8EE90F} = {B24B448A-28D8-778E-DCC1-FCF4A0916DF5} + {3DB6D7AE-8187-5324-1208-D6090D5324C6} = {BF1AF1AB-97A8-BD70-63F2-E028DE8EE90F} + {3247EE0D-B3E9-9C11-B0AE-FE719410390B} = {5B52EF8A-3661-DCFF-797D-BC4D6AC60BDA} + {CD7C09DA-FEC8-2CC5-D00C-E525638DFF4A} = {3247EE0D-B3E9-9C11-B0AE-FE719410390B} + {79B10804-91E9-972E-1913-EE0F0B11663E} = {CD7C09DA-FEC8-2CC5-D00C-E525638DFF4A} + {1345DD29-BB3A-FB5F-4B3D-E29F6045A27A} = {5B52EF8A-3661-DCFF-797D-BC4D6AC60BDA} + {9C2DD234-FA33-FDB6-86F0-EF9B75A13450} = {1345DD29-BB3A-FB5F-4B3D-E29F6045A27A} + {79E122F4-2325-3E92-438E-5825A307B594} = {1345DD29-BB3A-FB5F-4B3D-E29F6045A27A} + {538E2D98-5325-3F54-BE74-EFE5FC1ECBD8} = {1345DD29-BB3A-FB5F-4B3D-E29F6045A27A} + {66557252-B5C4-664B-D807-07018C627474} = {1345DD29-BB3A-FB5F-4B3D-E29F6045A27A} + {7203223D-FF02-7BEB-2798-D1639ACC01C4} = {1345DD29-BB3A-FB5F-4B3D-E29F6045A27A} + {5AC9EE40-1881-5F8A-46A2-2C303950D3C8} = {1345DD29-BB3A-FB5F-4B3D-E29F6045A27A} + {3C69853C-90E3-D889-1960-3B9229882590} = {1345DD29-BB3A-FB5F-4B3D-E29F6045A27A} + {643E4D4C-BC96-A37F-E0EC-488127F0B127} = {1345DD29-BB3A-FB5F-4B3D-E29F6045A27A} + {6F2CA7F5-3E7C-C61B-94E6-E7DD1227B5B1} = {1345DD29-BB3A-FB5F-4B3D-E29F6045A27A} + {F04B7DBB-77A5-C978-B2DE-8C189A32AA72} = {1345DD29-BB3A-FB5F-4B3D-E29F6045A27A} + {7C72F22A-20FF-DF5B-9191-6DFD0D497DB2} = {1345DD29-BB3A-FB5F-4B3D-E29F6045A27A} + {C896CC0A-F5E6-9AA4-C582-E691441F8D32} = {1345DD29-BB3A-FB5F-4B3D-E29F6045A27A} + {0AA3A418-AB45-CCA4-46D4-EEBFE011FECA} = {1345DD29-BB3A-FB5F-4B3D-E29F6045A27A} + {225D9926-4AE8-E539-70AD-8698E688F271} = {1345DD29-BB3A-FB5F-4B3D-E29F6045A27A} + {D6E8E69C-F721-BBCB-8C39-9716D53D72AD} = {1345DD29-BB3A-FB5F-4B3D-E29F6045A27A} + {589A43FD-8213-E9E3-6CFF-9CBA72D53E98} = {1345DD29-BB3A-FB5F-4B3D-E29F6045A27A} + {2BACF7E3-1278-FE99-8343-8221E6FBA9DE} = {1345DD29-BB3A-FB5F-4B3D-E29F6045A27A} + {75E47125-E4D7-8482-F1A4-726564970864} = {1345DD29-BB3A-FB5F-4B3D-E29F6045A27A} + {FCD529E0-DD17-6587-B29C-12D425C0AD0C} = {1345DD29-BB3A-FB5F-4B3D-E29F6045A27A} + {61B23570-4F2D-B060-BE1F-37995682E494} = {1345DD29-BB3A-FB5F-4B3D-E29F6045A27A} + {1182764D-2143-EEF0-9270-3DCE392F5D06} = {1345DD29-BB3A-FB5F-4B3D-E29F6045A27A} + {772B02B5-6280-E1D4-3E2E-248D0455C2FB} = {1345DD29-BB3A-FB5F-4B3D-E29F6045A27A} + {48F90289-938C-CCA7-B60F-D2143E7C9A69} = {1345DD29-BB3A-FB5F-4B3D-E29F6045A27A} + {E69FA1A0-6D1B-A6E4-2DC0-8F4C5F21BF04} = {1345DD29-BB3A-FB5F-4B3D-E29F6045A27A} + {083067CF-CE89-EF39-9BD3-4741919E26F3} = {1345DD29-BB3A-FB5F-4B3D-E29F6045A27A} + {A7542386-71EB-4F34-E1CE-27D399325955} = {1345DD29-BB3A-FB5F-4B3D-E29F6045A27A} + {90659617-4DF7-809A-4E5B-29BB5A98E8E1} = {5B52EF8A-3661-DCFF-797D-BC4D6AC60BDA} + {AB8B269C-5A2A-A4B8-0488-B5F81E55B4D9} = {90659617-4DF7-809A-4E5B-29BB5A98E8E1} + {A527DABC-AA87-7C64-8056-4627531A9960} = {AB8B269C-5A2A-A4B8-0488-B5F81E55B4D9} + {CEDC2447-F717-3C95-7E08-F214D575A7B7} = {AB8B269C-5A2A-A4B8-0488-B5F81E55B4D9} + {52220F70-4EAA-D93F-752B-CD431AAEEDDB} = {945F81BC-6A17-B466-15B3-47E17BBFFEEE} + {C0C58E4B-9B24-29EA-9585-4BB462666824} = {678BFC83-F74C-CD21-AFE5-9F1FD29B4092} + {24D80D5F-0A63-7924-B7C3-79A2772A28DF} = {569894C1-998D-B530-0EAA-AE633B3BC297} + {8A3083F4-FBB0-6972-9FB5-FE3D05488CD6} = {F3E2E624-EBEF-D7C4-007E-1297E7001D38} + {13E7A80F-191B-0B12-4C7F-A1CA9808DD65} = {94E5B89C-8E1D-757B-350E-821DBEADD75D} + {A82DBB41-8BF0-440B-1BD1-611A2521DAA0} = {9475E1E8-B4B3-EFFC-3B43-71F90D2021F2} + {8C96DAFC-3A63-EB7B-EA8F-07A63817204D} = {22A9ABBF-F2DA-7E3C-B6E2-05A8AE8A24F5} + {AD31623A-BC43-52C2-D906-AC1D8784A541} = {3823DE1E-2ACE-C956-99E1-00DB786D9E1D} + {776E2142-804F-03B9-C804-D061D64C6092} = {EC506DBE-AB6D-492E-786E-8B176021BF2E} + {5B4DF41E-C8CC-2606-FA2D-967118BD3C59} = {5F27FB4E-CF09-3A6B-F5B4-BF5A709FA609} + {3D8C5A6C-462D-7487-5BD0-A3EF6B657EB6} = {018E0E11-1CCE-A2BE-641D-21EE14D2E90D} + {2609BC1A-6765-29BE-78CC-C0F1D2814F10} = {3F605548-87E2-8A1D-306D-0CE6960B8242} + {C6822231-A4F4-9E69-6CE2-4FDB3E81C728} = {45F7FA87-7451-6970-7F6E-F8BAE45E081B} + {55D9B653-FB76-FCE8-1A3C-67B1BEDEC214} = {F2E6CB0E-DF77-1FAA-582B-62B040DF3848} + {DE5BF139-1E5C-D6EA-4FAA-661EF353A194} = {C494ECBE-DEA5-3576-D2AF-200FF12BC144} + {335E62C0-9E69-A952-680B-753B1B17C6D0} = {9C2DD234-FA33-FDB6-86F0-EF9B75A13450} + {97F94029-5419-6187-5A63-5C8FD9232FAE} = {64689413-46D7-8499-68A6-B6367ACBC597} + {AF9E7F02-25AD-3540-18D7-F6A4F8BA5A60} = {79E122F4-2325-3E92-438E-5825A307B594} + {AB6AE2B6-8D6B-2D9F-2A88-7C596C59F4FC} = {39EFDA5B-F5EE-8212-D5BA-90E1B82013E7} + {375F5AD0-F7EE-1782-7B34-E181CDB61B9F} = {3B82DBF3-3DAE-EA97-85F4-6DCFA09940DF} + {C117E9AF-D7B8-D4E2-4262-84B6321A9F5C} = {A4FEB09C-E55C-03AE-8FC2-BF6D4F6C9FD7} + {D492EFDB-294B-ABA2-FAFB-EAEE6F3DCB52} = {67E71A20-7221-A495-BBCA-9B40D5193448} + {9D0C51AF-D1AB-9E12-0B16-A4AA974FAAB5} = {3FC9AD6C-AF2C-E557-4D34-8E52BA6AD9E8} + {BA45605A-1CCE-6B0C-489D-C113915B243F} = {6844B539-C2A3-9D4F-139D-9D533BCABADA} + {9D31FC8A-2A69-B78A-D3E5-4F867B16D971} = {4263AA71-0335-3F44-9A9B-423C3A3D05E6} + {92268008-FBB0-C7AD-ECC2-7B75BED9F5E1} = {F1B1DB47-D2D7-59CB-679B-23E4928E8328} + {8DCCAF70-D364-4C8B-4E90-AF65091DE0C5} = {BC35DE94-4F04-3436-27A3-F11647FEDD5C} + {7828C164-DD01-2809-CCB3-364486834F60} = {864C8B80-771A-0C15-30A5-558F99006E0D} + {DE95E7B2-0937-A980-441F-829E023BC43E} = {603E7A23-1D6B-D3A9-B0E6-3E332B13ED5C} + {91D69463-23E2-E2C7-AA7E-A78B13CED620} = {D2F7E58B-47D4-5205-D917-144CA1CFF4F1} + {34EFF636-81A7-8DF6-7CC9-4DA784BAC7F3} = {1DCF4EBB-DBC4-752C-13D4-D1EECE4E8907} + {5DCF16A8-97C6-2CB4-6A63-0370239039EB} = {1B37A859-E733-60CB-4806-1A24B6F10E05} + {EB093C48-CDAC-106B-1196-AE34809B34C0} = {F2B58F4E-6F28-A25F-5BFB-CDEBAD6B9A3E} + {370A79BD-AAB3-B833-2B06-A28B3A19E153} = {A527DABC-AA87-7C64-8056-4627531A9960} + {92C62F7B-8028-6EE1-B71B-F45F459B8E97} = {538E2D98-5325-3F54-BE74-EFE5FC1ECBD8} + {F664A948-E352-5808-E780-77A03F19E93E} = {66557252-B5C4-664B-D807-07018C627474} + {FA83F778-5252-0B80-5555-E69F790322EA} = {7203223D-FF02-7BEB-2798-D1639ACC01C4} + {F3A27846-6DE0-3448-222C-25A273E86B2E} = {5AC9EE40-1881-5F8A-46A2-2C303950D3C8} + {C53E0895-879A-D9E6-0A43-24AD17A2F270} = {3C69853C-90E3-D889-1960-3B9229882590} + {0AED303F-69E6-238F-EF80-81985080EDB7} = {643E4D4C-BC96-A37F-E0EC-488127F0B127} + {2904D288-CE64-A565-2C46-C2E85A96A1EE} = {6F2CA7F5-3E7C-C61B-94E6-E7DD1227B5B1} + {A6667CC3-B77F-023E-3A67-05F99E9FF46A} = {F04B7DBB-77A5-C978-B2DE-8C189A32AA72} + {A26E2816-F787-F76B-1D6C-E086DD3E19CE} = {7C72F22A-20FF-DF5B-9191-6DFD0D497DB2} + {B3DEC619-67AC-1B5A-4F3E-A1F24C3F6877} = {C896CC0A-F5E6-9AA4-C582-E691441F8D32} + {90DB65B4-8F6E-FB8E-0281-505AD8BC6BA6} = {0AA3A418-AB45-CCA4-46D4-EEBFE011FECA} + {059FBB86-DEE6-8207-3F23-2A1A3EC00DEA} = {225D9926-4AE8-E539-70AD-8698E688F271} + {8BBA3159-C4CC-F685-A28C-7FE6CBD3D2A1} = {D6E8E69C-F721-BBCB-8C39-9716D53D72AD} + {632A1F0D-1BA5-C84B-B716-2BE638A92780} = {589A43FD-8213-E9E3-6CFF-9CBA72D53E98} + {9DE7852B-7E2D-257E-B0F1-45D2687854ED} = {2BACF7E3-1278-FE99-8343-8221E6FBA9DE} + {DC2AFC89-C3C8-4E9B-13A7-027EB6386EFA} = {75E47125-E4D7-8482-F1A4-726564970864} + {CB296A20-2732-77C1-7F23-27D5BAEDD0C7} = {054761F9-16D3-B2F8-6F4D-EFC2248805CD} + {0DBEC9BA-FE1D-3898-B2C6-E4357DC23E0F} = {B54CE64C-4167-1DD1-B7D6-2FD7A5AEF715} + {A63897D9-9531-989B-7309-E384BCFC2BB9} = {FCD529E0-DD17-6587-B29C-12D425C0AD0C} + {8C594D82-3463-3367-4F06-900AC707753D} = {61B23570-4F2D-B060-BE1F-37995682E494} + {52F400CD-D473-7A1F-7986-89011CD2A887} = {CEDC2447-F717-3C95-7E08-F214D575A7B7} + {9588FBF9-C37E-D16E-2E8F-CFA226EAC01D} = {1182764D-2143-EEF0-9270-3DCE392F5D06} + {97998C88-E6E1-D5E2-B632-537B58E00CBF} = {F4F1CBE2-1CDD-CAA4-41F0-266DB4677C05} + {38A9EE9B-6FC8-93BC-0D43-2A906E678D66} = {772B02B5-6280-E1D4-3E2E-248D0455C2FB} + {19868E2D-7163-2108-1094-F13887C4F070} = {831265B0-8896-9C95-3488-E12FD9F6DC53} + {CC319FC5-F4B1-C3DD-7310-4DAD343E0125} = {BC12ED55-6015-7C8B-8384-B39CE93C76D6} + {84F711C2-C210-28D2-F0D9-B13733FEE23D} = {48F90289-938C-CCA7-B60F-D2143E7C9A69} + {CBB14B90-27F9-8DD6-DFC4-3507DBD1FBC6} = {E69FA1A0-6D1B-A6E4-2DC0-8F4C5F21BF04} + {A78EBC0F-C62C-8F56-95C0-330E376242A2} = {9D6AB85A-85EA-D85A-5566-A121D34016E6} + {6D26FB21-7E48-024B-E5D4-E3F0F31976BB} = {083067CF-CE89-EF39-9BD3-4741919E26F3} + {28D91816-206C-576E-1A83-FD98E08C2E3C} = {69C91AE6-4555-7B2C-AD32-F7F11B9C605A} + {58D8630F-C0F4-B772-8572-BCC98FF0F0D8} = {C9BCCEDF-7B8A-BCD8-A6B4-75EB25689FE8} + {7CB7FEA8-8A12-A5D6-0057-AA65DB328617} = {9F30DC58-7747-31D8-2403-D7D0F5454C87} + {52698305-D6F8-C13C-0882-48FC37726404} = {336213F7-1241-D268-8EA5-1C73F0040714} + {5567139C-0365-B6A0-5DD0-978A09B9F176} = {5693F73D-6707-6F86-65D6-654023205615} + {256D269B-35EA-F833-2F1D-8E0058908DEE} = {593308D7-2453-DC66-4151-E983E4B3F422} + {1F372AB9-D8DD-D295-1D5E-CB5D454CBB24} = {3DB6D7AE-8187-5324-1208-D6090D5324C6} + {0AF13355-173C-3128-5AFC-D32E540DA3EF} = {79B10804-91E9-972E-1913-EE0F0B11663E} + {1D761F8B-921C-53BF-DCF5-5ABD329EEB0C} = {A7542386-71EB-4F34-E1CE-27D399325955} + {50FA7781-4439-465A-8061-BEC5C3469814} = {56BCE1BF-7CBA-7CE8-203D-A88051F1D642} + {F2181DC4-43EB-4F3A-BD3E-03AD1F9CE3C5} = {56BCE1BF-7CBA-7CE8-203D-A88051F1D642} + {321594DF-0087-4FD9-8421-C17C749FF742} = {56BCE1BF-7CBA-7CE8-203D-A88051F1D642} + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {180AF072-9F83-5251-AFF7-C5FF574F0925} + EndGlobalSection +EndGlobal diff --git a/src/Tools/__Tests/FixtureUpdater.Tests/FixtureUpdater.Tests.csproj b/src/Tools/__Tests/FixtureUpdater.Tests/FixtureUpdater.Tests.csproj new file mode 100644 index 000000000..95383e0db --- /dev/null +++ b/src/Tools/__Tests/FixtureUpdater.Tests/FixtureUpdater.Tests.csproj @@ -0,0 +1,16 @@ + + + + net10.0 + enable + enable + false + true + preview + + + + + + + diff --git a/src/Tools/__Tests/FixtureUpdater.Tests/FixtureUpdaterRunnerTests.cs b/src/Tools/__Tests/FixtureUpdater.Tests/FixtureUpdaterRunnerTests.cs new file mode 100644 index 000000000..85b8fa332 --- /dev/null +++ b/src/Tools/__Tests/FixtureUpdater.Tests/FixtureUpdaterRunnerTests.cs @@ -0,0 +1,142 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using StellaOps.Tools.FixtureUpdater; +using Xunit; + +public sealed class FixtureUpdaterRunnerTests +{ + [Fact] + public void Run_IsDeterministic_And_WritesGhsaFixtures() + { + var repoRoot = FindRepoRoot(); + using var temp = new TempDirectory(); + + var osvDir = Path.Combine(temp.Path, "osv"); + var ghsaDir = Path.Combine(temp.Path, "ghsa"); + var nvdDir = Path.Combine(temp.Path, "nvd"); + Directory.CreateDirectory(osvDir); + Directory.CreateDirectory(ghsaDir); + Directory.CreateDirectory(nvdDir); + + File.Copy( + Path.Combine(repoRoot, "src", "Concelier", "__Tests", "StellaOps.Concelier.Connector.Osv.Tests", "Fixtures", "osv-ghsa.raw-osv.json"), + Path.Combine(osvDir, "osv-ghsa.raw-osv.json")); + + File.Copy( + Path.Combine(repoRoot, "src", "Concelier", "__Tests", "StellaOps.Concelier.Connector.Ghsa.Tests", "Fixtures", "osv-ghsa.raw-ghsa.json"), + Path.Combine(ghsaDir, "osv-ghsa.raw-ghsa.json")); + + var options = new FixtureUpdaterOptions( + RepoRoot: null, + OsvFixturesPath: osvDir, + GhsaFixturesPath: ghsaDir, + NvdFixturesPath: nvdDir, + FixedTime: new DateTimeOffset(2025, 1, 1, 0, 0, 0, TimeSpan.Zero)); + + var firstResult = new FixtureUpdaterRunner(options).Run(); + Assert.Equal(0, firstResult.ErrorCount); + + var firstOutputs = ReadOutputs(temp.Path); + + var secondResult = new FixtureUpdaterRunner(options).Run(); + Assert.Equal(0, secondResult.ErrorCount); + + var secondOutputs = ReadOutputs(temp.Path); + Assert.Equal(firstOutputs.Count, secondOutputs.Count); + foreach (var (path, content) in firstOutputs) + { + Assert.True(secondOutputs.TryGetValue(path, out var secondContent)); + Assert.Equal(content, secondContent); + } + + Assert.True(File.Exists(Path.Combine(ghsaDir, "osv-ghsa.ghsa.json"))); + Assert.False(File.Exists(Path.Combine(osvDir, "osv-ghsa.ghsa.json"))); + } + + [Fact] + public void Run_Reports_ParseErrors_With_Context() + { + var repoRoot = FindRepoRoot(); + using var temp = new TempDirectory(); + + var osvDir = Path.Combine(temp.Path, "osv"); + var ghsaDir = Path.Combine(temp.Path, "ghsa"); + var nvdDir = Path.Combine(temp.Path, "nvd"); + Directory.CreateDirectory(osvDir); + Directory.CreateDirectory(ghsaDir); + Directory.CreateDirectory(nvdDir); + + File.Copy( + Path.Combine(repoRoot, "src", "Concelier", "__Tests", "StellaOps.Concelier.Connector.Osv.Tests", "Fixtures", "osv-ghsa.raw-osv.json"), + Path.Combine(osvDir, "osv-ghsa.raw-osv.json")); + + File.WriteAllText(Path.Combine(ghsaDir, "osv-ghsa.raw-ghsa.json"), "{ broken json }"); + + var errors = new List(); + var options = new FixtureUpdaterOptions( + RepoRoot: null, + OsvFixturesPath: osvDir, + GhsaFixturesPath: ghsaDir, + NvdFixturesPath: nvdDir, + FixedTime: new DateTimeOffset(2025, 1, 1, 0, 0, 0, TimeSpan.Zero)); + + var result = new FixtureUpdaterRunner(options, _ => { }, message => errors.Add(message)).Run(); + Assert.True(result.ErrorCount > 0); + Assert.Contains(errors, message => message.Contains("osv-ghsa.raw-ghsa.json", StringComparison.Ordinal)); + } + + private static Dictionary ReadOutputs(string root) + { + var files = Directory.GetFiles(root, "*.json", SearchOption.AllDirectories) + .OrderBy(path => path, StringComparer.Ordinal) + .ToArray(); + + var outputs = new Dictionary(StringComparer.Ordinal); + foreach (var file in files) + { + var relative = Path.GetRelativePath(root, file); + var content = File.ReadAllText(file).ReplaceLineEndings("\n"); + outputs[relative] = content; + } + + return outputs; + } + + private static string FindRepoRoot() + { + var current = new DirectoryInfo(AppContext.BaseDirectory); + while (current is not null) + { + var solution = Path.Combine(current.FullName, "src", "StellaOps.sln"); + if (File.Exists(solution)) + { + return current.FullName; + } + + current = current.Parent; + } + + throw new InvalidOperationException("Repository root not found."); + } + + private sealed class TempDirectory : IDisposable + { + public TempDirectory() + { + Path = System.IO.Path.Combine(System.IO.Path.GetTempPath(), $"fixture-updater-{Guid.NewGuid():N}"); + Directory.CreateDirectory(Path); + } + + public string Path { get; } + + public void Dispose() + { + if (Directory.Exists(Path)) + { + Directory.Delete(Path, recursive: true); + } + } + } +} diff --git a/src/Tools/__Tests/LanguageAnalyzerSmoke.Tests/LanguageAnalyzerSmoke.Tests.csproj b/src/Tools/__Tests/LanguageAnalyzerSmoke.Tests/LanguageAnalyzerSmoke.Tests.csproj new file mode 100644 index 000000000..05d4de41f --- /dev/null +++ b/src/Tools/__Tests/LanguageAnalyzerSmoke.Tests/LanguageAnalyzerSmoke.Tests.csproj @@ -0,0 +1,16 @@ + + + + net10.0 + enable + enable + false + true + preview + + + + + + + diff --git a/src/Tools/__Tests/LanguageAnalyzerSmoke.Tests/LanguageAnalyzerSmokeRunnerTests.cs b/src/Tools/__Tests/LanguageAnalyzerSmoke.Tests/LanguageAnalyzerSmokeRunnerTests.cs new file mode 100644 index 000000000..5a7f65742 --- /dev/null +++ b/src/Tools/__Tests/LanguageAnalyzerSmoke.Tests/LanguageAnalyzerSmokeRunnerTests.cs @@ -0,0 +1,76 @@ +using System; +using System.Collections.Generic; +using StellaOps.Tools.LanguageAnalyzerSmoke; +using Xunit; + +public sealed class LanguageAnalyzerSmokeRunnerTests +{ + [Fact] + public void Resolve_UsesProfileDefaults_WhenOverridesMissing() + { + var profile = AnalyzerProfileCatalog.GetProfile("python"); + var options = SmokeOptions.Resolve( + repoRoot: "C:\\repo", + analyzerId: "python", + pluginDirectoryName: null, + fixtureRelativePath: null, + allowGoldenDrift: false, + fixedTime: new DateTimeOffset(2025, 1, 1, 0, 0, 0, TimeSpan.Zero), + useSystemTime: false, + timeoutSeconds: 120); + + Assert.Equal(profile.PluginDirectory, options.PluginDirectoryName); + Assert.Equal(profile.FixtureRelativePath, options.FixtureRelativePath); + Assert.Equal(profile.AnalyzerId, options.AnalyzerId); + } + + [Fact] + public void ValidateManifest_RejectsMissingCapabilities() + { + var profile = AnalyzerProfileCatalog.GetProfile("python"); + var manifest = new PluginManifest + { + SchemaVersion = "1.0", + Id = profile.ExpectedPluginId, + RequiresRestart = true, + EntryPoint = new PluginEntryPoint + { + Type = "dotnet", + TypeName = profile.ExpectedEntryPointType, + Assembly = "Plugin.dll" + }, + Capabilities = Array.Empty() + }; + + var exception = Assert.Throws(() => + LanguageAnalyzerSmokeRunner.ValidateManifest(manifest, profile, profile.PluginDirectory)); + Assert.Contains("capability", exception.Message, StringComparison.OrdinalIgnoreCase); + } + + [Fact] + public void CompareGoldenSnapshot_Throws_WhenDriftNotAllowed() + { + Assert.Throws(() => + LanguageAnalyzerSmokeRunner.CompareGoldenSnapshot( + scenarioName: "sample", + actualJson: "{\"a\":1}", + goldenNormalized: "{\"a\":2}", + allowGoldenDrift: false, + info: _ => { })); + } + + [Fact] + public void CompareGoldenSnapshot_AllowsWhenDriftAllowed() + { + var warnings = new List(); + LanguageAnalyzerSmokeRunner.CompareGoldenSnapshot( + scenarioName: "sample", + actualJson: "{\"a\":1}", + goldenNormalized: "{\"a\":2}", + allowGoldenDrift: true, + info: message => warnings.Add(message)); + + Assert.Single(warnings); + Assert.Contains("golden", warnings[0], StringComparison.OrdinalIgnoreCase); + } +} diff --git a/src/Tools/__Tests/NotifySmokeCheck.Tests/NotifySmokeCheck.Tests.csproj b/src/Tools/__Tests/NotifySmokeCheck.Tests/NotifySmokeCheck.Tests.csproj new file mode 100644 index 000000000..bb0f7251b --- /dev/null +++ b/src/Tools/__Tests/NotifySmokeCheck.Tests/NotifySmokeCheck.Tests.csproj @@ -0,0 +1,16 @@ + + + + net10.0 + enable + enable + false + true + preview + + + + + + + diff --git a/src/Tools/__Tests/NotifySmokeCheck.Tests/NotifySmokeCheckRunnerTests.cs b/src/Tools/__Tests/NotifySmokeCheck.Tests/NotifySmokeCheckRunnerTests.cs new file mode 100644 index 000000000..3138ed6b7 --- /dev/null +++ b/src/Tools/__Tests/NotifySmokeCheck.Tests/NotifySmokeCheckRunnerTests.cs @@ -0,0 +1,66 @@ +using System; +using System.Collections.Generic; +using StackExchange.Redis; +using StellaOps.Tools.NotifySmokeCheck; +using Xunit; + +public sealed class NotifySmokeCheckRunnerTests +{ + [Fact] + public void FromEnvironment_ParsesExpectedKinds() + { + var env = new Dictionary(StringComparer.Ordinal) + { + ["NOTIFY_SMOKE_REDIS_DSN"] = "localhost:6379", + ["NOTIFY_SMOKE_EXPECT_KINDS"] = "scan, scan, Alert", + ["NOTIFY_SMOKE_LOOKBACK_MINUTES"] = "15", + ["NOTIFY_SMOKE_NOTIFY_BASEURL"] = "https://notify.local", + ["NOTIFY_SMOKE_NOTIFY_TOKEN"] = "token", + ["NOTIFY_SMOKE_NOTIFY_TENANT"] = "tenant" + }; + + var options = NotifySmokeOptions.FromEnvironment(name => env.TryGetValue(name, out var value) ? value : null); + + Assert.Equal(new[] { "scan", "alert" }, options.ExpectedKinds); + } + + [Fact] + public void FromEnvironment_UsesFixedTimeWhenProvided() + { + var env = new Dictionary(StringComparer.Ordinal) + { + ["NOTIFY_SMOKE_REDIS_DSN"] = "localhost:6379", + ["NOTIFY_SMOKE_EXPECT_KINDS"] = "scan", + ["NOTIFY_SMOKE_LOOKBACK_MINUTES"] = "5", + ["NOTIFY_SMOKE_NOTIFY_BASEURL"] = "https://notify.local", + ["NOTIFY_SMOKE_NOTIFY_TOKEN"] = "token", + ["NOTIFY_SMOKE_NOTIFY_TENANT"] = "tenant", + ["NOTIFY_SMOKE_FIXED_TIME"] = "2025-01-02T03:04:05Z" + }; + + var options = NotifySmokeOptions.FromEnvironment(name => env.TryGetValue(name, out var value) ? value : null); + Assert.Equal(new DateTimeOffset(2025, 1, 2, 3, 4, 5, TimeSpan.Zero), options.TimeProvider.GetUtcNow()); + } + + [Fact] + public void ParseDeliveries_HandlesItemsArray() + { + var json = "{\"items\":[{\"kind\":\"scan\",\"status\":\"delivered\"},{\"kind\":\"vex\",\"status\":\"failed\"}]}"; + var deliveries = NotifySmokeCheckRunner.ParseDeliveries(json); + + Assert.Equal(2, deliveries.Count); + Assert.Equal("scan", deliveries[0].Kind, StringComparer.OrdinalIgnoreCase); + Assert.Equal("delivered", deliveries[0].Status, StringComparer.OrdinalIgnoreCase); + } + + [Fact] + public void TryGetStreamTimestamp_ParsesEntryId() + { + var entry = new StreamEntry("1700000000000-0", Array.Empty()); + + var success = NotifySmokeCheckRunner.TryGetStreamTimestamp(entry, out var timestamp); + + Assert.True(success); + Assert.Equal(DateTimeOffset.FromUnixTimeMilliseconds(1700000000000), timestamp); + } +} diff --git a/src/Tools/__Tests/PolicyDslValidator.Tests/PolicyDslValidator.Tests.csproj b/src/Tools/__Tests/PolicyDslValidator.Tests/PolicyDslValidator.Tests.csproj new file mode 100644 index 000000000..3a38d1f7e --- /dev/null +++ b/src/Tools/__Tests/PolicyDslValidator.Tests/PolicyDslValidator.Tests.csproj @@ -0,0 +1,16 @@ + + + + net10.0 + enable + enable + false + true + preview + + + + + + + diff --git a/src/Tools/__Tests/PolicyDslValidator.Tests/PolicyDslValidatorAppTests.cs b/src/Tools/__Tests/PolicyDslValidator.Tests/PolicyDslValidatorAppTests.cs new file mode 100644 index 000000000..f3a6af08b --- /dev/null +++ b/src/Tools/__Tests/PolicyDslValidator.Tests/PolicyDslValidatorAppTests.cs @@ -0,0 +1,44 @@ +using StellaOps.Policy; +using StellaOps.Policy.Tools; + +public sealed class PolicyDslValidatorAppTests +{ + [Fact] + public async Task RunAsync_ReturnsUsageExitCode_OnMissingInputs() + { + var runner = new CapturingRunner(); + + var exitCode = await PolicyDslValidatorApp.RunAsync(Array.Empty(), runner); + + Assert.Equal(64, exitCode); + Assert.False(runner.WasCalled); + } + + [Fact] + public async Task Command_CapturesStrictAndJson() + { + var runner = new CapturingRunner(); + var exitCode = await PolicyDslValidatorApp.RunAsync(new[] { "--strict", "--json", "policy.json" }, runner); + + Assert.Equal(0, exitCode); + Assert.True(runner.WasCalled); + Assert.NotNull(runner.CapturedOptions); + Assert.True(runner.CapturedOptions!.Strict); + Assert.True(runner.CapturedOptions!.OutputJson); + Assert.Single(runner.CapturedOptions!.Inputs); + Assert.Equal("policy.json", runner.CapturedOptions!.Inputs[0]); + } + + private sealed class CapturingRunner : IPolicyValidationRunner + { + public PolicyValidationCliOptions? CapturedOptions { get; private set; } + public bool WasCalled { get; private set; } + + public Task RunAsync(PolicyValidationCliOptions options, CancellationToken cancellationToken) + { + CapturedOptions = options; + WasCalled = true; + return Task.FromResult(0); + } + } +} diff --git a/src/Tools/__Tests/PolicySchemaExporter.Tests/PolicySchemaExporter.Tests.csproj b/src/Tools/__Tests/PolicySchemaExporter.Tests/PolicySchemaExporter.Tests.csproj new file mode 100644 index 000000000..dc91d609f --- /dev/null +++ b/src/Tools/__Tests/PolicySchemaExporter.Tests/PolicySchemaExporter.Tests.csproj @@ -0,0 +1,16 @@ + + + + net10.0 + enable + enable + false + true + preview + + + + + + + diff --git a/src/Tools/__Tests/PolicySchemaExporter.Tests/PolicySchemaExporterTests.cs b/src/Tools/__Tests/PolicySchemaExporter.Tests/PolicySchemaExporterTests.cs new file mode 100644 index 000000000..2707667f8 --- /dev/null +++ b/src/Tools/__Tests/PolicySchemaExporter.Tests/PolicySchemaExporterTests.cs @@ -0,0 +1,46 @@ +using System.IO; +using StellaOps.Policy.Tools; + +public sealed class PolicySchemaExporterTests +{ + [Fact] + public void GenerateSchemas_IsStableAndHasExpectedNames() + { + var exports = PolicySchemaExporterSchema.BuildExports(); + + var first = PolicySchemaExporterSchema.GenerateSchemas( + PolicySchemaExporterSchema.CreateGenerator(), + exports); + var second = PolicySchemaExporterSchema.GenerateSchemas( + PolicySchemaExporterSchema.CreateGenerator(), + exports); + + Assert.Equal(exports.Length, first.Count); + foreach (var export in exports) + { + Assert.True(first.ContainsKey(export.FileName)); + Assert.True(second.ContainsKey(export.FileName)); + Assert.Equal(first[export.FileName], second[export.FileName]); + } + } + + [Fact] + public void ResolveOutputDirectory_UsesRepoRootForRelativeOutput() + { + var repoRoot = Path.Combine(Path.GetTempPath(), "schema-exporter"); + var resolved = PolicySchemaExporterPaths.ResolveOutputDirectory("out", repoRoot); + var expected = Path.GetFullPath(Path.Combine(repoRoot, "out")); + + Assert.Equal(expected, resolved); + } + + [Fact] + public void ResolveDefaultOutputDirectory_UsesRepoRootDocsSchemas() + { + var repoRoot = Path.Combine(Path.GetTempPath(), "schema-exporter-root"); + var resolved = PolicySchemaExporterPaths.ResolveDefaultOutputDirectory(repoRoot); + var expected = Path.GetFullPath(Path.Combine(repoRoot, "docs", "schemas")); + + Assert.Equal(expected, resolved); + } +} diff --git a/src/Tools/__Tests/PolicySimulationSmoke.Tests/PolicySimulationSmoke.Tests.csproj b/src/Tools/__Tests/PolicySimulationSmoke.Tests/PolicySimulationSmoke.Tests.csproj new file mode 100644 index 000000000..5c83eab55 --- /dev/null +++ b/src/Tools/__Tests/PolicySimulationSmoke.Tests/PolicySimulationSmoke.Tests.csproj @@ -0,0 +1,16 @@ + + + + net10.0 + enable + enable + false + true + preview + + + + + + + diff --git a/src/Tools/__Tests/PolicySimulationSmoke.Tests/PolicySimulationSmokeEvaluatorTests.cs b/src/Tools/__Tests/PolicySimulationSmoke.Tests/PolicySimulationSmokeEvaluatorTests.cs new file mode 100644 index 000000000..66f8a8da4 --- /dev/null +++ b/src/Tools/__Tests/PolicySimulationSmoke.Tests/PolicySimulationSmokeEvaluatorTests.cs @@ -0,0 +1,67 @@ +using System.Collections.Immutable; +using StellaOps.Policy; +using StellaOps.Policy.Tools; + +public sealed class PolicySimulationSmokeEvaluatorTests +{ + [Fact] + public void EvaluateScenario_FailsWhenPreviewFails() + { + var scenario = new PolicySimulationScenario { Name = "demo" }; + var response = new PolicyPreviewResponse( + Success: false, + PolicyDigest: "digest", + RevisionId: null, + Issues: ImmutableArray.Empty, + Diffs: ImmutableArray.Empty, + ChangedCount: 0); + + var result = PolicySimulationSmokeEvaluator.EvaluateScenario(scenario, response); + + Assert.False(result.Success); + Assert.Contains("Preview failed.", result.Failures); + } + + [Fact] + public void EvaluateScenario_FailsWhenExpectedDiffMissing() + { + var scenario = new PolicySimulationScenario + { + Name = "demo", + ExpectedDiffs = new List + { + new ScenarioExpectedDiff { FindingId = "F-1", Status = "Blocked" } + } + }; + + var baseline = new PolicyVerdict("F-2", PolicyVerdictStatus.Pass); + var projected = new PolicyVerdict("F-2", PolicyVerdictStatus.Pass); + var diff = new PolicyVerdictDiff(baseline, projected); + + var response = new PolicyPreviewResponse( + Success: true, + PolicyDigest: "digest", + RevisionId: null, + Issues: ImmutableArray.Empty, + Diffs: ImmutableArray.Create(diff), + ChangedCount: 1); + + var result = PolicySimulationSmokeEvaluator.EvaluateScenario(scenario, response); + + Assert.False(result.Success); + Assert.Contains("Expected finding 'F-1' missing from diff.", result.Failures); + } + + [Fact] + public async Task RunAsync_ReturnsNoInputWhenScenarioRootMissing() + { + var runner = new PolicySimulationSmokeRunner(); + var missingRoot = Path.Combine(Path.GetTempPath(), "stellaops-missing-" + Guid.NewGuid().ToString("N")); + + var exitCode = await runner.RunAsync( + new PolicySimulationSmokeOptions { ScenarioRoot = missingRoot }, + CancellationToken.None); + + Assert.Equal(66, exitCode); + } +} diff --git a/src/Tools/__Tests/RustFsMigrator.Tests/RustFsMigrator.Tests.csproj b/src/Tools/__Tests/RustFsMigrator.Tests/RustFsMigrator.Tests.csproj new file mode 100644 index 000000000..912da38c8 --- /dev/null +++ b/src/Tools/__Tests/RustFsMigrator.Tests/RustFsMigrator.Tests.csproj @@ -0,0 +1,16 @@ + + + + net10.0 + enable + enable + false + true + preview + + + + + + + diff --git a/src/Tools/__Tests/RustFsMigrator.Tests/RustFsMigratorTests.cs b/src/Tools/__Tests/RustFsMigrator.Tests/RustFsMigratorTests.cs new file mode 100644 index 000000000..fab4350b0 --- /dev/null +++ b/src/Tools/__Tests/RustFsMigrator.Tests/RustFsMigratorTests.cs @@ -0,0 +1,42 @@ +using System; +using Xunit; + +public sealed class RustFsMigratorTests +{ + [Fact] + public void Parse_ExtractsRetryAndTimeoutOptions() + { + var options = MigrationOptions.Parse(new[] + { + "--s3-bucket", "bucket", + "--rustfs-endpoint", "http://rustfs:8080", + "--rustfs-bucket", "target", + "--retry-attempts", "5", + "--retry-delay-ms", "500", + "--timeout-seconds", "60", + "--retain-days", "1.5" + }); + + Assert.NotNull(options); + Assert.Equal(5, options!.RetryAttempts); + Assert.Equal(500, options.RetryDelayMs); + Assert.Equal(60, options.TimeoutSeconds); + Assert.NotNull(options.RetentionSeconds); + Assert.True(options.RetentionSeconds > 0); + } + + [Fact] + public void BuildRustFsUri_EncodesObjectKey() + { + var options = new MigrationOptions + { + RustFsEndpoint = "https://rustfs.local", + RustFsBucket = "scanner artifacts" + }; + + var uri = RustFsMigratorPaths.BuildRustFsUri(options, "path/with space/file.txt"); + Assert.Equal("https", uri.Scheme); + Assert.Contains("scanner%20artifacts", uri.AbsoluteUri, StringComparison.Ordinal); + Assert.Contains("path/with%20space/file.txt", uri.AbsoluteUri, StringComparison.Ordinal); + } +} diff --git a/src/__Libraries/StellaOps.Policy.Tools/PolicyDslValidatorApp.cs b/src/__Libraries/StellaOps.Policy.Tools/PolicyDslValidatorApp.cs new file mode 100644 index 000000000..434be1d9d --- /dev/null +++ b/src/__Libraries/StellaOps.Policy.Tools/PolicyDslValidatorApp.cs @@ -0,0 +1,33 @@ +using System.CommandLine; +using StellaOps.Policy; + +namespace StellaOps.Policy.Tools; + +public static class PolicyDslValidatorApp +{ + public static Task RunAsync(string[] args) + { + var runner = new PolicyValidationRunner(new PolicyValidationCli()); + return RunAsync(args, runner); + } + + public static async Task RunAsync(string[] args, IPolicyValidationRunner runner) + { + if (runner is null) + { + throw new ArgumentNullException(nameof(runner)); + } + + var root = PolicyDslValidatorCommand.Build(runner); + var parseResult = root.Parse(args, new ParserConfiguration()); + var invocationConfiguration = new InvocationConfiguration(); + + if (parseResult.Errors.Count > 0) + { + await parseResult.InvokeAsync(invocationConfiguration, CancellationToken.None); + return 64; // EX_USAGE + } + + return await parseResult.InvokeAsync(invocationConfiguration, CancellationToken.None); + } +} diff --git a/src/__Libraries/StellaOps.Policy.Tools/PolicyDslValidatorCommand.cs b/src/__Libraries/StellaOps.Policy.Tools/PolicyDslValidatorCommand.cs new file mode 100644 index 000000000..c1a82e987 --- /dev/null +++ b/src/__Libraries/StellaOps.Policy.Tools/PolicyDslValidatorCommand.cs @@ -0,0 +1,57 @@ +using System.CommandLine; +using StellaOps.Policy; + +namespace StellaOps.Policy.Tools; + +public static class PolicyDslValidatorCommand +{ + public static RootCommand Build(IPolicyValidationRunner runner, CancellationToken? cancellationTokenOverride = null) + { + var root = new RootCommand("Validate StellaOps policy DSL files."); + Configure(root, runner, cancellationTokenOverride); + return root; + } + + public static Command BuildCommand(IPolicyValidationRunner runner, CancellationToken? cancellationTokenOverride = null) + { + var command = new Command("policy-dsl-validate", "Validate StellaOps policy DSL files."); + Configure(command, runner, cancellationTokenOverride); + return command; + } + + private static void Configure(Command command, IPolicyValidationRunner runner, CancellationToken? cancellationTokenOverride) + { + var inputs = new Argument>("inputs") + { + Description = "Policy files, directories, or globs to validate.", + Arity = ArgumentArity.OneOrMore + }; + + var strict = new Option("--strict", new[] { "-s" }) + { + Description = "Treat warnings as errors." + }; + + var outputJson = new Option("--json", new[] { "-j" }) + { + Description = "Emit machine-readable JSON output." + }; + + command.Add(inputs); + command.Add(strict); + command.Add(outputJson); + + command.SetAction(async (parseResult, cancellationToken) => + { + var options = new PolicyValidationCliOptions + { + Inputs = parseResult.GetValue(inputs) ?? new List(), + Strict = parseResult.GetValue(strict), + OutputJson = parseResult.GetValue(outputJson), + }; + + var effectiveCancellationToken = cancellationTokenOverride ?? cancellationToken; + return await runner.RunAsync(options, effectiveCancellationToken); + }); + } +} diff --git a/src/__Libraries/StellaOps.Policy.Tools/PolicySchemaExporterApp.cs b/src/__Libraries/StellaOps.Policy.Tools/PolicySchemaExporterApp.cs new file mode 100644 index 000000000..308343bd5 --- /dev/null +++ b/src/__Libraries/StellaOps.Policy.Tools/PolicySchemaExporterApp.cs @@ -0,0 +1,22 @@ +using System.CommandLine; + +namespace StellaOps.Policy.Tools; + +public static class PolicySchemaExporterApp +{ + public static async Task RunAsync(string[] args) + { + var runner = new PolicySchemaExporterRunner(); + var root = PolicySchemaExporterCommand.Build(runner); + var parseResult = root.Parse(args, new ParserConfiguration()); + var invocationConfiguration = new InvocationConfiguration(); + + if (parseResult.Errors.Count > 0) + { + await parseResult.InvokeAsync(invocationConfiguration, CancellationToken.None); + return 64; // EX_USAGE + } + + return await parseResult.InvokeAsync(invocationConfiguration, CancellationToken.None); + } +} diff --git a/src/__Libraries/StellaOps.Policy.Tools/PolicySchemaExporterCommand.cs b/src/__Libraries/StellaOps.Policy.Tools/PolicySchemaExporterCommand.cs new file mode 100644 index 000000000..f07dcda24 --- /dev/null +++ b/src/__Libraries/StellaOps.Policy.Tools/PolicySchemaExporterCommand.cs @@ -0,0 +1,48 @@ +using System.CommandLine; + +namespace StellaOps.Policy.Tools; + +public static class PolicySchemaExporterCommand +{ + public static RootCommand Build(PolicySchemaExporterRunner runner, CancellationToken? cancellationTokenOverride = null) + { + var root = new RootCommand("Export policy schema JSON files."); + Configure(root, runner, cancellationTokenOverride); + return root; + } + + public static Command BuildCommand(PolicySchemaExporterRunner runner, CancellationToken? cancellationTokenOverride = null) + { + var command = new Command("policy-schema-export", "Export policy schema JSON files."); + Configure(command, runner, cancellationTokenOverride); + return command; + } + + private static void Configure(Command command, PolicySchemaExporterRunner runner, CancellationToken? cancellationTokenOverride) + { + var output = new Option("--output", new[] { "-o" }) + { + Description = "Output directory for schema files." + }; + + var repoRoot = new Option("--repo-root", new[] { "-r" }) + { + Description = "Repository root used to resolve default output path." + }; + + command.Add(output); + command.Add(repoRoot); + + command.SetAction((parseResult, cancellationToken) => + { + var options = new PolicySchemaExportOptions + { + OutputDirectory = parseResult.GetValue(output), + RepoRoot = parseResult.GetValue(repoRoot), + }; + + var effectiveCancellationToken = cancellationTokenOverride ?? cancellationToken; + return runner.RunAsync(options, effectiveCancellationToken); + }); + } +} diff --git a/src/__Libraries/StellaOps.Policy.Tools/PolicySchemaExporterRunner.cs b/src/__Libraries/StellaOps.Policy.Tools/PolicySchemaExporterRunner.cs new file mode 100644 index 000000000..cdd6e7be9 --- /dev/null +++ b/src/__Libraries/StellaOps.Policy.Tools/PolicySchemaExporterRunner.cs @@ -0,0 +1,190 @@ +using System.Collections.Immutable; +using NJsonSchema; +using NJsonSchema.Generation; +using Newtonsoft.Json; +using StellaOps.Scheduler.Models; + +namespace StellaOps.Policy.Tools; + +public sealed record PolicySchemaExportOptions +{ + public string? OutputDirectory { get; init; } + public string? RepoRoot { get; init; } +} + +public sealed record SchemaExportDefinition(string FileName, Type Type); + +public sealed class PolicySchemaExporterRunner +{ + public async Task RunAsync(PolicySchemaExportOptions options, CancellationToken cancellationToken) + { + if (options is null) + { + throw new ArgumentNullException(nameof(options)); + } + + var repoRoot = NormalizePath(options.RepoRoot) + ?? PolicySchemaExporterPaths.TryFindRepoRoot(Directory.GetCurrentDirectory()) + ?? PolicySchemaExporterPaths.TryFindRepoRoot(AppContext.BaseDirectory); + + string? outputDirectory; + if (!string.IsNullOrWhiteSpace(options.OutputDirectory)) + { + outputDirectory = PolicySchemaExporterPaths.ResolveOutputDirectory(options.OutputDirectory!, repoRoot); + } + else if (!string.IsNullOrWhiteSpace(repoRoot)) + { + outputDirectory = PolicySchemaExporterPaths.ResolveDefaultOutputDirectory(repoRoot); + } + else + { + Console.Error.WriteLine("Unable to resolve repo root. Provide --output or --repo-root."); + return 64; // EX_USAGE + } + + if (!TryEnsureOutputDirectory(outputDirectory, out var error)) + { + Console.Error.WriteLine(error); + return 73; // EX_CANTCREAT + } + + var generator = PolicySchemaExporterSchema.CreateGenerator(); + var exports = PolicySchemaExporterSchema.BuildExports(); + var schemas = PolicySchemaExporterSchema.GenerateSchemas(generator, exports); + + foreach (var export in exports) + { + if (!schemas.TryGetValue(export.FileName, out var json)) + { + continue; + } + + var outputPath = Path.Combine(outputDirectory, export.FileName); + await File.WriteAllTextAsync(outputPath, json + Environment.NewLine, cancellationToken); + Console.WriteLine($"Wrote {outputPath}"); + } + + return 0; + } + + private static string? NormalizePath(string? path) + { + if (string.IsNullOrWhiteSpace(path)) + { + return null; + } + + return Path.GetFullPath(path); + } + + private static bool TryEnsureOutputDirectory(string outputDirectory, out string? error) + { + error = null; + try + { + if (File.Exists(outputDirectory)) + { + error = $"Output path '{outputDirectory}' is a file, expected a directory."; + return false; + } + + Directory.CreateDirectory(outputDirectory); + return true; + } + catch (Exception ex) + { + error = $"Failed to create output directory '{outputDirectory}': {ex.Message}"; + return false; + } + } +} + +public static class PolicySchemaExporterSchema +{ + public static ImmutableArray BuildExports() + => ImmutableArray.Create( + new SchemaExportDefinition("policy-run-request.schema.json", typeof(PolicyRunRequest)), + new SchemaExportDefinition("policy-run-status.schema.json", typeof(PolicyRunStatus)), + new SchemaExportDefinition("policy-diff-summary.schema.json", typeof(PolicyDiffSummary)), + new SchemaExportDefinition("policy-explain-trace.schema.json", typeof(PolicyExplainTrace)) + ); + + public static JsonSchemaGenerator CreateGenerator() + { + var generatorSettings = new NJsonSchema.NewtonsoftJson.Generation.NewtonsoftJsonSchemaGeneratorSettings + { + SchemaType = SchemaType.JsonSchema, + DefaultReferenceTypeNullHandling = ReferenceTypeNullHandling.NotNull, + SerializerSettings = new JsonSerializerSettings + { + ContractResolver = new Newtonsoft.Json.Serialization.CamelCasePropertyNamesContractResolver(), + NullValueHandling = NullValueHandling.Ignore, + }, + }; + + return new JsonSchemaGenerator(generatorSettings); + } + + public static IReadOnlyDictionary GenerateSchemas(JsonSchemaGenerator generator, IEnumerable exports) + { + if (generator is null) + { + throw new ArgumentNullException(nameof(generator)); + } + + if (exports is null) + { + throw new ArgumentNullException(nameof(exports)); + } + + var results = new Dictionary(StringComparer.OrdinalIgnoreCase); + foreach (var export in exports) + { + var schema = generator.Generate(export.Type); + schema.Title = export.Type.Name; + schema.AllowAdditionalProperties = false; + results[export.FileName] = schema.ToJson(Formatting.Indented); + } + + return results; + } +} + +public static class PolicySchemaExporterPaths +{ + public static string? TryFindRepoRoot(string startDirectory) + { + if (string.IsNullOrWhiteSpace(startDirectory)) + { + return null; + } + + var current = new DirectoryInfo(Path.GetFullPath(startDirectory)); + while (current is not null) + { + var candidate = Path.Combine(current.FullName, "src", "Directory.Build.props"); + if (File.Exists(candidate)) + { + return current.FullName; + } + + current = current.Parent; + } + + return null; + } + + public static string ResolveDefaultOutputDirectory(string repoRoot) + => Path.GetFullPath(Path.Combine(repoRoot, "docs", "schemas")); + + public static string ResolveOutputDirectory(string outputPath, string? repoRoot) + { + if (Path.IsPathRooted(outputPath)) + { + return Path.GetFullPath(outputPath); + } + + var baseDirectory = !string.IsNullOrWhiteSpace(repoRoot) ? repoRoot : Directory.GetCurrentDirectory(); + return Path.GetFullPath(Path.Combine(baseDirectory, outputPath)); + } +} diff --git a/src/__Libraries/StellaOps.Policy.Tools/PolicySimulationSmokeApp.cs b/src/__Libraries/StellaOps.Policy.Tools/PolicySimulationSmokeApp.cs new file mode 100644 index 000000000..b1941b60e --- /dev/null +++ b/src/__Libraries/StellaOps.Policy.Tools/PolicySimulationSmokeApp.cs @@ -0,0 +1,22 @@ +using System.CommandLine; + +namespace StellaOps.Policy.Tools; + +public static class PolicySimulationSmokeApp +{ + public static async Task RunAsync(string[] args) + { + var runner = new PolicySimulationSmokeRunner(); + var root = PolicySimulationSmokeCommand.Build(runner); + var parseResult = root.Parse(args, new ParserConfiguration()); + var invocationConfiguration = new InvocationConfiguration(); + + if (parseResult.Errors.Count > 0) + { + await parseResult.InvokeAsync(invocationConfiguration, CancellationToken.None); + return 64; // EX_USAGE + } + + return await parseResult.InvokeAsync(invocationConfiguration, CancellationToken.None); + } +} diff --git a/src/__Libraries/StellaOps.Policy.Tools/PolicySimulationSmokeCommand.cs b/src/__Libraries/StellaOps.Policy.Tools/PolicySimulationSmokeCommand.cs new file mode 100644 index 000000000..e1a01421a --- /dev/null +++ b/src/__Libraries/StellaOps.Policy.Tools/PolicySimulationSmokeCommand.cs @@ -0,0 +1,75 @@ +using System.CommandLine; + +namespace StellaOps.Policy.Tools; + +public static class PolicySimulationSmokeCommand +{ + public static RootCommand Build(PolicySimulationSmokeRunner runner, CancellationToken? cancellationTokenOverride = null) + { + var root = new RootCommand("Run policy simulation smoke scenarios."); + Configure(root, runner, cancellationTokenOverride); + return root; + } + + public static Command BuildCommand(PolicySimulationSmokeRunner runner, CancellationToken? cancellationTokenOverride = null) + { + var command = new Command("policy-simulation-smoke", "Run policy simulation smoke scenarios."); + Configure(command, runner, cancellationTokenOverride); + return command; + } + + private static void Configure(Command command, PolicySimulationSmokeRunner runner, CancellationToken? cancellationTokenOverride) + { + var scenarioRoot = new Option("--scenario-root", new[] { "-r" }) + { + Description = "Path to the policy simulation scenarios." + }; + + var output = new Option("--output", new[] { "-o" }) + { + Description = "Directory for summary output." + }; + + var repoRoot = new Option("--repo-root", Array.Empty()) + { + Description = "Repository root for resolving relative paths." + }; + + var fixedTime = new Option("--fixed-time", Array.Empty()) + { + Description = "Fixed ISO-8601 timestamp for deterministic runs." + }; + + command.Add(scenarioRoot); + command.Add(output); + command.Add(repoRoot); + command.Add(fixedTime); + + command.SetAction(async (parseResult, cancellationToken) => + { + var fixedTimeValue = parseResult.GetValue(fixedTime); + DateTimeOffset? fixedTimeParsed = null; + if (!string.IsNullOrWhiteSpace(fixedTimeValue)) + { + if (!PolicySimulationSmokeParsing.TryParseFixedTime(fixedTimeValue!, out var parsed)) + { + Console.Error.WriteLine("Invalid --fixed-time value. Use ISO-8601 (e.g., 2025-01-02T03:04:05Z)."); + return 64; // EX_USAGE + } + + fixedTimeParsed = parsed; + } + + var options = new PolicySimulationSmokeOptions + { + ScenarioRoot = parseResult.GetValue(scenarioRoot) ?? "samples/policy/simulations", + OutputDirectory = parseResult.GetValue(output), + RepoRoot = parseResult.GetValue(repoRoot), + FixedTime = fixedTimeParsed, + }; + + var effectiveCancellationToken = cancellationTokenOverride ?? cancellationToken; + return await runner.RunAsync(options, effectiveCancellationToken); + }); + } +} diff --git a/src/__Libraries/StellaOps.Policy.Tools/PolicySimulationSmokeModels.cs b/src/__Libraries/StellaOps.Policy.Tools/PolicySimulationSmokeModels.cs new file mode 100644 index 000000000..35b5cd53a --- /dev/null +++ b/src/__Libraries/StellaOps.Policy.Tools/PolicySimulationSmokeModels.cs @@ -0,0 +1,74 @@ +using StellaOps.Policy; + +namespace StellaOps.Policy.Tools; + +public sealed record PolicySimulationScenario +{ + public string Name { get; init; } = "scenario"; + public string PolicyPath { get; init; } = string.Empty; + public List Findings { get; init; } = new(); + public List ExpectedDiffs { get; init; } = new(); + public List? Baseline { get; init; } +} + +public sealed record ScenarioFinding +{ + public string FindingId { get; init; } = string.Empty; + public string Severity { get; init; } = "Low"; + public string? Environment { get; init; } + public string? Source { get; init; } + public string? Vendor { get; init; } + public string? License { get; init; } + public string? Image { get; init; } + public string? Repository { get; init; } + public string? Package { get; init; } + public string? Purl { get; init; } + public string? Cve { get; init; } + public string? Path { get; init; } + public string? LayerDigest { get; init; } + public string[]? Tags { get; init; } +} + +public sealed record ScenarioExpectedDiff +{ + public string FindingId { get; init; } = string.Empty; + public string Status { get; init; } = "Pass"; +} + +public sealed record ScenarioBaseline +{ + public string FindingId { get; init; } = string.Empty; + public string Status { get; init; } = "Pass"; + public string? RuleName { get; init; } + public string? RuleAction { get; init; } + public string? Notes { get; init; } + public double Score { get; init; } + public string? ConfigVersion { get; init; } + public Dictionary? Inputs { get; init; } +} + +public sealed record ScenarioResult(string ScenarioName) +{ + public bool Success { get; init; } = true; + public int ChangedCount { get; init; } + public List Failures { get; } = new(); + public Dictionary ActualStatuses { get; } = new(StringComparer.OrdinalIgnoreCase); +} + +public sealed class NullPolicySnapshotRepository : IPolicySnapshotRepository +{ + public Task AddAsync(PolicySnapshot snapshot, CancellationToken cancellationToken = default) => Task.CompletedTask; + + public Task GetLatestAsync(CancellationToken cancellationToken = default) => Task.FromResult(null); + + public Task> ListAsync(int limit, CancellationToken cancellationToken = default) + => Task.FromResult>(Array.Empty()); +} + +public sealed class NullPolicyAuditRepository : IPolicyAuditRepository +{ + public Task AddAsync(PolicyAuditEntry entry, CancellationToken cancellationToken = default) => Task.CompletedTask; + + public Task> ListAsync(int limit, CancellationToken cancellationToken = default) + => Task.FromResult>(Array.Empty()); +} diff --git a/src/__Libraries/StellaOps.Policy.Tools/PolicySimulationSmokeRunner.cs b/src/__Libraries/StellaOps.Policy.Tools/PolicySimulationSmokeRunner.cs new file mode 100644 index 000000000..194e051e5 --- /dev/null +++ b/src/__Libraries/StellaOps.Policy.Tools/PolicySimulationSmokeRunner.cs @@ -0,0 +1,338 @@ +using System.Collections.Immutable; +using System.Globalization; +using System.Text.Json; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging.Abstractions; +using StellaOps.Policy; + +namespace StellaOps.Policy.Tools; + +public sealed record PolicySimulationSmokeOptions +{ + public string ScenarioRoot { get; init; } = "samples/policy/simulations"; + public string? OutputDirectory { get; init; } + public string? RepoRoot { get; init; } + public DateTimeOffset? FixedTime { get; init; } +} + +public sealed class PolicySimulationSmokeRunner +{ + private readonly ILoggerFactory _loggerFactory; + + public PolicySimulationSmokeRunner(ILoggerFactory? loggerFactory = null) + { + _loggerFactory = loggerFactory ?? NullLoggerFactory.Instance; + } + + public async Task RunAsync(PolicySimulationSmokeOptions options, CancellationToken cancellationToken) + { + if (options is null) + { + throw new ArgumentNullException(nameof(options)); + } + + var repoRoot = PolicySimulationSmokePaths.ResolveRepoRoot(options.RepoRoot); + var scenarioRoot = PolicySimulationSmokePaths.ResolveScenarioRoot(options.ScenarioRoot, repoRoot); + if (scenarioRoot is null) + { + Console.Error.WriteLine("Scenario root is relative; provide --repo-root or use an absolute path."); + return 64; // EX_USAGE + } + + if (!Directory.Exists(scenarioRoot)) + { + Console.Error.WriteLine($"Scenario root '{scenarioRoot}' does not exist."); + return 66; // EX_NOINPUT + } + + var scenarioFiles = Directory.GetFiles(scenarioRoot, "scenario.json", SearchOption.AllDirectories) + .OrderBy(static path => path, StringComparer.OrdinalIgnoreCase) + .ToArray(); + if (scenarioFiles.Length == 0) + { + Console.Error.WriteLine($"No scenario.json files found under '{scenarioRoot}'."); + return 0; + } + + var timeProvider = options.FixedTime.HasValue + ? new FixedTimeProvider(options.FixedTime.Value) + : TimeProvider.System; + + var snapshotStore = new PolicySnapshotStore( + new NullPolicySnapshotRepository(), + new NullPolicyAuditRepository(), + timeProvider, + _loggerFactory.CreateLogger()); + var previewService = new PolicyPreviewService(snapshotStore, _loggerFactory.CreateLogger()); + + var serializerOptions = new JsonSerializerOptions(JsonSerializerDefaults.Web) + { + PropertyNameCaseInsensitive = true, + ReadCommentHandling = JsonCommentHandling.Skip, + }; + + var summary = new List(); + var success = true; + + foreach (var scenarioFile in scenarioFiles) + { + cancellationToken.ThrowIfCancellationRequested(); + + var scenarioText = await File.ReadAllTextAsync(scenarioFile, cancellationToken); + var scenario = JsonSerializer.Deserialize(scenarioText, serializerOptions); + if (scenario is null) + { + Console.Error.WriteLine($"Failed to deserialize scenario '{scenarioFile}'."); + success = false; + continue; + } + + var policyPath = PolicySimulationSmokePaths.ResolvePolicyPath(scenario.PolicyPath, repoRoot); + if (policyPath is null) + { + Console.Error.WriteLine($"Policy path '{scenario.PolicyPath}' is relative; provide --repo-root or use an absolute path."); + success = false; + continue; + } + + if (!File.Exists(policyPath)) + { + Console.Error.WriteLine($"Policy file '{scenario.PolicyPath}' referenced by scenario '{scenario.Name}' does not exist."); + success = false; + continue; + } + + var policyContent = await File.ReadAllTextAsync(policyPath, cancellationToken); + var policyFormat = PolicySchema.DetectFormat(policyPath); + var findings = scenario.Findings.Select(ToPolicyFinding).ToImmutableArray(); + var baseline = scenario.Baseline?.Select(ToPolicyVerdict).ToImmutableArray() ?? ImmutableArray.Empty; + + var request = new PolicyPreviewRequest( + ImageDigest: $"sha256:simulation-{scenario.Name}", + Findings: findings, + BaselineVerdicts: baseline, + SnapshotOverride: null, + ProposedPolicy: new PolicySnapshotContent( + Content: policyContent, + Format: policyFormat, + Actor: "ci", + Source: "ci/simulation-smoke", + Description: $"CI simulation for scenario '{scenario.Name}'")); + + var response = await previewService.PreviewAsync(request, cancellationToken); + var scenarioResult = PolicySimulationSmokeEvaluator.EvaluateScenario(scenario, response); + summary.Add(scenarioResult); + + if (!scenarioResult.Success) + { + success = false; + } + } + + if (options.OutputDirectory is not null) + { + var outputDirectory = PolicySimulationSmokePaths.ResolveOutputDirectory(options.OutputDirectory, repoRoot); + if (outputDirectory is null) + { + Console.Error.WriteLine("Output path is relative; provide --repo-root or use an absolute path."); + return 64; // EX_USAGE + } + + Directory.CreateDirectory(outputDirectory); + var summaryPath = Path.Combine(outputDirectory, "policy-simulation-summary.json"); + var summaryJson = JsonSerializer.Serialize(summary, new JsonSerializerOptions { WriteIndented = true }); + await File.WriteAllTextAsync(summaryPath, summaryJson, cancellationToken); + } + + return success ? 0 : 1; + } + + private static PolicyFinding ToPolicyFinding(ScenarioFinding finding) + { + var tags = finding.Tags is null ? ImmutableArray.Empty : ImmutableArray.CreateRange(finding.Tags); + var severity = Enum.Parse(finding.Severity, ignoreCase: true); + return new PolicyFinding( + finding.FindingId, + severity, + finding.Environment, + finding.Source, + finding.Vendor, + finding.License, + finding.Image, + finding.Repository, + finding.Package, + finding.Purl, + finding.Cve, + finding.Path, + finding.LayerDigest, + tags); + } + + private static PolicyVerdict ToPolicyVerdict(ScenarioBaseline baseline) + { + var status = Enum.Parse(baseline.Status, ignoreCase: true); + var inputs = baseline.Inputs?.ToImmutableDictionary(StringComparer.OrdinalIgnoreCase) ?? ImmutableDictionary.Empty; + return new PolicyVerdict( + baseline.FindingId, + status, + RuleName: baseline.RuleName, + RuleAction: baseline.RuleAction, + Notes: baseline.Notes, + Score: baseline.Score, + ConfigVersion: baseline.ConfigVersion ?? PolicyScoringConfig.Default.Version, + Inputs: inputs, + QuietedBy: null, + Quiet: false, + UnknownConfidence: null, + ConfidenceBand: null, + UnknownAgeDays: null, + SourceTrust: null, + Reachability: null); + } +} + +public static class PolicySimulationSmokeEvaluator +{ + public static ScenarioResult EvaluateScenario(PolicySimulationScenario scenario, PolicyPreviewResponse response) + { + var result = new ScenarioResult(scenario.Name); + if (!response.Success) + { + result.Failures.Add("Preview failed."); + return result with { Success = false, ChangedCount = response.ChangedCount }; + } + + var diffs = response.Diffs.ToDictionary(diff => diff.Projected.FindingId, StringComparer.OrdinalIgnoreCase); + foreach (var expected in scenario.ExpectedDiffs) + { + if (!diffs.TryGetValue(expected.FindingId, out var diff)) + { + result.Failures.Add($"Expected finding '{expected.FindingId}' missing from diff."); + continue; + } + + var projectedStatus = diff.Projected.Status.ToString(); + result.ActualStatuses[expected.FindingId] = projectedStatus; + if (!string.Equals(projectedStatus, expected.Status, StringComparison.OrdinalIgnoreCase)) + { + result.Failures.Add($"Finding '{expected.FindingId}' expected status '{expected.Status}' but was '{projectedStatus}'."); + } + } + + foreach (var diff in diffs.Values) + { + if (!result.ActualStatuses.ContainsKey(diff.Projected.FindingId)) + { + result.ActualStatuses[diff.Projected.FindingId] = diff.Projected.Status.ToString(); + } + } + + var success = result.Failures.Count == 0; + return result with + { + Success = success, + ChangedCount = response.ChangedCount + }; + } +} + +public static class PolicySimulationSmokePaths +{ + public static string? ResolveRepoRoot(string? explicitRepoRoot) + { + if (!string.IsNullOrWhiteSpace(explicitRepoRoot)) + { + return Path.GetFullPath(explicitRepoRoot); + } + + return TryFindRepoRoot(Directory.GetCurrentDirectory()) + ?? TryFindRepoRoot(AppContext.BaseDirectory); + } + + public static string? ResolveScenarioRoot(string scenarioRoot, string? repoRoot) + { + if (Path.IsPathRooted(scenarioRoot)) + { + return Path.GetFullPath(scenarioRoot); + } + + if (string.IsNullOrWhiteSpace(repoRoot)) + { + return null; + } + + return Path.GetFullPath(Path.Combine(repoRoot, scenarioRoot)); + } + + public static string? ResolvePolicyPath(string policyPath, string? repoRoot) + { + if (Path.IsPathRooted(policyPath)) + { + return Path.GetFullPath(policyPath); + } + + if (string.IsNullOrWhiteSpace(repoRoot)) + { + return null; + } + + return Path.GetFullPath(Path.Combine(repoRoot, policyPath)); + } + + public static string? ResolveOutputDirectory(string outputDirectory, string? repoRoot) + { + if (Path.IsPathRooted(outputDirectory)) + { + return Path.GetFullPath(outputDirectory); + } + + var baseDirectory = !string.IsNullOrWhiteSpace(repoRoot) ? repoRoot : Directory.GetCurrentDirectory(); + return Path.GetFullPath(Path.Combine(baseDirectory, outputDirectory)); + } + + public static string? TryFindRepoRoot(string startDirectory) + { + if (string.IsNullOrWhiteSpace(startDirectory)) + { + return null; + } + + var current = new DirectoryInfo(Path.GetFullPath(startDirectory)); + while (current is not null) + { + var candidate = Path.Combine(current.FullName, "src", "Directory.Build.props"); + if (File.Exists(candidate)) + { + return current.FullName; + } + + current = current.Parent; + } + + return null; + } +} + +public static class PolicySimulationSmokeParsing +{ + public static bool TryParseFixedTime(string value, out DateTimeOffset fixedTime) + => DateTimeOffset.TryParse( + value, + CultureInfo.InvariantCulture, + DateTimeStyles.AssumeUniversal | DateTimeStyles.AdjustToUniversal, + out fixedTime); +} + +public sealed class FixedTimeProvider : TimeProvider +{ + private readonly DateTimeOffset _fixedTime; + + public FixedTimeProvider(DateTimeOffset fixedTime) + { + _fixedTime = fixedTime.ToUniversalTime(); + } + + public override DateTimeOffset GetUtcNow() => _fixedTime; + + public override TimeZoneInfo LocalTimeZone => TimeZoneInfo.Utc; +} diff --git a/src/__Libraries/StellaOps.Policy.Tools/PolicyValidationRunner.cs b/src/__Libraries/StellaOps.Policy.Tools/PolicyValidationRunner.cs new file mode 100644 index 000000000..179afbe1a --- /dev/null +++ b/src/__Libraries/StellaOps.Policy.Tools/PolicyValidationRunner.cs @@ -0,0 +1,21 @@ +using StellaOps.Policy; + +namespace StellaOps.Policy.Tools; + +public interface IPolicyValidationRunner +{ + Task RunAsync(PolicyValidationCliOptions options, CancellationToken cancellationToken); +} + +public sealed class PolicyValidationRunner : IPolicyValidationRunner +{ + private readonly PolicyValidationCli _cli; + + public PolicyValidationRunner(PolicyValidationCli cli) + { + _cli = cli ?? throw new ArgumentNullException(nameof(cli)); + } + + public Task RunAsync(PolicyValidationCliOptions options, CancellationToken cancellationToken) + => _cli.RunAsync(options, cancellationToken); +} diff --git a/src/__Libraries/StellaOps.Policy.Tools/StellaOps.Policy.Tools.csproj b/src/__Libraries/StellaOps.Policy.Tools/StellaOps.Policy.Tools.csproj new file mode 100644 index 000000000..9aa8e5b50 --- /dev/null +++ b/src/__Libraries/StellaOps.Policy.Tools/StellaOps.Policy.Tools.csproj @@ -0,0 +1,23 @@ + + + net10.0 + enable + enable + preview + + + + + + + + + + + + + + + + +