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
@@ -32,7 +32,7 @@ internal static class AlarmTriggerConfigJson
/// <param name="hiHi">HiLo: high-high setpoint.</param>
/// <param name="expression">Expression: boolean trigger expression.</param>
/// <param name="analysisKind">
/// M9-T28b: optional analysis kind for Expression triggers ("strict" → emits
/// Optional analysis kind for Expression triggers ("strict" → emits
/// <c>"analysisKind":"Strict"</c>; null/"advisory"/anything else → Advisory default,
/// key omitted). Ignored for non-Expression trigger types.
/// </param>
@@ -86,7 +86,7 @@ internal static class AlarmTriggerConfigJson
break;
case "expression":
w.WriteString("expression", expression ?? "");
// M9-T28b: emit "analysisKind":"Strict" only when the caller passes
// Emit "analysisKind":"Strict" only when the caller passes
// --trigger-kind strict (case-insensitive); Advisory (the default) is
// expressed by omitting the key, matching ValidationService.IsStrictAnalysis.
if (string.Equals(analysisKind?.Trim(), "Strict", StringComparison.OrdinalIgnoreCase))
+1 -1
View File
@@ -40,7 +40,7 @@ public class CliConfig
".scadabridge", "config.json");
if (File.Exists(configPath))
{
// CLI-021: a malformed (`JsonException`), unreadable
// A malformed (`JsonException`), unreadable
// (`UnauthorizedAccessException`), or otherwise faulted
// (`IOException`) config file must not crash the CLI before any
// command runs — even a command that supplies everything via
@@ -27,8 +27,8 @@ public sealed class AuditBackfillSourceNodeArgs
}
/// <summary>
/// Pure helpers for the <c>audit backfill-source-node</c> subcommand (Audit Log
/// #23 M5.6 T5). Builds the request body, POSTs to
/// Pure helpers for the <c>audit backfill-source-node</c> subcommand. Builds
/// the request body, POSTs to
/// <c>/api/audit/backfill-source-node</c>, and renders the result. Kept separate
/// from the command wiring so each piece is unit-testable without standing up the
/// command tree.
@@ -4,8 +4,8 @@ using System.CommandLine.Parsing;
namespace ZB.MOM.WW.ScadaBridge.CLI.Commands;
/// <summary>
/// The <c>scadabridge audit</c> command group (Audit Log #23 M8). Provides read access to
/// the centralized append-only Audit Log via the Bundle B REST endpoints
/// The <c>scadabridge audit</c> command group. Provides read access to
/// the centralized append-only Audit Log via the REST endpoints
/// (<c>GET /api/audit/query</c>, <c>GET /api/audit/export</c>,
/// <c>GET /api/audit/tree</c>), plus a v1 no-op <c>verify-chain</c> placeholder
/// for the deferred hash-chain tamper-evidence feature.
@@ -291,7 +291,7 @@ public static class AuditCommands
}
/// <summary>
/// Builds the <c>audit backfill-source-node</c> sub-command (Audit Log #23 M5.6 T5).
/// Builds the <c>audit backfill-source-node</c> sub-command.
/// Sets <c>SourceNode</c> on historical pre-feature rows whose <c>SourceNode IS NULL</c>
/// and <c>OccurredAtUtc</c> is older than <c>--before</c>, in batches. Admin-only.
/// </summary>
@@ -6,7 +6,7 @@ namespace ZB.MOM.WW.ScadaBridge.CLI.Commands;
/// <summary>
/// Filter + destination arguments for an <c>audit export</c> invocation. Mirrors the
/// Bundle B <c>GET /api/audit/export</c> parameters.
/// <c>GET /api/audit/export</c> parameters.
/// <see cref="Channel"/>/<see cref="Kind"/>/<see cref="Status"/>/<see cref="Site"/>
/// are multi-valued — each supplied value becomes a repeated query-string param so
/// the server's multi-value <c>IN (…)</c> filter sees the full set, exactly like
@@ -150,7 +150,7 @@ public static class AuditExportHelpers
if (!response.IsSuccessStatusCode)
{
var message = await response.Content.ReadAsStringAsync();
// CLI-018: honour the documented "authorization failure → exit 2"
// Honour the documented "authorization failure → exit 2"
// contract on the REST audit surface as well. HTTP 403 is the
// primary signal; the server may also surface UNAUTHORIZED /
// FORBIDDEN via the JSON error envelope on a non-403 status.
@@ -5,7 +5,7 @@ namespace ZB.MOM.WW.ScadaBridge.CLI.Commands;
/// <summary>
/// Renders a page of audit-log events to a writer. The <c>audit query</c> command picks
/// a formatter from the <c>--format</c> option. The default JSONL formatter is defined
/// here; the human-readable table formatter is supplied by Bundle C.
/// here; the human-readable table formatter is supplied by <see cref="TableAuditFormatter"/>.
/// </summary>
public interface IAuditFormatter
{
@@ -10,7 +10,7 @@ namespace ZB.MOM.WW.ScadaBridge.CLI.Commands;
/// centralized append-only Audit Log served by <see cref="AuditCommands"/>).
/// </summary>
/// <remarks>
/// Renamed from <c>audit-log</c> in #23 M8-T7 to avoid confusion with the new
/// Renamed from <c>audit-log</c> to avoid confusion with the new
/// <c>scadabridge audit</c> group. The old <c>audit-log</c> name is retained as a
/// deprecated alias; <see cref="DeprecatedAlias"/> still resolves the full subcommand
/// tree, and <c>Program.cs</c> prints a deprecation warning when it is used.
@@ -54,7 +54,7 @@ public static class AuditLogCommands
public static Command Build(Option<string> urlOption, Option<string> formatOption, Option<string> usernameOption, Option<string> passwordOption)
{
var command = new Command("audit-config") { Description = "Query the configuration-change audit log" };
// Backward-compatible alias for the pre-M8 `audit-log` name. The alias keeps
// Backward-compatible alias for the old `audit-log` name. The alias keeps
// full subcommand parity automatically; the deprecation warning is emitted by
// the args[0] check in Program.cs.
command.Aliases.Add(DeprecatedAlias);
@@ -6,7 +6,7 @@ using System.Text.RegularExpressions;
namespace ZB.MOM.WW.ScadaBridge.CLI.Commands;
/// <summary>
/// Filter arguments for an <c>audit query</c> invocation. Mirrors the Bundle B
/// Filter arguments for an <c>audit query</c> invocation. Mirrors the
/// <c>GET /api/audit/query</c> filter parameters; <see cref="Since"/>/<see cref="Until"/>
/// are time-specs (relative like <c>1h</c>/<c>7d</c>, or absolute ISO-8601).
/// <see cref="Channel"/>/<see cref="Kind"/>/<see cref="Status"/>/<see cref="Site"/>
@@ -192,7 +192,7 @@ public static class AuditQueryHelpers
{
OutputFormatter.WriteError(
response.Error ?? "Audit query failed.", response.ErrorCode ?? "ERROR");
// CLI-018: surface the documented "authorization failure → exit 2"
// Surface the documented "authorization failure → exit 2"
// contract for the audit REST surface too, not just /management.
return CommandHelpers.IsAuthorizationFailure(response) ? 2 : 1;
}
@@ -6,7 +6,7 @@ using ZB.MOM.WW.ScadaBridge.Commons.Messages.Management;
namespace ZB.MOM.WW.ScadaBridge.CLI.Commands;
/// <summary>
/// Transport (#24) bundle export / preview / import. The bundle bytes travel
/// Transport bundle export / preview / import. The bundle bytes travel
/// through the management endpoint as base64 inside the standard JSON envelope
/// so no transport plumbing diverges from the other commands; the CLI handles
/// file I/O at the edges.
@@ -61,14 +61,14 @@ public static class BundleCommands
var dbConnectionsOption = NameListOption("--db-connections", "Comma-separated database-connection names");
var notificationListsOption = NameListOption("--notification-lists", "Comma-separated notification-list names");
var smtpConfigsOption = NameListOption("--smtp-configs", "Comma-separated SMTP host names");
// SMS (S10b): SmsConfiguration is keyed by AccountSid (no Name column), so
// SMS: SmsConfiguration is keyed by AccountSid (no Name column), so
// tokens are AccountSid values — mirrors --smtp-configs using Host.
var smsConfigsOption = NameListOption("--sms-configs", "Comma-separated SMS provider account SIDs");
// Inbound API keys are not transported between environments (re-arch C4) — no
// Inbound API keys are not transported between environments — no
// --api-keys option. Re-create keys and re-grant their method scopes on the
// destination via the admin UI/CLI.
var apiMethodsOption = NameListOption("--api-methods", "Comma-separated API-method names");
// M8 (B4): site/instance-scoped export. Sites accept a SiteIdentifier
// Site/instance-scoped export. Sites accept a SiteIdentifier
// (preferred) or friendly Name per token; instances accept a UniqueName.
var sitesOption = NameListOption("--sites", "Comma-separated site identifiers or names");
var instancesOption = NameListOption("--instances", "Comma-separated instance unique-names");
@@ -131,7 +131,7 @@ public static class BundleCommands
timeout: BundleCommandTimeout,
onSuccess: jsonOk =>
{
// CLI-020: previously the JSON envelope parse + property extraction +
// Previously the JSON envelope parse + property extraction +
// base64 decode all ran unguarded — a server-side bug that omits one of
// the two expected properties, returns a null base64 value, sends invalid
// base64, or returns a malformed JSON envelope would surface as one of
@@ -139,7 +139,7 @@ public static class BundleCommands
// JsonException, i.e. an unhandled stack trace rather than the
// documented "exit 1 with a clean INVALID_RESPONSE error". Wrap the
// envelope parse and the streamed write in a single try/catch matching
// the graceful-degradation theme established by CLI-002 / CLI-003 / CLI-005.
// the graceful-degradation theme established elsewhere in this command group.
string base64;
int byteCount;
try
@@ -158,7 +158,7 @@ public static class BundleCommands
return 1;
}
// CLI-019: stream the base64 → file write so a 100 MB bundle
// Stream the base64 → file write so a 100 MB bundle
// doesn't double-buffer through Convert.FromBase64String's
// ~100 MB byte[] on the LOH plus a synchronous File.WriteAllBytes.
// The management envelope's body is still buffered into the
@@ -314,7 +314,7 @@ public static class BundleCommands
Description = "Resolution policy applied to every Modified row: skip, overwrite, or rename. Default: overwrite.",
DefaultValueFactory = _ => "overwrite",
};
// M8 (D3): site/connection name mapping. Repeatable. A token with no
// Site/connection name mapping. Repeatable. A token with no
// "=dst" part, or "=" with an empty right-hand side, means CreateNew (the
// destination is created from the bundle payload); otherwise the source
// is mapped to the named existing destination.
@@ -400,7 +400,7 @@ public static class BundleCommands
// Shared HTTP plumbing
// ====================================================================
//
// CLI-017: bundle commands previously routed through a private
// Bundle commands previously routed through a private
// RunBundleCommandAsync that re-implemented URL/credential resolution and
// skipped the IsAuthorizationFailure(...) check that ExecuteCommandAsync
// enforces — a server that signalled FORBIDDEN/UNAUTHORIZED via the error
@@ -409,7 +409,7 @@ public static class BundleCommands
// the longer BundleCommandTimeout and a per-command success handler, so the
// exit-code contract is unified across every command group.
// CLI-019: chunked base64 → file streaming. The management envelope's
// Chunked base64 → file streaming. The management envelope's
// success body is a single buffered JSON string (the wire format does not
// currently support response-body streaming), so we cannot remove the
// ~base64-string + ~envelope-string allocation. What we CAN — and do —
@@ -27,13 +27,12 @@ internal static class CommandHelpers
/// body instead of running the default <see cref="HandleResponse"/> rendering path —
/// useful when the caller needs to capture the response (e.g. write a file) rather
/// than print it. The authorization-failure exit-code contract
/// (<see cref="IsAuthorizationFailure"/>) is preserved on the error path either way,
/// closing CLI-017's regression.
/// (<see cref="IsAuthorizationFailure"/>) is preserved on the error path either way.
/// </param>
/// <param name="tableProjector">
/// Optional transform applied to the success JSON body <em>only</em> when the resolved
/// format is <c>table</c>. Lets a command render a compact table projection (e.g.
/// <c>template list</c> dropping per-template attribute dumps, followup #6) while
/// <c>template list</c> dropping per-template attribute dumps) while
/// leaving JSON output untouched for machine consumers. Ignored when
/// <paramref name="onSuccess"/> is supplied.
/// </param>
@@ -95,8 +94,7 @@ internal static class CommandHelpers
// Caller-supplied success handler short-circuits the default rendering — but
// the error path still routes through IsAuthorizationFailure so the documented
// exit-2 contract holds whether or not a custom handler is provided
// (CLI-017 unification of the bundle path).
// exit-2 contract holds whether or not a custom handler is provided.
if (onSuccess is not null)
{
if (response.JsonData is not null)
@@ -255,7 +253,7 @@ internal static class CommandHelpers
// Derive the header set as the union of property names across *every*
// element, in first-seen order. Using only items[0] would silently drop
// columns for any later element with a different shape (CLI-016).
// columns for any later element with a different shape.
var objectItems = items.Where(i => i.ValueKind == JsonValueKind.Object).ToList();
string[] headers;
if (objectItems.Count > 0)
@@ -100,7 +100,7 @@ public static class DebugCommands
.WithAutomaticReconnect()
.Build();
// CLI-011: CancellationTokenSource owns a WaitHandle and must be disposed.
// CancellationTokenSource owns a WaitHandle and must be disposed.
using var cts = new CancellationTokenSource();
var exitTcs = new TaskCompletionSource<int>(TaskCreationOptions.RunContinuationsAsynchronously);
@@ -199,7 +199,7 @@ public static class DebugCommands
}
catch (Exception ex)
{
// CLI-010: Ctrl+C during connect throws OperationCanceledException — that is
// Ctrl+C during connect throws OperationCanceledException — that is
// a graceful user cancellation, not a connection failure.
var failure = DebugStreamHelpers.ClassifyConnectFailure(ex, cts.IsCancellationRequested);
if (failure.IsCancellation)
@@ -250,7 +250,7 @@ public static class DebugCommands
await connection.DisposeAsync();
// CLI-012: resolve the exit code from a single authoritative source. A result
// Resolve the exit code from a single authoritative source. A result
// set by OnStreamTerminated/Closed always wins; a brief grace period covers a
// termination racing with Ctrl+C. Pure Ctrl+C (no result) is a graceful exit 0.
return await DebugStreamHelpers.ResolveStreamExitCodeAsync(exitTcs.Task);
@@ -3,8 +3,8 @@ namespace ZB.MOM.WW.ScadaBridge.CLI.Commands;
/// <summary>
/// Pure, testable helpers for the <c>debug stream</c> command. The SignalR-driven
/// <see cref="DebugCommands"/> body itself cannot be unit-tested without a live hub, so
/// the decision logic — connect-failure classification (CLI-010) and exit-code
/// resolution after stream termination (CLI-012) — is extracted here.
/// the decision logic — connect-failure classification and exit-code
/// resolution after stream termination — is extracted here.
/// </summary>
internal static class DebugStreamHelpers
{
@@ -3,8 +3,8 @@ using System.Text.Json;
namespace ZB.MOM.WW.ScadaBridge.CLI.Commands;
/// <summary>
/// Human-readable table formatter for <c>audit query --format table</c> (Audit Log
/// #23 M8-T6). Renders each fetched page as a column-aligned text table with a fixed
/// Human-readable table formatter for <c>audit query --format table</c>.
/// Renders each fetched page as a column-aligned text table with a fixed
/// column set (<see cref="Columns"/>). Long free-text fields (Target, Actor) are
/// truncated with an ellipsis so columns stay aligned regardless of payload size.
/// </summary>
@@ -446,7 +446,7 @@ public static class TemplateCommands
/// <summary>
/// Determines whether <c>--trigger-kind</c> was supplied without a <c>--trigger-config</c>.
/// In that case <see cref="TriggerConfigJson.InjectAnalysisKind"/> has no JSON object to inject
/// into and silently drops the kind (#257) — the caller should warn the user.
/// into and silently drops the kind — the caller should warn the user.
/// </summary>
/// <param name="triggerConfig">The raw <c>--trigger-config</c> JSON value, or null when absent.</param>
/// <param name="triggerKind">The raw <c>--trigger-kind</c> value, or null when absent.</param>
@@ -502,7 +502,7 @@ public static class TemplateCommands
var hiOption = new Option<double?>("--hi") { Description = "HiLo: high setpoint" };
var hiHiOption = new Option<double?>("--hihi") { Description = "HiLo: high-high setpoint" };
var expressionOption = new Option<string?>("--expression") { Description = "Expression: boolean trigger expression" };
// M9-T28b: analysis kind for Expression triggers (advisory|strict; default advisory).
// Analysis kind for Expression triggers (advisory|strict; default advisory).
// Writes "analysisKind":"Strict" into the trigger config when set to strict.
var triggerKindOption = new Option<string?>("--trigger-kind")
{
@@ -567,7 +567,7 @@ public static class TemplateCommands
var updateTriggerConfigOption = new Option<string?>("--trigger-config") { Description = "Trigger configuration JSON" };
var updateLockedOption = new Option<bool>("--locked") { Description = "Lock status" };
updateLockedOption.DefaultValueFactory = _ => false;
// M9-T28b: --trigger-kind for update (same semantics as add)
// --trigger-kind for update (same semantics as add)
var updateTriggerKindOption = new Option<string?>("--trigger-kind")
{
Description = AlarmTriggerKindOptionDescription
@@ -699,7 +699,7 @@ public static class TemplateCommands
var returnOption = new Option<string?>("--return-def") { Description = "Return definition JSON" };
var minTimeOption = new Option<string?>("--min-time-between-runs") { Description = MinTimeBetweenRunsOptionDescription };
var execTimeoutOption = new Option<int?>("--execution-timeout-seconds") { Description = ExecutionTimeoutOptionDescription };
// M9-T28b: analysis kind for Expression triggers (advisory|strict; default advisory).
// Analysis kind for Expression triggers (advisory|strict; default advisory).
var scriptTriggerKindOption = new Option<string?>("--trigger-kind")
{
Description = ScriptTriggerKindOptionDescription
@@ -758,7 +758,7 @@ public static class TemplateCommands
var updateReturnOption = new Option<string?>("--return-def") { Description = "Return definition JSON" };
var updateMinTimeOption = new Option<string?>("--min-time-between-runs") { Description = MinTimeBetweenRunsOptionDescription };
var updateExecTimeoutOption = new Option<int?>("--execution-timeout-seconds") { Description = ExecutionTimeoutOptionDescription };
// M9-T28b: --trigger-kind for update (same semantics as add)
// --trigger-kind for update (same semantics as add)
var updateScriptTriggerKindOption = new Option<string?>("--trigger-kind")
{
Description = ScriptTriggerKindOptionDescription
@@ -4,7 +4,7 @@ using System.Text.Json.Nodes;
namespace ZB.MOM.WW.ScadaBridge.CLI.Commands;
/// <summary>
/// Compact table projection for <c>template list</c> / <c>template get</c> (followup #6).
/// Compact table projection for <c>template list</c> / <c>template get</c>.
/// The management API returns full <c>Template</c> entities — every attribute, alarm,
/// script, and composition inline — which the generic table renderer dumps as one giant
/// cell per template (~171 KB for a real catalogue, unusable in a terminal). This
@@ -93,7 +93,7 @@ public class ManagementHttpClient : IDisposable
/// <summary>
/// Issues a plain HTTP <c>GET</c> against a REST endpoint (e.g. the audit
/// <c>/api/audit/query</c> endpoint introduced by Audit Log #23 M8) and returns the
/// <c>/api/audit/query</c> endpoint) and returns the
/// response body. Unlike <see cref="SendCommandAsync"/>, this does not wrap the call
/// in the <c>POST /management</c> command envelope — the audit endpoints are plain
/// REST resources. Authentication (HTTP Basic) and the base address are shared.
+1 -1
View File
@@ -41,7 +41,7 @@ rootCommand.SetAction(_ =>
Console.WriteLine("Use --help to see available commands.");
});
// Deprecation notice for the pre-M8 `audit-log` command name. The command itself
// Deprecation notice for the earlier `audit-log` command name. The command itself
// still works (it is an alias of `audit-config`), but using the old name emits a
// warning to stderr so scripts can be migrated.
AuditLogCommands.WriteDeprecationWarningIfNeeded(args, Console.Error);