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
@@ -188,7 +188,7 @@ public class ArtifactDeploymentService
// marked removed and the mirror deletes it), and a null Secrets means "central did
// not ship secrets at all" (the pre-feature/old-central contract), which touches
// nothing. Shipping null here when the LAST reference is dropped therefore left the
// secret live on both site nodes forever (Task 13 live gate, check 5). An empty
// secret live on both site nodes forever (observed in the live gate). An empty
// list costs an old site nothing (it ignores proto field 9), and the hash is
// unaffected: the hash service folds an empty and a null list identically.
Secrets: collected.Secrets,
@@ -198,7 +198,7 @@ public class ArtifactDeploymentService
}
/// <summary>
/// Task 7 (design §3.4): reconciles a site's raw <see cref="ArtifactDeploymentResponse"/>
/// Reconciles a site's raw <see cref="ArtifactDeploymentResponse"/>
/// against what the deployed <see cref="DeployArtifactsCommand"/> actually shipped, so
/// central never stamps a site *Current* on the strength of a reply that only proves the
/// artifact set was RECEIVED, not that every shipped secret was APPLIED.
@@ -267,8 +267,8 @@ public class ArtifactDeploymentService
{
// A removal-only deploy (the site's last secret reference was dropped, so nothing
// ships but the site retires previously-deployed rows) and a secret-store outage both
// count as "secrets involved" — the former used to write no row at all (final review
// M6 follow-up), leaving the removal visible only in the site's own logs.
// count as "secrets involved" — the former used to write no row at all,
// leaving the removal visible only in the site's own logs.
var hasSecretRefs = (command.Secrets?.Count ?? 0) > 0
|| missing.Count > 0
|| secretStoreError is not null
@@ -475,7 +475,7 @@ public class ArtifactDeploymentService
var (command, missing, secretStoreError) = siteCommands[site.Id];
// A central secret-store read failure (final review M5) fails only the sites
// A central secret-store read failure fails only the sites
// that reference a secret — resolution is incomplete, so shipping would either
// drop a secret the site still needs or retire one it still uses. Sites with no
// secret references never touch the store and deploy normally.
@@ -515,7 +515,7 @@ public class ArtifactDeploymentService
var response = await _communicationService.DeployArtifactsAsync(
site.SiteIdentifier, command, cts.Token);
// Task 7 (design §3.4): a reply that only proves receipt is not enough to
// A reply that only proves receipt is not enough to
// stamp *Current* — reconcile it against what was actually shipped before
// this result feeds the stamp decision below.
return ReconcileSecretsOutcome(command, response, site.SiteIdentifier, site.Name);
@@ -547,7 +547,7 @@ public class ArtifactDeploymentService
perSiteResults[result.SiteId] = result;
}
// Task 7 (design §3.4): one best-effort DeploySiteSecrets audit row per site whose
// One best-effort DeploySiteSecrets audit row per site whose
// command carried or would have carried secrets — covers the reconciled
// success/failure path AND the fail-closed (missing secret, nothing sent) path, since
// both already flow into perSiteResults above by the time this loop runs. Driven off
@@ -641,7 +641,7 @@ public class ArtifactDeploymentService
var (command, missing, secretStoreError) = await BuildDeployArtifactsCommandAsync(siteDbId, cts.Token);
// Same store-outage rule as the sweep path (final review M5).
// Same store-outage rule as the sweep path.
if (secretStoreError is not null)
{
_logger.LogError(
@@ -659,7 +659,7 @@ public class ArtifactDeploymentService
var missingMessage = BuildMissingSecretsMessage(missing);
_logger.LogError(
"Cannot deploy artifacts to site {SiteId}: {Error}", siteIdentifier, missingMessage);
// Task 7: the fail-closed case still gets its DeploySiteSecrets row — nothing
// The fail-closed case still gets its DeploySiteSecrets row — nothing
// was sent, but the command carried (or would have carried) secrets.
await LogSecretsAuditAsync(
user, command, missing, null, null, siteIdentifier, siteIdentifier, false, missingMessage,
@@ -677,7 +677,7 @@ public class ArtifactDeploymentService
var response = await _communicationService.DeployArtifactsAsync(siteIdentifier, command, cts.Token);
// Task 7 (design §3.4): reconcile the raw wire response against what was
// Reconcile the raw wire response against what was
// actually shipped before it feeds the audit row, the stamp decision, or the
// returned Result — an old site's/partial site's reply must not read as success.
var result = ReconcileSecretsOutcome(command, response, siteIdentifier, siteIdentifier);
@@ -739,7 +739,7 @@ public class ArtifactDeploymentService
/// faulted flight and the UI shows the aggregate as unavailable instead.
/// </para>
/// <para>
/// A central secret-store read failure is the one per-site exception (final review M5): the
/// A central secret-store read failure is the one per-site exception: the
/// affected site is left OUT of the map, which the evaluator reads as <i>Out of date</i> (a
/// missing entry never matches a stamp), so a store outage degrades only the sites that
/// reference secrets instead of failing the fleet-wide check.
@@ -765,7 +765,7 @@ public class ArtifactDeploymentService
var (command, _, secretStoreError) = await BuildDeployArtifactsCommandAsync(
site.Id, globals, cancellationToken, deploymentId: "current");
// A central secret-store outage (final review M5) leaves this site's current hash
// A central secret-store outage leaves this site's current hash
// unknowable. Omitting it from the map makes the site read *Out of date* — the
// conservative answer, never a false *Current* — while every other site, including
// every site with no secret references, still evaluates normally instead of the
@@ -211,7 +211,7 @@ public class DeploymentService
// idempotency, lock coverage and optimistic concurrency from drifting apart
// between them.
// reconcileGate is null on this path on purpose: the batch-wide reconcile
// budget exists to stop a serial phase-1 loop multiplying one unreachable
// budget exists to stop a serial prepare-phase loop multiplying one unreachable
// site's query timeout by the instance count. A single instance pays it
// once, and this is the explicit operator path — it keeps the full
// communication-layer QueryTimeout.
@@ -248,7 +248,7 @@ public class DeploymentService
/// <para>
/// Everything here touches the scoped, non-thread-safe <c>DbContext</c>, so it
/// must run serially — a bulk site deploy loops this phase before fanning out
/// the phase-2 network waits. On success the returned
/// the send-phase network waits. On success the returned
/// <see cref="PreparedDeployment"/> owns the operation lock; the CALLER is
/// responsible for disposing it once phase 3 has completed.
/// </para>
@@ -470,7 +470,7 @@ public class DeploymentService
/// </para>
///
/// <para>
/// A staging failure is returned as the phase-2 fault rather than thrown, so
/// A staging failure is returned as the send-phase fault rather than thrown, so
/// phase 3 marks the record Failed on exactly the same path as a send fault —
/// the record must never be left InProgress.
/// </para>
@@ -702,7 +702,7 @@ public class DeploymentService
/// </para>
///
/// <para>
/// <b>The cleanup save is un-poisoned before it is given up on (P7-5).</b> A
/// <b>The cleanup save is un-poisoned before it is given up on.</b> A
/// failed <c>SaveChanges</c> does not untrack the entity that caused it: EF
/// keeps it in the change set and re-attempts it on the NEXT save. Every phase
/// of a bulk site deploy shares ONE scoped <c>DbContext</c> across every
@@ -821,7 +821,7 @@ public class DeploymentService
IDisposable? LockHandle,
Result<DeploymentRecord>? EarlyResult)
{
/// <summary>Builds a phase-1-resolved deployment carrying the given result and holding no lock.</summary>
/// <summary>Builds a prepare-phase-resolved deployment carrying the given result and holding no lock.</summary>
/// <param name="result">The result to hand back to the caller.</param>
/// <returns>A prepared deployment whose <see cref="EarlyResult"/> is set.</returns>
public static PreparedDeployment Resolved(Result<DeploymentRecord> result) =>
@@ -930,7 +930,7 @@ public class DeploymentService
/// <param name="user">The username initiating the deployment, recorded on every record and audit row.</param>
/// <param name="force">
/// Deploy every deployable instance even when its config is unchanged — the
/// pre-2026-08 behaviour. The operator escape hatch for the case central's
/// previous behaviour. The operator escape hatch for the case central's
/// recorded state cannot see: a site that lost its config (restored volume,
/// rebuilt node) looks up-to-date from here and needs the push anyway. Has no
/// effect on Disabled instances.
@@ -14,7 +14,7 @@ namespace ZB.MOM.WW.ScadaBridge.DeploymentManager;
/// <param name="Missing">References that are absent or tombstoned in the store.</param>
/// <param name="StoreError">
/// <see langword="null"/> when every reference was looked up. Otherwise the store read failed
/// (final review M5: e.g. the shared SQL Server secret store is unreachable), resolution stopped
/// (e.g. the shared SQL Server secret store is unreachable), resolution stopped
/// at the first failure, and <see cref="Secrets"/>/<see cref="Missing"/> are INCOMPLETE — the
/// caller must treat this site as undeployable and its current hash as unknown. The message is
/// the exception type and message only; it never contains secret material.
@@ -43,7 +43,7 @@ public sealed class SiteSecretsCollector(ISecretStore store)
/// The resolved rows (mapped field-for-field from <see cref="StoredSecret"/>) and the
/// references that were absent or tombstoned in the store. A store read failure is
/// returned as <see cref="SiteSecretsCollection.StoreError"/> rather than thrown, so one
/// site's lookup failing never aborts a whole multi-site sweep (final review M5); only
/// site's lookup failing never aborts a whole multi-site sweep; only
/// cancellation of <paramref name="ct"/> propagates. A site whose connections reference no
/// secret never touches the store at all.
/// </returns>
@@ -10,6 +10,8 @@ public sealed class StaleInstanceProbe : IStaleInstanceProbe
private readonly IFlatteningPipeline _flatteningPipeline;
/// <summary>Initializes the authoritative probe. Watermark remains a constructor compatibility dependency.</summary>
/// <param name="flatteningPipeline">The pipeline used to flatten instances for staleness comparison.</param>
/// <param name="watermark">The template graph watermark; retained only for constructor compatibility.</param>
public StaleInstanceProbe(IFlatteningPipeline flatteningPipeline, ITemplateGraphWatermark watermark)
{
_flatteningPipeline = flatteningPipeline ?? throw new ArgumentNullException(nameof(flatteningPipeline));