docs: fill missing XML docs and strip tracking IDs from src comments

Clears CommentChecker findings in src/ (3,280 -> 209, the remainder being false
positives like PLC-5/IEEE-754/M0.0) by adding missing summaries/params/returns,
normalising inheritdoc usage, and removing Gitea/review tracking IDs while keeping
the rationale they annotated. Comment-only: comment-stripped sources are identical
to the parent commit.
This commit is contained in:
Joseph Doherty
2026-10-15 06:14:58 -04:00
parent ebcbd81fca
commit 826312befe
430 changed files with 4434 additions and 3923 deletions
@@ -106,8 +106,8 @@ public static class Part9StateMachine
if (current.Acked == AlarmAckedState.Acknowledged)
{
// A COMMENTED re-ack carries a real comment even though nothing is acknowledged (Gitea #597 review
// m1): the OPC UA node reports it — the SDK writes the comment on a re-ack — so the system of
// A COMMENTED re-ack carries a real comment even though nothing is acknowledged (review
// finding m1): the OPC UA node reports it — the SDK writes the comment on a re-ack — so the system of
// record must hold it too, or the event advertises a comment that exists only on the node that
// served the call (never persisted, never replicated to the pair peer). Recorded exactly like
// AddComment; the ack fields (LastAck*) stay those of the real acknowledge. An uncommented re-ack
@@ -387,7 +387,7 @@ public enum EmissionKind
Enabled,
Disabled,
CommentAdded,
/// <summary>#478 — the worst-of-input source quality changed bucket (Good/Uncertain/Bad) with no
/// <summary>The worst-of-input source quality changed bucket (Good/Uncertain/Bad) with no
/// accompanying Part 9 state transition. Delivered out of band via the dedicated
/// <c>WriteAlarmQuality</c> node path, never through the <c>IAlarmSource</c> fan-out (it is not a
/// state change and must not materialize or historize a condition).</summary>
@@ -97,7 +97,7 @@ public sealed class ScriptedAlarmEngine : IDisposable
new(StringComparer.Ordinal);
/// <summary>
/// #478 — last emitted worst-of-input quality bucket per alarm (0 = Good, 1 = Uncertain,
/// Last emitted worst-of-input quality bucket per alarm (0 = Good, 1 = Uncertain,
/// 2 = Bad), computed each evaluation over the refilled read cache. A change in this bucket
/// with no accompanying Part 9 state transition drives a standalone
/// <see cref="EmissionKind.QualityChanged"/> emission (a Bad input freezes the condition — no
@@ -384,7 +384,7 @@ public sealed class ScriptedAlarmEngine : IDisposable
=> _alarms.Values.Select(a => a.Condition).ToArray();
/// <summary>
/// #487 — the currently-held condition of every loaded alarm, packaged with the definition's
/// The currently-held condition of every loaded alarm, packaged with the definition's
/// severity, the rendered message template and the last-observed input quality, i.e. everything
/// a caller needs to <b>project</b> the alarm onto an OPC UA condition node without waiting for
/// the next transition.
@@ -740,7 +740,7 @@ public sealed class ScriptedAlarmEngine : IDisposable
_ => new AlarmScratch(state.Inputs, state.Logger, _clock));
RefillReadCache(scratch.ReadCache, state.Inputs);
// #478 — worst OPC UA quality across the alarm's inputs, computed BEFORE the readiness
// Worst OPC UA quality across the alarm's inputs, computed BEFORE the readiness
// short-circuit so an outright-Bad input is still observed. A bucket change with no state
// transition is delivered out of band as a QualityChanged emission (see below).
var worstStatus = WorstInputStatus(scratch.ReadCache);
@@ -881,13 +881,13 @@ public sealed class ScriptedAlarmEngine : IDisposable
// adapter honors it to suppress ONLY the durable sink write; the live alerts fan-out is
// unaffected (it is not gated on this flag).
HistorizeToAveva: state.Definition.HistorizeToAveva,
// #478 — the worst input quality at evaluation time rides the transition so the projected
// The worst input quality at evaluation time rides the transition so the projected
// full snapshot keeps quality consistent (no clobber-to-Good).
WorstInputStatusCode: worstInputStatus);
}
/// <summary>
/// #478 — build a standalone <see cref="EmissionKind.QualityChanged"/> event carrying the new
/// Build a standalone <see cref="EmissionKind.QualityChanged"/> event carrying the new
/// worst-of-input quality. Emitted when the quality bucket moved but no Part 9 transition fired
/// (a Bad input freezes the condition; a Suppressed/None transition also leaves state unchanged).
/// The host routes it to the dedicated <c>WriteAlarmQuality</c> node path (annotate quality only,
@@ -913,14 +913,14 @@ public sealed class ScriptedAlarmEngine : IDisposable
/// the <see cref="AreInputsReady"/> guard already handles by holding the condition. Counting it would
/// flash every scripted condition Bad at deploy until the first push and flood the quality path with
/// load-time annotations, so it is skipped (contributes Good). Empty / all-unpushed cache ⇒ Good (0).
/// <para><b>"Never pushed" is a specific status code, not "the value is null" (#481, closing #478
/// Finding 3).</b> This used to skip every entry whose value was null, which made a genuine runtime Bad
/// <para><b>"Never pushed" is a specific status code, not "the value is null"
/// (Finding 3).</b> This used to skip every entry whose value was null, which made a genuine runtime Bad
/// indistinguishable from cold start — and that is exactly the shape a comms-lost driver produces, so
/// the case the skip was hiding was the case that matters most. The upstream source now stamps a
/// never-pushed path <see cref="StatusNeverPushed"/> and nothing else does, so the two are tellable
/// apart. A null snapshot is still skipped: that is a cache the refill did not populate, not an
/// observation.</para>
/// <para><b>The comparison itself lives in <see cref="InputQuality.WorstOf"/></b> (archreview R3-02)
/// <para><b>The comparison itself lives in <see cref="InputQuality.WorstOf"/></b>
/// — the same rule the virtual-tag and Calculation seams now use, so "worst input wins, carrying its
/// sub-code, first-seen on a severity tie" is stated once. What stays here is the alarm-specific
/// <em>filter</em>: this engine's two skips are deliberately NOT part of the shared rule, because the
@@ -952,7 +952,7 @@ public sealed class ScriptedAlarmEngine : IDisposable
return severity >= 2 ? 2 : (int)severity;
}
/// <summary>#478 — a canonical worst StatusCode for an alarm's last-observed quality bucket, used by
/// <summary>A canonical worst StatusCode for an alarm's last-observed quality bucket, used by
/// the operator-command + shelving-timer emission paths (which don't re-read inputs) so an ack /
/// shelve while an input is Bad still carries Bad rather than resetting the condition to Good.</summary>
private uint LastWorstStatus(string alarmId)
@@ -1264,14 +1264,14 @@ public sealed record ScriptedAlarmEvent(
DateTime TimestampUtc,
string? Comment = null,
bool HistorizeToAveva = true,
// #478 — the worst OPC UA StatusCode across the alarm's input tags at evaluation time. A raw uint,
// since Core.ScriptedAlarms does not reference Commons. Since #519 the host carries it to the condition
// The worst OPC UA StatusCode across the alarm's input tags at evaluation time. A raw uint,
// since Core.ScriptedAlarms does not reference Commons. The host carries it to the condition
// node UNCHANGED — it used to be collapsed to a 3-state bucket and re-expanded, losing the sub-code.
// Default 0u == Good keeps every existing constructor call unchanged.
uint WorstInputStatusCode = 0u);
/// <summary>
/// #487 — a loaded alarm's current condition, ready to be projected onto its OPC UA node.
/// A loaded alarm's current condition, ready to be projected onto its OPC UA node.
/// Produced by <see cref="ScriptedAlarmEngine.GetProjections"/> on demand; it is <b>not</b> an
/// emission and never travels the <see cref="ScriptedAlarmEngine.OnEvent"/> path, so it can never
/// become an <c>alerts</c> row or a historian record. Deliberately a separate type from
@@ -81,7 +81,7 @@ public sealed class ScriptedAlarmSource : IAlarmSource, IDisposable
{
if (_disposed) return;
// #478 — QualityChanged is a source-quality annotation, not a Part 9 state change. It is delivered
// QualityChanged is a source-quality annotation, not a Part 9 state change. It is delivered
// out of band via the dedicated WriteAlarmQuality node path; surfacing it here would fabricate a
// phantom AlarmEventArgs that materializes / historizes a condition. Swallow it.
if (evt.Emission == EmissionKind.QualityChanged) return;