namespace NATS.Server.TestUtilities.Parity; public sealed record DriftRow(string Feature, string DifferencesStatus, string EvidenceStatus, string Reason); public sealed class JetStreamParityTruthMatrixReport { public JetStreamParityTruthMatrixReport(IReadOnlyList driftRows, IReadOnlyList contradictions) { DriftRows = driftRows; Contradictions = contradictions; } public IReadOnlyList DriftRows { get; } public IReadOnlyList Contradictions { get; } } public static class JetStreamParityTruthMatrix { public static JetStreamParityTruthMatrixReport Load(string differencesRelativePath, string mapRelativePath) { var repositoryRoot = Path.GetFullPath(Path.Combine(AppContext.BaseDirectory, "..", "..", "..", "..", "..")); var differencesPath = Path.Combine(repositoryRoot, differencesRelativePath); var mapPath = Path.Combine(repositoryRoot, mapRelativePath); File.Exists(differencesPath).ShouldBeTrue(); File.Exists(mapPath).ShouldBeTrue(); var differences = ParityRowInspector.Load(differencesRelativePath).Rows; var matrixRows = ParseTruthMatrix(mapPath); var drift = new List(); if (matrixRows.Count == 0) { drift.Add(new DriftRow( "JetStream Truth Matrix", "missing", "missing", "docs/plans/2026-02-23-jetstream-remaining-parity-map.md must include a populated 'JetStream Truth Matrix' table.")); } foreach (var row in matrixRows) { var differencesRow = differences.FirstOrDefault(r => string.Equals(r.Feature, row.DifferencesFeature, StringComparison.OrdinalIgnoreCase)); if (differencesRow is null) { drift.Add(new DriftRow( row.Feature, "missing", row.EvidenceStatus, $"Differences row '{row.DifferencesFeature}' was not found in differences.md.")); continue; } if (!string.Equals(differencesRow.DotNetStatus, "Y", StringComparison.OrdinalIgnoreCase)) { drift.Add(new DriftRow( row.Feature, differencesRow.DotNetStatus, row.EvidenceStatus, "Differences status must be Y for a verified truth-matrix row.")); } if (!string.Equals(row.EvidenceStatus, "verified", StringComparison.OrdinalIgnoreCase)) { drift.Add(new DriftRow( row.Feature, differencesRow.DotNetStatus, row.EvidenceStatus, "Evidence status must be 'verified'.")); } if (string.IsNullOrWhiteSpace(row.TestEvidence) || row.TestEvidence == "-") { drift.Add(new DriftRow( row.Feature, differencesRow.DotNetStatus, row.EvidenceStatus, "Test evidence must be provided for every truth-matrix row.")); } } var contradictions = ParseRemainingExplicitDeltaContradictions(differencesPath, matrixRows); return new JetStreamParityTruthMatrixReport(drift, contradictions); } private static List ParseTruthMatrix(string mapPath) { var rows = new List(); var inTruthMatrix = false; foreach (var rawLine in File.ReadLines(mapPath)) { var line = rawLine.Trim(); if (line.StartsWith("## ", StringComparison.Ordinal)) { inTruthMatrix = string.Equals( line, "## JetStream Truth Matrix", StringComparison.OrdinalIgnoreCase); continue; } if (!inTruthMatrix || !line.StartsWith("|", StringComparison.Ordinal) || line.Contains("---", StringComparison.Ordinal)) continue; var cells = line.Trim('|').Split('|').Select(c => c.Trim()).ToArray(); if (cells.Length < 4 || string.Equals(cells[0], "Feature", StringComparison.OrdinalIgnoreCase)) continue; rows.Add(new TruthMatrixRow( cells[0], cells[1], cells[2], cells[3])); } return rows; } private static List ParseRemainingExplicitDeltaContradictions( string differencesPath, IReadOnlyList matrixRows) { var contradictions = new List(); var inExplicitDeltas = false; var negativeMarkers = new[] { "unimplemented", "still `n`", "still n", "remains", "incomplete", }; foreach (var rawLine in File.ReadLines(differencesPath)) { var line = rawLine.Trim(); if (line.StartsWith("### ", StringComparison.Ordinal)) { inExplicitDeltas = string.Equals( line, "### Remaining Explicit Deltas", StringComparison.OrdinalIgnoreCase); continue; } if (inExplicitDeltas && line.StartsWith("## ", StringComparison.Ordinal)) { inExplicitDeltas = false; continue; } if (!inExplicitDeltas || !line.StartsWith("- ", StringComparison.Ordinal)) continue; var normalizedLine = line.ToLowerInvariant(); if (!negativeMarkers.Any(marker => normalizedLine.Contains(marker, StringComparison.Ordinal))) continue; foreach (var row in matrixRows.Where(r => string.Equals(r.EvidenceStatus, "verified", StringComparison.OrdinalIgnoreCase))) { if (MentionsFeature(normalizedLine, row)) { contradictions.Add($"{row.Feature}: {line[2..].Trim()}"); break; } } } return contradictions; } private static bool MentionsFeature(string normalizedLine, TruthMatrixRow row) { var tokens = Tokenize(row.Feature) .Concat(Tokenize(row.DifferencesFeature)) .Where(t => t.Length >= 4) .Distinct(StringComparer.Ordinal) .ToArray(); if (tokens.Length == 0) return false; var matches = tokens.Count(t => normalizedLine.Contains(t, StringComparison.Ordinal)); return matches >= 2; } private static IEnumerable Tokenize(string value) { var chars = value.ToLowerInvariant() .Select(c => char.IsLetterOrDigit(c) ? c : ' ') .ToArray(); return new string(chars) .Split(' ', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries); } private sealed record TruthMatrixRow( string Feature, string DifferencesFeature, string EvidenceStatus, string TestEvidence); }