From 5722a48b2bc8a10fc6453ac84a0ab4b4618c4175 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Sun, 8 Mar 2026 01:02:33 +0000
Subject: [PATCH 1/5] Initial plan
From 3cddd9bfca851f198c742a287006fcdab1de4685 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Sun, 8 Mar 2026 01:08:00 +0000
Subject: [PATCH 2/5] Replace numeric requirement IDs with descriptive string
IDs
Co-authored-by: Malcolmnixon <1863707+Malcolmnixon@users.noreply.github.com>
---
requirements.yaml | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/requirements.yaml b/requirements.yaml
index a5a4db7..ffddb5c 100644
--- a/requirements.yaml
+++ b/requirements.yaml
@@ -16,7 +16,7 @@ sections:
sections:
- title: Library API
requirements:
- - id: CACH-LIB-001
+ - id: CACH-Lib-EnsureCached
title: The library shall provide a method to ensure a NuGet package is cached locally on the PC.
justification: |
Provides the core caching functionality of the library, allowing callers to ensure
@@ -26,7 +26,7 @@ sections:
- title: Platform Support
requirements:
- - id: CACH-PLT-001
+ - id: CACH-Platform-Windows
title: The library shall build and run on Windows platforms.
justification: |
DEMA Consulting libraries must support Windows as a major development platform.
@@ -34,7 +34,7 @@ sections:
# Tests link to "windows" to ensure results come from Windows platform
- "windows@NuGetCache_EnsureCachedAsync_ReturnsPackageFolder"
- - id: CACH-PLT-002
+ - id: CACH-Platform-Linux
title: The library shall build and run on Linux platforms.
justification: |
DEMA Consulting libraries must support Linux for CI/CD and containerized environments.
@@ -42,7 +42,7 @@ sections:
# Tests link to "ubuntu" to ensure results come from Linux platform
- "ubuntu@NuGetCache_EnsureCachedAsync_ReturnsPackageFolder"
- - id: CACH-PLT-007
+ - id: CACH-Platform-MacOS
title: The library shall build and run on macOS platforms.
justification: |
DEMA Consulting libraries must support macOS for developers using Apple platforms.
@@ -50,28 +50,28 @@ sections:
# Tests link to "macos" to ensure results come from macOS platform
- "macos@NuGetCache_EnsureCachedAsync_ReturnsPackageFolder"
- - id: CACH-PLT-003
+ - id: CACH-Platform-Net8
title: The library shall support .NET 8 runtime.
justification: |
.NET 8 is an LTS release providing long-term stability for enterprise users.
tests:
- "net8.0@NuGetCache_EnsureCachedAsync_ReturnsPackageFolder"
- - id: CACH-PLT-004
+ - id: CACH-Platform-Net9
title: The library shall support .NET 9 runtime.
justification: |
.NET 9 support enables users to leverage the latest .NET features.
tests:
- "net9.0@NuGetCache_EnsureCachedAsync_ReturnsPackageFolder"
- - id: CACH-PLT-005
+ - id: CACH-Platform-Net10
title: The library shall support .NET 10 runtime.
justification: |
.NET 10 support ensures the library remains compatible with the latest .NET ecosystem.
tests:
- "net10.0@NuGetCache_EnsureCachedAsync_ReturnsPackageFolder"
- - id: CACH-PLT-006
+ - id: CACH-Platform-NetStd20
title: The library shall support .NET Standard 2.0, verified on .NET Framework 4.8.1 on Windows.
justification: |
.NET Standard 2.0 support ensures the library can be consumed by projects targeting
From a80c6f0ba0c9846329425127e4638a772a03ebfd Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Sun, 8 Mar 2026 01:11:27 +0000
Subject: [PATCH 3/5] Rename requirement IDs: CACH- to Caching-, Platform to
PLT
Co-authored-by: Malcolmnixon <1863707+Malcolmnixon@users.noreply.github.com>
---
requirements.yaml | 28 +++++++++----------
.../NuGetCacheTests.cs | 2 +-
2 files changed, 15 insertions(+), 15 deletions(-)
diff --git a/requirements.yaml b/requirements.yaml
index ffddb5c..07cefb0 100644
--- a/requirements.yaml
+++ b/requirements.yaml
@@ -16,7 +16,7 @@ sections:
sections:
- title: Library API
requirements:
- - id: CACH-Lib-EnsureCached
+ - id: Caching-Lib-EnsureCached
title: The library shall provide a method to ensure a NuGet package is cached locally on the PC.
justification: |
Provides the core caching functionality of the library, allowing callers to ensure
@@ -26,7 +26,7 @@ sections:
- title: Platform Support
requirements:
- - id: CACH-Platform-Windows
+ - id: Caching-PLT-Windows
title: The library shall build and run on Windows platforms.
justification: |
DEMA Consulting libraries must support Windows as a major development platform.
@@ -34,7 +34,7 @@ sections:
# Tests link to "windows" to ensure results come from Windows platform
- "windows@NuGetCache_EnsureCachedAsync_ReturnsPackageFolder"
- - id: CACH-Platform-Linux
+ - id: Caching-PLT-Linux
title: The library shall build and run on Linux platforms.
justification: |
DEMA Consulting libraries must support Linux for CI/CD and containerized environments.
@@ -42,7 +42,7 @@ sections:
# Tests link to "ubuntu" to ensure results come from Linux platform
- "ubuntu@NuGetCache_EnsureCachedAsync_ReturnsPackageFolder"
- - id: CACH-Platform-MacOS
+ - id: Caching-PLT-MacOS
title: The library shall build and run on macOS platforms.
justification: |
DEMA Consulting libraries must support macOS for developers using Apple platforms.
@@ -50,28 +50,28 @@ sections:
# Tests link to "macos" to ensure results come from macOS platform
- "macos@NuGetCache_EnsureCachedAsync_ReturnsPackageFolder"
- - id: CACH-Platform-Net8
+ - id: Caching-PLT-Net8
title: The library shall support .NET 8 runtime.
justification: |
.NET 8 is an LTS release providing long-term stability for enterprise users.
tests:
- "net8.0@NuGetCache_EnsureCachedAsync_ReturnsPackageFolder"
- - id: CACH-Platform-Net9
+ - id: Caching-PLT-Net9
title: The library shall support .NET 9 runtime.
justification: |
.NET 9 support enables users to leverage the latest .NET features.
tests:
- "net9.0@NuGetCache_EnsureCachedAsync_ReturnsPackageFolder"
- - id: CACH-Platform-Net10
+ - id: Caching-PLT-Net10
title: The library shall support .NET 10 runtime.
justification: |
.NET 10 support ensures the library remains compatible with the latest .NET ecosystem.
tests:
- "net10.0@NuGetCache_EnsureCachedAsync_ReturnsPackageFolder"
- - id: CACH-Platform-NetStd20
+ - id: Caching-PLT-NetStd20
title: The library shall support .NET Standard 2.0, verified on .NET Framework 4.8.1 on Windows.
justification: |
.NET Standard 2.0 support ensures the library can be consumed by projects targeting
@@ -82,7 +82,7 @@ sections:
- title: OTS Software
requirements:
- - id: CACH-OTS-MSTest
+ - id: Caching-OTS-MSTest
title: MSTest shall execute unit tests and report results.
justification: |
MSTest (MSTest.TestFramework and MSTest.TestAdapter) is the unit-testing framework used
@@ -93,7 +93,7 @@ sections:
tests:
- NuGetCache_EnsureCachedAsync_ReturnsPackageFolder
- - id: CACH-OTS-ReqStream
+ - id: Caching-OTS-ReqStream
title: ReqStream shall enforce that every requirement is linked to passing test evidence.
justification: |
DemaConsulting.ReqStream processes requirements.yaml and the TRX test-result files to
@@ -105,7 +105,7 @@ sections:
tests:
- ReqStream_EnforcementMode
- - id: CACH-OTS-BuildMark
+ - id: Caching-OTS-BuildMark
title: BuildMark shall generate build-notes documentation from GitHub Actions metadata.
justification: |
DemaConsulting.BuildMark queries the GitHub API to capture workflow run details and
@@ -116,7 +116,7 @@ sections:
tests:
- BuildMark_MarkdownReportGeneration
- - id: CACH-OTS-VersionMark
+ - id: Caching-OTS-VersionMark
title: VersionMark shall publish captured tool-version information.
justification: |
DemaConsulting.VersionMark reads version metadata for each dotnet tool used in the
@@ -128,7 +128,7 @@ sections:
- VersionMark_CapturesVersions
- VersionMark_GeneratesMarkdownReport
- - id: CACH-OTS-SarifMark
+ - id: Caching-OTS-SarifMark
title: SarifMark shall convert CodeQL SARIF results into a markdown report.
justification: |
DemaConsulting.SarifMark reads the SARIF output produced by CodeQL code scanning and
@@ -140,7 +140,7 @@ sections:
- SarifMark_SarifReading
- SarifMark_MarkdownReportGeneration
- - id: CACH-OTS-SonarMark
+ - id: Caching-OTS-SonarMark
title: SonarMark shall generate a SonarCloud quality report.
justification: |
DemaConsulting.SonarMark retrieves quality-gate and metrics data from SonarCloud and
diff --git a/test/DemaConsulting.NuGet.Caching.Tests/NuGetCacheTests.cs b/test/DemaConsulting.NuGet.Caching.Tests/NuGetCacheTests.cs
index 5f46cfd..1b5abbe 100644
--- a/test/DemaConsulting.NuGet.Caching.Tests/NuGetCacheTests.cs
+++ b/test/DemaConsulting.NuGet.Caching.Tests/NuGetCacheTests.cs
@@ -36,7 +36,7 @@ public class NuGetCacheTests
/// package folder after downloading a known small package from nuget.org.
///
///
- /// This test proves CACH-REQ-007: the library can ensure a NuGet package is cached locally.
+ /// This test proves Caching-Lib-EnsureCached: the library can ensure a NuGet package is cached locally.
///
[TestMethod]
public async Task NuGetCache_EnsureCachedAsync_ReturnsPackageFolder()
From ca29acaf317de4553a70dd1ad36018013074ef16 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Sun, 8 Mar 2026 01:29:01 +0000
Subject: [PATCH 4/5] Fix race condition in EnsureCachedAsync: check
.nupkg.metadata instead of Directory.Exists
Co-authored-by: Malcolmnixon <1863707+Malcolmnixon@users.noreply.github.com>
---
src/DemaConsulting.NuGet.Caching/NuGetCache.cs | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/src/DemaConsulting.NuGet.Caching/NuGetCache.cs b/src/DemaConsulting.NuGet.Caching/NuGetCache.cs
index 74157fe..d847798 100644
--- a/src/DemaConsulting.NuGet.Caching/NuGetCache.cs
+++ b/src/DemaConsulting.NuGet.Caching/NuGetCache.cs
@@ -70,8 +70,11 @@ public static async Task EnsureCachedAsync(
// {globalPackagesFolder}/{packageId.lower}/{version.lower}/
var packagePath = GetPackagePath(globalPackagesFolder, packageId, version.ToLowerInvariant());
- // Return immediately when the package is already present - the common hot path
- if (Directory.Exists(packagePath))
+ // Return immediately when the package is fully installed - the common hot path.
+ // Checking for the .nupkg.metadata file (written by NuGet as the last extraction step)
+ // rather than the directory avoids a race condition where concurrent callers see the
+ // directory before extraction is complete and return a partially-populated path.
+ if (File.Exists(Path.Combine(packagePath, ".nupkg.metadata")))
{
return packagePath;
}
From 3aec9d42d010ffe55a34e19a7ba7286677e20ac0 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Sun, 8 Mar 2026 01:32:23 +0000
Subject: [PATCH 5/5] Use PathHelpers.SafePathCombine for .nupkg.metadata check
Co-authored-by: Malcolmnixon <1863707+Malcolmnixon@users.noreply.github.com>
---
src/DemaConsulting.NuGet.Caching/NuGetCache.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/DemaConsulting.NuGet.Caching/NuGetCache.cs b/src/DemaConsulting.NuGet.Caching/NuGetCache.cs
index d847798..f1af0cc 100644
--- a/src/DemaConsulting.NuGet.Caching/NuGetCache.cs
+++ b/src/DemaConsulting.NuGet.Caching/NuGetCache.cs
@@ -74,7 +74,7 @@ public static async Task EnsureCachedAsync(
// Checking for the .nupkg.metadata file (written by NuGet as the last extraction step)
// rather than the directory avoids a race condition where concurrent callers see the
// directory before extraction is complete and return a partially-populated path.
- if (File.Exists(Path.Combine(packagePath, ".nupkg.metadata")))
+ if (File.Exists(PathHelpers.SafePathCombine(packagePath, ".nupkg.metadata")))
{
return packagePath;
}