Files
ScadaBridge/code-reviews/README.md
T
Joseph Doherty c1fe1c4f83 feat(audit): close AuditLog-001 — wire combined-telemetry dual-write transport
Closes the last open code-review finding. The unreachable
IngestCachedTelemetryAsync path now carries production cached-call
lifecycle traffic, delivering the design's "AuditLog + SiteCalls in one
MS SQL transaction" guarantee. Before this commit, the SiteCalls
operational half had NO production transport at all — central's
SiteCallAuditActor.OnUpsertAsync had zero producers, so cached-call
operational state never reached the central mirror.

Site-side partition (so neither path double-emits):
- ISiteAuditQueue.ReadPendingCachedTelemetryAsync — new method returning
  rows where Kind ∈ {CachedSubmit, ApiCallCached, DbWriteCached,
  CachedResolve} AND ForwardState = Pending.
- ISiteAuditQueue.ReadPendingAsync — XML doc updated, SQLite impl now
  filters Kind NOT IN the cached set so cached rows no longer ride the
  audit-only drain.

New cached-drain in SiteAuditTelemetryActor:
- Optional IOperationTrackingStore? ctor param (null on central
  composition roots — the cached scheduler is never armed there).
- Independent CachedDrain message + scheduler tick parallel to the
  existing Drain — a stall on one path can't block the other; shared
  lifecycle CTS gates both.
- OnCachedDrainAsync: reads cached audit rows, joins each with its
  matching SiteCallOperational snapshot via CorrelationId →
  TrackedOperationId from the tracking store, builds CachedTelemetryBatch,
  pushes via IngestCachedTelemetryAsync, marks ack'd rows Forwarded.
- Orphan rows (no tracking snapshot, thrown tracking-store call,
  missing CorrelationId) logged at Warning + skipped — they stay
  Pending so reconciliation/retry picks them up later. Best-effort
  contract preserved.

Central side: AuditLogIngestActor.OnCachedTelemetryAsync was already
implemented (M3 Bundle G dead code today, alive after this commit) —
performs InsertIfNotExists for AuditLog + UpsertAsync for SiteCalls
inside a BeginTransactionAsync. The handler is idempotent on EventId,
so any duplicate arrivals from concurrent push + reconciliation are
silent no-ops.

Composition root: AkkaHostedService now resolves IOperationTrackingStore
via GetService<>() (site-only) and threads it through the actor's
Props.Create.

Tests added (+3 in SiteAuditTelemetryActorTests):
- Cached rows route through the new transport, not the audit-only drain.
- Orphan cached row (no tracking match) is logged + skipped, drain
  doesn't crash.
- Ordinary audit rows still flow through the audit-only drain unchanged.
- ParentExecutionIdCorrelationTests now unions both queues to assert
  all expected Kinds remain covered after the partition.

Build clean; AuditLog.Tests 250/251 (the 1 fail is the pre-existing
date-sensitive PartitionPurgeTests integration flake explicitly accepted
across the session); SiteRuntime.Tests 302/302.

README regenerated: 0 pending of 481 total.

Session-final totals: 136 of 136 originally-open Theme findings closed
across 11 commits (10 themed batches + this architectural close).
2026-05-28 09:08:43 -04:00

4.5 KiB

Code Reviews

Comprehensive, per-module code reviews of the ScadaLink codebase. Each module (one buildable project under src/) has its own folder containing a findings.md. This README is the aggregated index — the single place to see all outstanding work.

Generated by regen-readme.py from the per-module findings.md files. Do not edit by hand — edit the findings files and re-run the script.

How it works

  • Reviews are performed one module at a time against a fixed checklist.
  • Every finding is recorded in the module's findings.md with a severity and status.
  • Findings are never deleted — they are closed by changing their status, keeping a full audit trail.
  • This README aggregates every pending finding (Open / In Progress) across all modules.

See REVIEW-PROCESS.md for the full procedure: the review checklist, severity definitions, finding format, and how to mark items resolved.

Layout

code-reviews/
├── README.md            # this file — process overview + pending findings
├── REVIEW-PROCESS.md     # how to perform a review and track findings
├── regen-readme.py       # regenerates this README from the findings files
├── _template/findings.md # copy-this template for a module review
└── <Module>/findings.md  # one folder per src/ project

Baseline review — 2026-05-16

All 19 modules were reviewed at commit 9c60592 (241 findings: 6 Critical, 46 High, 100 Medium, 89 Low). The tables below track what remains open as findings are resolved and re-triaged; findings discovered after the baseline are appended to their module file and counted in Total.

Severity Open findings
Critical 0
High 0
Medium 0
Low 0
Total 0

Module Status

Module Last reviewed Commit Open (C/H/M/L) Open Total
AuditLog 2026-05-28 1eb6e97 0/0/0/0 0 11
CLI 2026-05-28 1eb6e97 0/0/0/0 0 23
CentralUI 2026-05-28 1eb6e97 0/0/0/0 0 33
ClusterInfrastructure 2026-05-28 1eb6e97 0/0/0/0 0 14
Commons 2026-05-28 1eb6e97 0/0/0/0 0 23
Communication 2026-05-28 1eb6e97 0/0/0/0 0 22
ConfigurationDatabase 2026-05-28 1eb6e97 0/0/0/0 0 24
DataConnectionLayer 2026-05-28 1eb6e97 0/0/0/0 0 22
DeploymentManager 2026-05-28 1eb6e97 0/0/0/0 0 24
ExternalSystemGateway 2026-05-28 1eb6e97 0/0/0/0 0 23
HealthMonitoring 2026-05-28 1eb6e97 0/0/0/0 0 23
Host 2026-05-28 1eb6e97 0/0/0/0 0 22
InboundAPI 2026-05-28 1eb6e97 0/0/0/0 0 25
ManagementService 2026-05-28 1eb6e97 0/0/0/0 0 23
NotificationOutbox 2026-05-28 1eb6e97 0/0/0/0 0 10
NotificationService 2026-05-28 1eb6e97 0/0/0/0 0 25
Security 2026-05-28 1eb6e97 0/0/0/0 0 21
SiteCallAudit 2026-05-28 1eb6e97 0/0/0/0 0 6
SiteEventLogging 2026-05-28 1eb6e97 0/0/0/0 0 23
SiteRuntime 2026-05-28 1eb6e97 0/0/0/0 0 26
StoreAndForward 2026-05-28 1eb6e97 0/0/0/0 0 24
TemplateEngine 2026-05-28 1eb6e97 0/0/0/0 0 22
Transport 2026-05-28 1eb6e97 0/0/0/0 0 12

Pending Findings

Every Open / In Progress finding across all modules, highest severity first. Resolved findings drop off this list but remain recorded in their module's findings.md (see REVIEW-PROCESS.md §4–§5). Full detail — description, location, recommendation — lives in the module's findings.md.

Critical (0)

None open.

High (0)

None open.

Medium (0)

None open.

Low (0)

None open.