docs(comments): strip internal task/milestone/bundle bookkeeping from code comments

Remove project bookkeeping citations from shipped code comments across the
solution: hyphenated task IDs (WP-14, StoreAndForward-025), milestone/task/
issue refs (M3, Task 4, Audit Log #23, #21), Bundle X task-bundle labels,
and C/D/K/S/T phase labels.

Comment text only — no code logic, string/log literals, or XML-doc structure
changed. Genuine descriptions are preserved (only the citation is stripped),
and technical lookalikes are retained (UTF-8, SHA-256, T00:00:00, M365,
UTC-5, pre-C4/pre-C5 schema versions). Flagged by the new CommentChecker
TaskReferenceInComment / TrackingReferenceInComment checks plus targeted
grep passes; full solution builds clean, append-only guard tests pass.
This commit is contained in:
Joseph Doherty
2026-07-07 11:03:26 -04:00
parent 67005ca4c0
commit 9cff87fe85
435 changed files with 2338 additions and 2547 deletions
+31 -31
View File
@@ -40,7 +40,7 @@ var configuration = new ConfigurationBuilder()
.AddCommandLine(args)
.Build();
// WP-11: Full startup validation — fail fast before any DI or actor system setup
// Full startup validation — fail fast before any DI or actor system setup
StartupValidator.Validate(configuration);
// Read node options for Serilog enrichment
@@ -48,9 +48,9 @@ var nodeRole = configuration["ScadaBridge:Node:Role"]!;
var nodeHostname = configuration["ScadaBridge:Node:NodeHostname"] ?? "unknown";
var siteId = configuration["ScadaBridge:Node:SiteId"] ?? "central";
// WP-14: Serilog structured logging.
// Host-011: minimum level is driven by ScadaBridge:Logging:MinimumLevel (LoggingOptions).
// Host-014: console and file sinks are defined in the `Serilog` configuration
// Serilog structured logging.
// Minimum level is driven by ScadaBridge:Logging:MinimumLevel (LoggingOptions).
// Console and file sinks are defined in the `Serilog` configuration
// section (appsettings.json) and applied via ReadFrom.Configuration inside the
// factory — the sink set, output template, file path and rolling interval are all
// configuration-driven per REQ-HOST-8, not hard-coded here.
@@ -67,10 +67,10 @@ try
var builder = WebApplication.CreateBuilder(args);
builder.Configuration.AddConfiguration(configuration);
// WP-14: Serilog
// Serilog
builder.Host.UseSerilog();
// WP-17: Windows Service support (no-op when not running as a Windows Service)
// Windows Service support (no-op when not running as a Windows Service)
builder.Host.UseWindowsService();
// Shared components
@@ -86,32 +86,32 @@ try
// AddNotificationService() SMTP machinery above. AddNotificationOutbox binds
// NotificationOutboxOptions via BindConfiguration, so no explicit Configure is needed.
builder.Services.AddNotificationOutbox();
// Transport (#24) — central-only bundle export/import pipeline. Binds
// Transport — central-only bundle export/import pipeline. Binds
// TransportOptions from ScadaBridge:Transport via BindConfiguration; no
// explicit Configure needed.
builder.Services.AddTransport();
// Audit Log (#23) — central node owns the AuditLogIngestActor singleton +
// Audit Log — central node owns the AuditLogIngestActor singleton +
// IAuditLogRepository. The site writer chain is still registered (lazy
// singletons) but is never resolved on a central node.
builder.Services.AddAuditLog(builder.Configuration);
// #23 M6-T5 Bundle D — central-only hosted service that rolls
// Central-only hosted service that rolls
// pf_AuditLog_Month forward monthly. Depends on IPartitionMaintenance
// (registered below by AddConfigurationDatabase).
builder.Services.AddAuditLogCentralMaintenance(builder.Configuration);
// #23 M6 Bundle B/C — central-only registration backing the two
// Central-only registration backing the two
// maintenance singletons started in AkkaHostedService: the production
// ISiteEnumerator + IPullAuditEventsClient (gRPC) used by the
// SiteAuditReconciliationActor, plus the AuditLogPurgeOptions /
// SiteAuditReconciliationOptions bindings consumed by both singletons.
// Central-only by design (it dials sites), kept out of AddAuditLog.
builder.Services.AddAuditLogCentralReconciliationClient(builder.Configuration);
// Site Call Audit (#22) — central node owns the SiteCallAuditActor
// singleton (M3 Bundle F). The extension itself currently registers
// Site Call Audit — central node owns the SiteCallAuditActor
// singleton. The extension itself currently registers
// nothing — actor Props are constructed inline in AkkaHostedService —
// but the call is here for symmetry with the other audit composition
// roots so future per-actor DI lands without touching Program.cs.
builder.Services.AddSiteCallAudit();
// KPI History (#26, M6) — central-only. Binds KpiHistoryOptions from
// KPI History — central-only. Binds KpiHistoryOptions from
// ScadaBridge:KpiHistory and registers the validated options consumed by
// the KpiHistoryRecorderActor cluster singleton (started in
// AkkaHostedService). Observability/best-effort: NOT readiness-gated.
@@ -144,7 +144,7 @@ try
// The POST /api/{methodName} endpoint authenticates Bearer tokens
// (sbk_<keyId>_<secret>) and authorizes by scope == method name through this
// verifier. The legacy peppered-HMAC X-API-Key path — the SQL Server ApiKey
// entity, ApiKeyValidator, and IApiKeyHasher — was retired in re-arch C5; the
// entity, ApiKeyValidator, and IApiKeyHasher — was retired; the
// ScadaBridge:InboundApi:ApiKeyPepper config key is now consumed only as the
// library verifier's pepper secret (PepperSecretName below).
//
@@ -175,7 +175,7 @@ try
builder.Services.AddZbApiKeyAuth(builder.Configuration, apiKeyStoreSection);
// Inbound-API key re-arch (C1), additive: expose the library admin facade
// Inbound-API key re-arch, additive: expose the library admin facade
// (ApiKeyAdminCommands) and the app-side management seam (IInboundApiKeyAdmin)
// in the SAME container as AddZbApiKeyAuth, so CLI + CentralUI later create /
// list / enable / disable / delete inbound keys and edit their method-scopes
@@ -201,7 +201,7 @@ try
?? throw new InvalidOperationException("ScadaBridge:Database:ConfigurationDb connection string is required for Central role.");
builder.Services.AddConfigurationDatabase(configDbConnectionString);
// WP-12: Health checks for readiness gating — shared ZB.MOM.WW.Health probes.
// Health checks for readiness gating — shared ZB.MOM.WW.Health probes.
// Check names and the ready/active tier split are preserved: database + akka-cluster
// carry the Ready tag (/health/ready), active-node carries the Active tag (/health/active).
// The Akka checks resolve ActorSystem from DI via the transient bridge registered below;
@@ -216,7 +216,7 @@ try
failureStatus: null,
tags: new[] { ZbHealthTags.Ready },
args: AkkaClusterStatusPolicy.Default)
// M2.14 (#28): readiness ALSO reflects "required cluster singletons running"
// Readiness ALSO reflects "required cluster singletons running"
// (REQ-HOST-4a). Probes each central singleton's local ClusterSingletonProxy
// with a bounded Identify and degrades to Unhealthy if any required singleton
// is unreachable. Registered inside the Central-role branch (this is it) so the
@@ -233,11 +233,11 @@ try
failureStatus: null,
tags: new[] { ZbHealthTags.Active });
// WP-13: Akka.NET bootstrap via hosted service
// Akka.NET bootstrap via hosted service
builder.Services.AddSingleton<AkkaHostedService>();
builder.Services.AddHostedService(sp => sp.GetRequiredService<AkkaHostedService>());
// HOST-021: bridge the AkkaHostedService-owned ActorSystem to DI as a SINGLETON via
// Bridge the AkkaHostedService-owned ActorSystem to DI as a SINGLETON via
// GetOrCreateActorSystem(). The shared ZB.MOM.WW.Health Akka checks resolve ActorSystem
// from DI, per probe, inside a child scope. ActorSystem is IDisposable, so a TRANSIENT
// (or scoped) bridge is captured-and-disposed by each probe's scope — disposing the live
@@ -249,7 +249,7 @@ try
builder.Services.AddSingleton<Akka.Actor.ActorSystem>(sp =>
sp.GetRequiredService<AkkaHostedService>().GetOrCreateActorSystem());
// InboundAPI-022: register the production IActiveNodeGate implementation so
// Register the production IActiveNodeGate implementation so
// standby-node gating is actually enforced (the InboundApiEndpointFilter
// consults IActiveNodeGate and defaults to "allow" when none is registered,
// which leaves the design's "central cluster only (active node)" guarantee
@@ -285,12 +285,12 @@ try
.GetRequiredService<ILoggerFactory>()
.CreateLogger(typeof(MigrationHelper).FullName!);
// Host-010: tolerate a database that is briefly unreachable at boot
// Tolerate a database that is briefly unreachable at boot
// (e.g. app and DB containers starting together) with a bounded
// exponential backoff before failing fatally.
// Host-015: only connection-class (transient) faults are retried — a
// Only connection-class (transient) faults are retried — a
// schema-version mismatch is permanent and must fail fast on attempt 1.
// Host-019: thread the host's ApplicationStopping token into both the
// Thread the host's ApplicationStopping token into both the
// migration call itself and the inter-attempt Task.Delay so a SIGTERM
// during the bounded-retry window (~2 min worst-case) tears down
// cleanly instead of being ignored until the loop exhausts.
@@ -316,7 +316,7 @@ try
app.UseAuthorization();
app.UseAntiforgery();
// Audit Log #23 (M4 Bundle D, T8): emit one InboundRequest/InboundAuthFailure
// Emit one InboundRequest/InboundAuthFailure
// audit row per call into the inbound API. Placed AFTER UseAuthentication/
// UseAuthorization so any HttpContext.User the framework populates is in
// place, and scoped to the /api/ prefix so it never observes the Central UI,
@@ -324,7 +324,7 @@ try
// is responsible for stashing the resolved API key name on
// HttpContext.Items (see AuditWriteMiddleware.AuditActorItemKey) AFTER its
// in-handler API key validation succeeds.
// InboundAPI-025: scope the audit middleware to the inbound API method
// Scope the audit middleware to the inbound API method
// route (/api/{methodName}) and explicitly exclude the management/audit
// sub-trees that share the /api prefix. Without these exclusions the
// middleware would emit a spurious ApiInbound audit row for every
@@ -343,7 +343,7 @@ try
&& HttpMethods.IsPost(ctx.Request.Method),
branch => branch.UseAuditWriteMiddleware());
// WP-12: Map the canonical three-tier health endpoints in one call:
// Map the canonical three-tier health endpoints in one call:
// /health/ready — Ready-tagged checks (database + akka-cluster). REQ-HOST-4a defines
// readiness as cluster membership + DB connectivity, explicitly NOT
// cluster leadership, so the leader-only active-node check is excluded
@@ -365,11 +365,11 @@ try
app.MapCentralUI<ZB.MOM.WW.ScadaBridge.Host.Components.App>();
app.MapInboundAPI();
app.MapManagementAPI();
// Audit Log #23 (M8): CLI-facing /api/audit/{query,export} routes. Same
// Audit Log: CLI-facing /api/audit/{query,export} routes. Same
// Basic-Auth + LDAP mechanism as /management; gated on the OperationalAudit
// / AuditExport role sets.
app.MapAuditAPI();
// Notify-and-fetch deploy (#2/#3): site-facing token-gated fetch of a staged
// Notify-and-fetch deploy: site-facing token-gated fetch of a staged
// deployment's flattened config. Machine-to-machine — AllowAnonymous, gated
// solely by the per-deployment X-Deployment-Token (no central FallbackPolicy).
app.MapDeploymentConfigAPI();
@@ -394,10 +394,10 @@ try
var builder = WebApplication.CreateBuilder(args);
builder.Configuration.AddConfiguration(configuration);
// WP-14: Serilog
// Serilog
builder.Host.UseSerilog();
// WP-17: Windows Service support (no-op when not running as a Windows Service)
// Windows Service support (no-op when not running as a Windows Service)
builder.Host.UseWindowsService();
// Read GrpcPort from config (NodeOptions already has default 8083)
@@ -449,7 +449,7 @@ try
// Map gRPC service — resolves the singleton SiteStreamGrpcServer from DI
app.MapGrpcService<ZB.MOM.WW.ScadaBridge.Communication.Grpc.SiteStreamGrpcServer>();
// Host-017 / REQ-HOST-7: site-shutdown ordering. ApplicationStopping
// REQ-HOST-7: site-shutdown ordering. ApplicationStopping
// fires BEFORE IHostedService.StopAsync runs, so the gRPC server
// refuses new streams (Unavailable) and cancels every active stream
// here — clients observe a clean Cancelled and reconnect — and only