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
@@ -4,7 +4,7 @@ using ZB.MOM.WW.ScadaBridge.Commons.Entities.InboundApi;
namespace ZB.MOM.WW.ScadaBridge.InboundAPI;
/// <summary>
/// WP2.6b (arch-review misc — Inbound API per-request SQL): a short-TTL cache of
/// A short-TTL cache of
/// resolved <c>ApiMethod</c> rows, sitting in front of <c>IInboundApiRepository.GetMethodByNameAsync</c>
/// so a repeated <c>POST /api/{methodName}</c> burst for the same method does not each pay a
/// database round-trip.
@@ -60,6 +60,7 @@ public sealed class ApiMethodCache
/// <param name="methodName">The method name to resolve.</param>
/// <param name="fetch">Loads the current row from the repository on a cache miss.</param>
/// <param name="cancellationToken">Cancellation token for the fetch.</param>
/// <returns>The cached or freshly fetched <see cref="ApiMethod"/>, or <c>null</c> when the method does not exist.</returns>
public async Task<ApiMethod?> GetOrFetchAsync(
string methodName,
Func<CancellationToken, Task<ApiMethod?>> fetch,
@@ -151,7 +151,7 @@ public static class EndpointExtensions
// "Echo" does not grant "echo". This is the intended invariant: method
// names are case-sensitive identifiers, and a key's granted scopes must be
// provisioned with the exact casing of the methods they authorize.
// WP2.6b: the per-request repository round-trip is fronted by a short-TTL
// The per-request repository round-trip is fronted by a short-TTL
// ApiMethodCache (invalidated by name on an ApiMethod ScriptArtifactsChanged
// notification, and self-healing via TTL expiry otherwise — see ApiMethodCache
// and ScriptArtifactChangeSubscriber). Only reached after the in-scope check
@@ -233,7 +233,7 @@ public sealed class HttpStandbyRequestForwarder : IStandbyRequestForwarder
Body = body;
}
/// <inheritdoc />
/// <summary>The peer's HTTP status code, replayed verbatim.</summary>
public int? StatusCode { get; }
/// <summary>The peer's <c>Content-Type</c>, replayed verbatim.</summary>
@@ -242,7 +242,9 @@ public sealed class HttpStandbyRequestForwarder : IStandbyRequestForwarder
/// <summary>The peer's response body, replayed verbatim.</summary>
public byte[] Body { get; }
/// <inheritdoc />
/// <summary>Writes the peer's status, content type and body to the response.</summary>
/// <param name="httpContext">The HTTP context to write the relayed response to.</param>
/// <returns>A task that represents the asynchronous operation.</returns>
public async Task ExecuteAsync(HttpContext httpContext)
{
httpContext.Response.StatusCode = StatusCode ?? StatusCodes.Status200OK;
@@ -36,7 +36,7 @@ public class InboundApiOptions
public string ApiKeyPepper { get; set; } = string.Empty;
/// <summary>
/// WP2.6b (arch-review misc — Inbound API per-request SQL): how long a resolved
/// How long a resolved
/// <c>ApiMethod</c> row (found OR not-found) is served from <see cref="ApiMethodCache"/>
/// before the next request re-fetches it from the repository. The
/// <c>ScriptArtifactChangeSubscriber</c>/<c>IScriptArtifactChangeBus</c> pipeline
@@ -44,8 +44,7 @@ namespace ZB.MOM.WW.ScadaBridge.InboundAPI;
/// </para>
///
/// <para>
/// <b>Audited (Audit Log #23, outbound DB scope; Flow Debugger outbound-calls plan
/// 2026-09-06 D7).</b> Every call emits exactly ONE <c>DbOutbound</c>/<c>DbWrite</c> row
/// <b>Audited (outbound DB scope).</b> Every call emits exactly ONE <c>DbOutbound</c>/<c>DbWrite</c> row
/// through the central <see cref="ICentralAuditWriter"/> using the site's
/// <c>AuditingDbCommand</c> vocabulary: <c>Extra = {"op":"write","rowsAffected":N}</c> for
/// <see cref="ExecuteAsync"/>, <c>{"op":"read","rowsReturned":N}</c> for the two query
@@ -152,6 +152,9 @@ public class InboundScriptExecutor
public void RemoveHandler(string methodName) => InvalidateMethod(methodName);
/// <summary>Checks compilation without publishing or invalidating a live handler.</summary>
/// <param name="method">The API method whose script is compiled.</param>
/// <param name="errors">The compilation diagnostics, empty on success.</param>
/// <returns><c>true</c> when the script compiles; otherwise <c>false</c>.</returns>
public bool ValidateCompilation(ApiMethod method, out IReadOnlyList<string> errors)
{
var (handler, diagnostics) = Compile(method);
@@ -332,6 +335,7 @@ public class InboundScriptExecutor
/// script execution points back at this inbound request. Null when the script
/// runs outside an inbound API request flow.
/// </param>
/// <param name="trace">When true, the run is traced for the Flow Debugger.</param>
/// <returns>The result of executing the script.</returns>
public async Task<InboundScriptResult> ExecuteAsync(
ApiMethod method,
@@ -212,7 +212,7 @@ public sealed class InboundScriptLogger
/// <summary>
/// Applies the per-message cap, marking a truncated message with a trailing ellipsis.
///
/// <para>Final review M2 — mirrors the site runtime's <c>ScriptLogger.Clip</c>: cuts one char
/// <para>Mirrors the site runtime's <c>ScriptLogger.Clip</c>: cuts one char
/// short when the cap would land between the two halves of a surrogate pair, so an emoji
/// straddling the boundary is dropped whole rather than leaving a lone surrogate that breaks
/// JSON serialization downstream.</para>
@@ -129,6 +129,10 @@ public sealed class AuditWriteMiddleware
/// so existing tests and composition roots without the central health snapshot
/// wired still construct without the counter; a NoOp is used when absent.
/// </param>
/// <param name="inboundOptions">
/// Live-reloadable inbound API options, read per-request. Optional; when absent the
/// defaults apply.
/// </param>
public AuditWriteMiddleware(
RequestDelegate next,
ICentralAuditWriter auditWriter,
@@ -15,10 +15,21 @@ internal static class RelayProvenance
private sealed record Proof(long Time, Guid ExecutionId, string Ip, string Binding);
private static readonly byte[] Domain = "ScadaBridge.InboundRelay.v1"u8.ToArray();
/// <summary>Whether a valid relay proof has been verified for this request.</summary>
/// <param name="context">The current HTTP context.</param>
/// <returns>True when the request carried a verified relay proof.</returns>
internal static bool IsVerified(HttpContext context) => context.Items.ContainsKey(VerifiedKey);
/// <summary>Gets the effective caller IP: the verified relayed IP, otherwise the connection's remote IP.</summary>
/// <param name="context">The current HTTP context.</param>
/// <returns>The caller IP address, or null when unknown.</returns>
internal static string? CallerIp(HttpContext context)
=> context.Items.TryGetValue(VerifiedKey, out var ip) ? ip as string : context.Connection.RemoteIpAddress?.ToString();
/// <summary>Builds a signed relay proof header value binding the caller IP, execution id and request.</summary>
/// <param name="context">The current HTTP context.</param>
/// <param name="body">The request body being relayed.</param>
/// <param name="pepper">The shared secret used to compute the MAC.</param>
/// <returns>The proof header value, or null when it cannot be produced.</returns>
internal static string? Sign(HttpContext context, byte[] body, string pepper)
{
if (pepper.Length < 16 || context.Connection.RemoteIpAddress is null) return null;
@@ -30,6 +41,10 @@ internal static class RelayProvenance
return Convert.ToBase64String(bytes) + "." + Convert.ToHexString(Mac(bytes, pepper));
}
/// <summary>Validates an incoming relay proof header and, when valid, records the relayed caller IP and execution id on the request.</summary>
/// <param name="context">The current HTTP context.</param>
/// <param name="options">The inbound API options.</param>
/// <returns>A task that represents the asynchronous operation.</returns>
internal static async Task VerifyAsync(HttpContext context, InboundApiOptions options)
{
var header = context.Request.Headers[Header].ToString();
@@ -57,6 +72,11 @@ internal static class RelayProvenance
context.Items[AuditWriteMiddleware.InboundExecutionIdItemKey] = proof.ExecutionId;
}
/// <summary>Reads a stream fully, failing if it exceeds the given byte limit.</summary>
/// <param name="body">The stream to read.</param>
/// <param name="limit">The maximum number of bytes allowed.</param>
/// <param name="ct">Token to cancel the read.</param>
/// <returns>The bytes read.</returns>
internal static async Task<byte[]> ReadBoundedAsync(Stream body, long limit, CancellationToken ct)
{
using var buffer = new MemoryStream();
@@ -35,7 +35,7 @@ public sealed class ScriptArtifactChangeSubscriber : IHostedService
/// <summary>Initializes the subscriber.</summary>
/// <param name="executor">The compiled-handler cache to invalidate.</param>
/// <param name="methodCache">
/// WP2.6b: the short-TTL resolved-<c>ApiMethod</c>-row cache to invalidate alongside
/// The short-TTL resolved-<c>ApiMethod</c>-row cache to invalidate alongside
/// the compiled handler.
/// </param>
/// <param name="logger">Logger instance.</param>
@@ -52,7 +52,9 @@ public sealed class ScriptArtifactChangeSubscriber : IHostedService
_bus = bus;
}
/// <inheritdoc />
/// <summary>Subscribes to the change bus, when one is registered, to invalidate cached handlers.</summary>
/// <param name="cancellationToken">Cancellation token (unused).</param>
/// <returns>A completed task.</returns>
public Task StartAsync(CancellationToken cancellationToken)
{
if (_bus is null)
@@ -66,7 +68,9 @@ public sealed class ScriptArtifactChangeSubscriber : IHostedService
return Task.CompletedTask;
}
/// <inheritdoc />
/// <summary>Disposes the change-bus subscription.</summary>
/// <param name="cancellationToken">Cancellation token (unused).</param>
/// <returns>A completed task.</returns>
public Task StopAsync(CancellationToken cancellationToken)
{
_subscription?.Dispose();
@@ -20,7 +20,7 @@ public static class ServiceCollectionExtensions
services.AddSingleton<InboundScriptExecutor>();
services.AddScoped<RouteHelper>();
// WP2.6b: short-TTL cache of resolved ApiMethod rows, sitting in front of the
// Short-TTL cache of resolved ApiMethod rows, sitting in front of the
// per-request repository fetch in EndpointExtensions. Invalidated by name via
// ScriptArtifactChangeSubscriber (below) and self-heals via TTL expiry for
// changes the bus does not cover.