docs(src): fix CommentChecker findings across src/ — 1,032 → 5 (all false positives)

Comment/XML-doc changes only, no code logic:
- strip project-tracking references (WP*, P*-*, row-NN, #NN, Task N) from
  comments, keeping the explanatory rationale
- add missing summaries, <param>, <returns>, <typeparam> and <inheritdoc/>
- replace misused <inheritdoc/> with real docs; where <inheritdoc/> was
  combined with useful remarks, move the rationale into // comments
- drop stale replicationActor <param> on DeploymentManagerActor ctor

Remaining 5 are false positives (CWE-1236 x2, failures-1, year-0001, M365).
Build 0 errors / 0 warnings.
This commit is contained in:
Joseph Doherty
2026-10-07 14:12:25 -04:00
parent 3a217b9484
commit 0ffd4bdbea
217 changed files with 1224 additions and 695 deletions
@@ -227,7 +227,7 @@ public class AuditLogIngestActor : ReceiveActor
projected.Add(AuditRowProjection.WithIngestedAtUtc(filtered, nowUtc));
}
// ONE set-based statement for the whole packet (WP2.2) instead of one
// ONE set-based statement for the whole packet instead of one
// IF NOT EXISTS … INSERT round trip per event. A telemetry packet of 200
// rows used to cost 200 sequential round trips on the central singleton's
// dispatcher; it now costs two. Idempotency is unchanged — duplicates
@@ -356,7 +356,7 @@ public class AuditLogIngestActor : ReceiveActor
var strategy = dbContext.Database.CreateExecutionStrategy();
// Fast path (WP2.2): the WHOLE packet in ONE transaction — one
// Fast path: the WHOLE packet in ONE transaction — one
// set-based audit insert plus one single-statement upsert per entry.
// The predecessor opened a transaction PER entry and issued three
// statements inside it (IF NOT EXISTS insert, then the two-statement
@@ -18,8 +18,8 @@ namespace ZB.MOM.WW.ScadaBridge.AuditLog.Central;
/// than <c>DateTime.UtcNow - RetentionDays</c>.</item>
/// <item>For each eligible boundary, calls
/// <see cref="IAuditLogRepository.SwitchOutPartitionAsync"/>, a
/// metadata-only staging-table switch (WP2.2 removed the index
/// drop/rebuild that used to bracket it).</item>
/// metadata-only staging-table switch (no index
/// drop/rebuild brackets it).</item>
/// <item>Publishes <see cref="AuditLogPurgedEvent"/> on the actor-system
/// EventStream so the central health collector + ops surfaces
/// can subscribe without coupling to this actor.</item>
@@ -11,8 +11,8 @@ namespace ZB.MOM.WW.ScadaBridge.AuditLog.Central;
/// <remarks>
/// <para>
/// The purge actor is a daily-cadence singleton, not a hot-loop. The
/// partition switch itself is metadata-only (since WP2.2's
/// <c>AlignAuditLogEventIdUniqueness</c> it no longer drops and rebuilds a
/// partition switch itself is metadata-only (since the
/// <c>AlignAuditLogEventIdUniqueness</c> migration it no longer drops and rebuilds a
/// non-aligned unique index around it), but it still takes schema-modification
/// locks and competes with ingest for the same table. Lower this only when an
/// operator can prove they need sub-daily purge granularity.
@@ -28,6 +28,9 @@ public sealed class GrpcPullTraceEventsClient : IPullTraceEventsClient
private readonly ILogger<GrpcPullTraceEventsClient> _logger;
/// <summary>Creates the client over the given site enumerator and unary-call invoker.</summary>
/// <param name="sites">Enumerates the sites and their gRPC endpoints.</param>
/// <param name="invoker">Issues the unary <c>PullTraceEvents</c> call.</param>
/// <param name="logger">Logger for pull diagnostics.</param>
public GrpcPullTraceEventsClient(
ISiteEnumerator sites,
IPullTraceEventsInvoker invoker,
@@ -152,6 +155,11 @@ public sealed class GrpcPullTraceEventsClient : IPullTraceEventsClient
public interface IPullTraceEventsInvoker
{
/// <summary>Issues the RPC against <paramref name="endpoint"/> with the site's preshared key.</summary>
/// <param name="siteId">The site the call targets.</param>
/// <param name="endpoint">The site node gRPC endpoint to call.</param>
/// <param name="request">The pull request.</param>
/// <param name="ct">Token to cancel the call.</param>
/// <returns>The site's trace-event response.</returns>
Task<PullTraceEventsResponse> InvokeAsync(
string siteId, string endpoint, PullTraceEventsRequest request, CancellationToken ct);
}
@@ -169,6 +177,8 @@ public sealed class GrpcPullTraceEventsInvoker : GrpcPullTraceEventsClient.IPull
private readonly ISitePskProvider? _pskProvider;
/// <summary>Creates the invoker with the given options and optional per-site PSK provider.</summary>
/// <param name="options">Communication options supplying keepalive settings.</param>
/// <param name="pskProvider">Optional provider of per-site preshared keys.</param>
public GrpcPullTraceEventsInvoker(CommunicationOptions options, ISitePskProvider? pskProvider)
{
_options = options ?? throw new ArgumentNullException(nameof(options));
@@ -212,7 +222,7 @@ public sealed class GrpcPullTraceEventsInvoker : GrpcPullTraceEventsClient.IPull
},
}.WithMessageLimits().WithSiteCredentials(_pskProvider, siteId));
/// <inheritdoc />
/// <summary>Disposes every cached gRPC channel.</summary>
public void Dispose()
{
foreach (var channel in _channels.Values)
@@ -521,6 +521,8 @@ public class SiteAuditReconciliationActor : ReceiveActor
/// lost rows get distinct synthetic ids.
/// </para>
/// </remarks>
/// <param name="lostEventId">The event id of the lost row being abandoned.</param>
/// <returns>A deterministic synthetic GUID for the abandonment row.</returns>
internal static Guid DeriveAbandonmentEventId(Guid lostEventId)
{
Span<byte> input = stackalloc byte[32];
@@ -150,7 +150,7 @@ public sealed class ScadaBridgeAuditRedactor : IAuditRedactor, IDisposable
}
}
/// <inheritdoc />
/// <summary>Disposes the options-change registration, if any.</summary>
public void Dispose() => _optionsReload?.Dispose();
/// <summary>
@@ -174,7 +174,7 @@ public class SqliteAuditWriter : IAuditWriter, ISiteAuditQueue, IAsyncDisposable
pragmaCmd.ExecuteNonQuery();
}
// synchronous=NORMAL (arch-review remediation WP1.2): SQLite's FULL default
// synchronous=NORMAL: SQLite's FULL default
// fsyncs on every transaction commit, which is the dominant cost of the
// per-event write path this same change coalesces via FlushIntervalMs — FULL
// would still fsync once per FLUSH even after that fix. NORMAL fsyncs at
@@ -346,8 +346,8 @@ public class SqliteAuditWriter : IAuditWriter, ISiteAuditQueue, IAsyncDisposable
// burst of concurrent enqueues. Once the immediately-available
// burst is drained, keep the transaction open for up to
// FlushIntervalMs waiting for MORE events to trickle in — this is
// the soft-flush coalescing arch-review remediation WP1.2 adds:
// without it, a low-rate trickle of writes (one script call every
// the soft-flush coalescing
// this loop provides: without it, a low-rate trickle of writes (one script call every
// few ms, well under BatchSize) fsyncs once PER EVENT, because the
// writer loop reaches an empty channel and flushes immediately.
// FlushIntervalMs bounds the worst-case added latency any single
@@ -392,8 +392,7 @@ public class SqliteAuditWriter : IAuditWriter, ISiteAuditQueue, IAsyncDisposable
/// <summary>
/// Total number of <see cref="FlushBatch"/> transactions committed since
/// construction. Test-only observability seam (arch-review remediation
/// WP1.2) for asserting that FlushIntervalMs coalesces a trickle of
/// construction. Test-only observability seam for asserting that FlushIntervalMs coalesces a trickle of
/// near-simultaneous writes into a single transaction rather than one
/// commit per event; production code never reads this.
/// </summary>
@@ -499,8 +498,7 @@ public class SqliteAuditWriter : IAuditWriter, ISiteAuditQueue, IAsyncDisposable
{
eventCmd.ExecuteNonQuery();
fwdCmd.ExecuteNonQuery();
// Do NOT complete pending.Completion here (arch-review 2026-08-19
// P4-2). A row's INSERTs succeeding is not durable until the
// Do NOT complete pending.Completion here. A row's INSERTs succeeding is not durable until the
// transaction actually commits below — completing the caller's Task
// this early means a later commit failure (SQLITE_FULL, IOERR, or a
// later row in this same batch throwing) reports false success: the
@@ -866,7 +864,15 @@ public class SqliteAuditWriter : IAuditWriter, ISiteAuditQueue, IAsyncDisposable
/// <summary>Flow Debugger PullTraceEvents: hard cap on ids per read (design §5.4).</summary>
public const int MaxExecutionIdsPerRead = 64;
/// <inheritdoc />
/// <summary>
/// Reads audit events belonging to any of the given execution ids, newer than <paramref name="sinceUtc"/>, in keyset-paged order.
/// </summary>
/// <param name="executionIds">Execution ids to match (capped at <see cref="MaxExecutionIdsPerRead"/>).</param>
/// <param name="sinceUtc">Lower bound on the event's occurrence time.</param>
/// <param name="limit">Maximum number of events to return; must be positive.</param>
/// <param name="ct">Cancellation token.</param>
/// <param name="afterEventId">Optional keyset cursor; only events after this id are returned.</param>
/// <returns>The matching audit events.</returns>
public Task<IReadOnlyList<AuditEvent>> ReadByExecutionIdsAsync(
IReadOnlyCollection<Guid> executionIds, DateTime sinceUtc, int limit, CancellationToken ct = default, string? afterEventId = null)
{
@@ -925,6 +931,8 @@ public class SqliteAuditWriter : IAuditWriter, ISiteAuditQueue, IAsyncDisposable
/// UNION deduplicates rows matching both IDs. Keeping payloads outside the union bounds sorting
/// to IDs/timestamps and avoids the optimizer preferring a whole-store timestamp scan.
/// </summary>
/// <param name="inList">The pre-built SQL parameter list for the <c>IN (...)</c> clauses.</param>
/// <returns>The trace-read SQL text.</returns>
internal static string BuildTraceReadSql(string inList) => $"""
SELECT e.EventId, e.OccurredAtUtc, e.Actor, e.Action, e.Outcome,
e.Category, e.Target, e.SourceNode, e.CorrelationId, e.DetailsJson
@@ -12,7 +12,7 @@ namespace ZB.MOM.WW.ScadaBridge.AuditLog.Site;
/// </summary>
/// <remarks>
/// <see cref="SqliteAuditWriterOptions.DatabasePath"/> is deliberately NOT
/// validated here (arch-review remediation WP1.2). <c>AddAuditLog</c> runs on
/// validated here. <c>AddAuditLog</c> runs on
/// BOTH Central and Site composition roots and binds this options type with
/// <c>ValidateOnStart</c> either way, but only Site nodes ever resolve
/// <see cref="SqliteAuditWriter"/> — requiring a non-empty path in this
@@ -17,6 +17,8 @@ internal static class SqliteErrorCodes
/// "primary/extended" (e.g. "10/522") for a <see cref="SqliteException"/>
/// anywhere in the exception chain; "n/a" for non-SQLite failures.
/// </summary>
/// <param name="ex">The exception to inspect, including its inner exceptions.</param>
/// <returns>The "primary/extended" SQLite error code string, or "n/a" for non-SQLite failures.</returns>
public static string Describe(Exception ex)
{
for (Exception? e = ex; e is not null; e = e.InnerException)