Summary
ConcurrentDictionary.AddOrUpdate executes its updateValueFactory delegate outside the dictionary's internal locks and may invoke it multiple times under contention. Concurrent calls to SubmitReviewAsync with the same evidence ID therefore mutate an EvidenceRecord field-by-field without synchronization, resulting in a record with a mixed review state.
Affected file
src/BusinessApplications/NISTCompliance/Services/NISTComplianceService.cs — line 233
Required fix
Replace the unsafe in-place mutation with an immutable update (create a new record value) or use a proper lock/Interlocked mechanism:
_evidenceRecords.AddOrUpdate(
evidenceId,
_ => CreateNewRecord(review),
(_, existing) => existing with { ReviewedBy = review.ReviewedBy, Status = review.Status, ReviewedAt = review.ReviewedAt }
);
References