- Add HistorianGateway to the Runtime/implementation table (single-process .NET 10 x64 gRPC sidecar; no COM/x86; 584 tests; local only, not yet pushed to gitea) - Update "What this repository is" count (five → six pieces of source; add GalaxyRepository) - Add HistorianGateway paragraph to Cross-project relationships / Net effect (independent sidecar; no runtime coupling to the other three; depends on shared GalaxyRepository lib via ProjectReference) - Add ZB.MOM.WW.GalaxyRepository row to Component normalization table + full description paragraph (built 0.1.0; consumed by HistorianGateway; mxaccessgw adoption is a follow-on; not yet published to Gitea feed) - Add HistorianGateway primary commands block (build/test/run/live-integration) - Extend Shared GLAuth note to cover HistorianGateway
29 KiB
CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
What this repository is
scadaproj is primarily an umbrella/index workspace that aggregates a family of
related SCADA / OT / Wonderware / OPC UA "sister projects" that live as sibling
directories under ~/Desktop/. It now also hosts six pieces of source itself —
the shared ZB.MOM.WW.Auth/ library, the shared
ZB.MOM.WW.Theme/ UI kit, the shared
ZB.MOM.WW.Health/ health-check library, the shared
ZB.MOM.WW.Telemetry/ observability library, the shared
ZB.MOM.WW.Configuration/ config-validation library, and the new
ZB.MOM.WW.GalaxyRepository/ Galaxy browse library — all the realized output of their
respective component normalizations (see Component normalization).
The point of this file is to give a high-level scan of each sister project — its purpose,
location, stack, and primary commands — so a fresh Claude Code session can orient across
the whole family without opening each repo first.
Each sister project keeps its own authoritative CLAUDE.md. This index is a
summary of those files; when you actually work in a project, open that project's
own CLAUDE.md for the full picture. See Refreshing this index.
The project list below is curated manually. Add or remove entries as the family changes — do not assume every directory under
~/Desktop/belongs here.
Sister projects (core SCADA/OT family)
Runtime / implementation (active code)
| Project | Location | Stack | Repo | Summary |
|---|---|---|---|---|
| OtOpcUa | ~/Desktop/OtOpcUa |
.NET 10, OPC UA, gRPC | gitea.dohertylan.com/dohertj2/lmxopcua |
OPC UA server that exposes industrial data sources under a unified Equipment-based address space — native-protocol drivers (Modbus, S7, AB CIP/Legacy, TwinCAT, FOCAS, OpcUaClient) and AVEVA System Platform (Wonderware) Galaxy, now a standard Equipment-kind driver (the old SystemPlatform mirror / alias-tag model was retired ~2026-06-12). Galaxy access flows through the in-process GalaxyDriver → gRPC → the mxaccessgw gateway. Surfaces live read + authorized write, native OPC UA Part 9 alarms, and server-side HistoryRead. |
MxAccessGateway (mxaccessgw) |
~/Desktop/MxAccessGateway |
.NET 10 gateway (x64) + .NET 4.8 worker (x86), gRPC | gitea.dohertylan.com/dohertj2/mxaccessgw |
gRPC gateway giving modern clients full MXAccess parity without loading 32-bit COM. Two-process: gateway (ASP.NET Core gRPC + Blazor dashboard) + per-session x86 worker that owns the MXAccess COM STA. OtOpcUa depends on this. |
| ScadaBridge | ~/Desktop/ScadaBridge |
.NET 10, Akka.NET, Docker | git | Full implementation of the distributed SCADA platform — hub-and-spoke (1 central cluster + N site clusters). Projects prefixed ZB.MOM.WW.ScadaBridge.*; solution ZB.MOM.WW.ScadaBridge.slnx. Ships src/, tests/, docker/ topology, and the design docs that are the spec. |
| HistorianGateway | ~/Desktop/HistorianGateway |
.NET 10 x64, gRPC, Blazor | local only (not yet pushed to gitea) | Single-process gRPC sidecar exposing (1) full read/write API to the AVEVA Historian (5 gRPC services; 15 retrieval modes; historical/backfill writes; tag-config lifecycle; SQL live-value path; store-forward + redundancy resilience; all default-disabled) and (2) read-only Galaxy object-hierarchy browse via the new shared ZB.MOM.WW.GalaxyRepository lib. No COM, no x86 worker. Dashboard on :5220 (HTTP/1.1); gRPC h2c on :5221. Vendors AVEVA.Historian.Client from histsdk. 584 tests green. |
Cross-project relationships
The three indexed projects are separate repos and separate processes, coupled at
runtime over wire protocols (gRPC + OPC UA) — not by project/compile references. They
share the ZB.MOM.WW.* product namespace (ZB.MOM.WW.OtOpcUa.*, ZB.MOM.WW.ScadaBridge.*;
the gateway uses MxGateway.*). The common subject is AVEVA System Platform (Wonderware)
"Galaxy" data, and mxaccessgw is the linchpin that the other two connect through.
Data flow
AVEVA System Platform — Wonderware "Galaxy"
(OT source of truth: runtime tags + Galaxy Repository SQL DB)
▲
│ MXAccess COM (32-bit, STA message pump)
│
┌────────────────┴─────────────────┐
│ MxAccessGateway (mxaccessgw) │ gateway x64 .NET10 + worker x86 net48
│ gRPC service; OWNS the 32-bit │ protos: mxaccess_gateway / mxaccess_worker
│ COM bitness + STA pump │ / galaxy_repository
└──────┬─────────────────────┬──────┘
gRPC (MxCommand/MxEvent + │ gRPC (ScadaBridge "MxGateway" adapter:
GalaxyRepository browse) │ native MxAccess data + A&C alarms)
│ │
┌─────┴──────┐ │
│ OtOpcUa │ GalaxyDriver maps │
│ OPC UA srv │ Galaxy hierarchy → │
│ (.NET 10) │ OPC UA addr space │
└─────┬──────┘ │
│ OPC UA (opc.tcp; data + A&C alarms)
▼ ▼
┌──────────────────────────────────────────────┐
│ ScadaBridge — Data Connection Layer (DCL) │
│ OPC UA adapter │ MxGateway adapter │ custom │
└─────────────────────────┬────────────────────┘
▼
Instance Actors → site clusters → central cluster / UI
Edge-by-edge
- MxAccessGateway is the foundation. It is the only component that loads 32-bit MXAccess COM (its x86 net48 worker owns the COM apartment + STA pump). It exposes that to modern x64/.NET-10 callers over gRPC, and also serves Galaxy Repository SQL browse RPCs. This is why the other two exist as .NET 10 / x64 and never touch COM directly.
- OtOpcUa → MxAccessGateway (gRPC client). OtOpcUa's in-process
GalaxyDriver(src/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Galaxy/) uses two gateway channels: theGalaxyRepositoryClientfor the static hierarchy, and an MXAccess session (MxCommand/MxEventprotos) for live read/write/subscribe. ADeployWatcherpolls the gateway's deploy-event signal to rebuild the OPC UA address space on Galaxy redeploy. OtOpcUa's job is a protocol bridge: it republishes Galaxy — now bound as a standard Equipment-kind driver alongside its native-protocol drivers, not a special SystemPlatform mirror — as an OPC UA address space (live values, Part 9 alarms, HistoryRead) for any OPC UA client. - ScadaBridge → OPC UA (OPC UA client). ScadaBridge's DCL has an OPC UA adapter that collects data and mirrors native OPC UA Alarms & Conditions. OtOpcUa is exactly such a server, so ScadaBridge can ingest Wonderware data indirectly via OtOpcUa.
- ScadaBridge → MxAccessGateway (gRPC client). The DCL also has a dedicated
MxGateway adapter that talks to
mxaccessgwdirectly for native MxAccess data and alarms — so ScadaBridge can reach Wonderware data directly, bypassing OtOpcUa. Both adapters implement the sameIAlarmSubscribableConnectionseam, and a read-onlyNativeAlarmActorunifies OPC-UA-A&C and MxAccess alarms onto one condition model.
Net effect
mxaccessgwis a shared dependency of both OtOpcUa and ScadaBridge.- ScadaBridge has two paths to the same Wonderware data: (1) OPC UA → OtOpcUa → gateway, or (2) MxGateway adapter → gateway directly. Path 1 gives standards-based OPC UA decoupling; path 2 gives a more direct/native feed.
- HistorianGateway is a new, independent sidecar (no runtime coupling to the three above).
It reaches the Historian via its vendored gRPC client and the Galaxy Repository SQL DB directly,
not through
mxaccessgw. It consumes the sharedZB.MOM.WW.GalaxyRepositorylib (cross-repoProjectReference). Any client that needs Historian data or Galaxy browse can target HistorianGateway independently; it is not a dependency of OtOpcUa or ScadaBridge today. - Coupling is loose: each repo references the others only as sibling context (the
## Sister Projectsnote in ScadaBridge's ownCLAUDE.mdlistsMxAccessGatewayandOtOpcUawith their Gitea URLs but states they are not part of its solution). - The break surface is the wire contracts, not code. Because coupling is by network
protocol, the things that break across repo boundaries are: the gateway's
.protofiles (mxaccess_gateway.proto,mxaccess_worker.proto,galaxy_repository.proto), thehistorian_gateway.v1proto (HistorianGateway's own contract), and the OPC UA address-space shape OtOpcUa publishes (browse paths, node IDs, A&C alarm model). Changes to any of these must be coordinated across the affected repos — a green build in one repo does not prove the others still interoperate.
Component normalization
Because the sister repos re-implement the same cross-cutting concerns separately and drift
apart, components/ normalizes them: per component, the one target spec,
each project's code-verified current state, and the gaps between. See
components/README.md for the convention and workflow.
| Component | Status | Goal | Design | Implementation |
|---|---|---|---|---|
| Auth (login / identity / authz) | Adopted (lib 0.1.3; all 3 apps, merged to local default main/master + pushed to origin (gitea)) |
Shared ZB.MOM.WW.Auth lib |
components/auth/ |
ZB.MOM.WW.Auth/ |
| UI Theme (layout / tokens / components) | Adopted (lib 0.2.0; all 3 apps, merged to local default + pushed to origin (gitea)) |
Shared ZB.MOM.WW.Theme RCL |
components/ui-theme/ |
ZB.MOM.WW.Theme/ |
| Health (readiness / liveness / active-node) | Built (lib 0.1.0) |
Shared ZB.MOM.WW.Health lib |
components/health/ |
ZB.MOM.WW.Health/ |
| Observability (metrics / traces / logs) | Built (lib 0.1.0) |
Shared ZB.MOM.WW.Telemetry lib + .Serilog |
components/observability/ |
ZB.MOM.WW.Telemetry/ |
| Config + validation (options / startup validation) | Adopted (lib 0.1.0; all 3 apps, local) |
Shared ZB.MOM.WW.Configuration lib |
components/configuration/ |
ZB.MOM.WW.Configuration/ |
| Audit (event model + writer seam) | Adopted (lib 0.1.0; all 3 apps, merged to local default main/master + pushed to origin (gitea)) |
Shared ZB.MOM.WW.Audit lib |
components/audit/ |
ZB.MOM.WW.Audit/ |
| Galaxy Repository (object-hierarchy SQL browse + gRPC service) | Built (lib 0.1.0; consumed by HistorianGateway via ProjectReference) |
Shared ZB.MOM.WW.GalaxyRepository lib |
(design in histsdk + design doc 2026-06-23) | ZB.MOM.WW.GalaxyRepository/ |
The auth component is fully populated: a normalized spec, a
proposed shared-contract, three
current-state docs, and an adoption GAPS
backlog. Common ground = LDAP/GLAuth identity + peppered-HMAC API keys; left per-project =
the authz vocabularies (OPC-UA permissions / gRPC scopes / roles + site-scoping).
The shared library is built and lives in this repo at ZB.MOM.WW.Auth/
(its own nested git repo; .NET 10; 4 packages — Abstractions, Ldap, ApiKeys, AspNetCore;
172 tests; dotnet pack → 4 nupkgs @ 0.1.0). The implementation plan is at
docs/plans/2026-06-01-zb-mom-ww-auth-shared-library.md.
Adopted across all three apps on 2026-06-02 (auth GAPS #1–#8) on each repo's feat/adopt-zb-auth branch —
committed + reviewed, then fast-forward-merged into the repo's local default (main/master) and PUSHED to origin
(gitea) on 2026-06-03 (in sync; the feat/* branches kept locally as history). Cutover: shared Auth.Ldap,
Auth.ApiKeys (ScadaBridge inbound fully re-architected to the keyId/Bearer model), IGroupRoleMapper<TRole> seam,
Transport-enum config, canonical ZbClaimTypes/ZbCookieDefaults, unified dev base DN dc=zb,dc=local, and the
canonical-six role vocabulary (with ScadaBridge's accepted auditor/admin SoD collapse). Consumer pins: OtOpcUa 0.1.1,
MxGateway 0.1.2, ScadaBridge 0.1.3. Per-repo detail in components/auth/GAPS.md +
docs/plans/2026-06-02-auth-audit-normalization*.md.
Build/test from ZB.MOM.WW.Auth/: dotnet test. Consumer matrix: OtOpcUa → Abstractions+Ldap+AspNetCore;
MxAccessGateway & ScadaBridge → all four (ApiKeys not used by OtOpcUa).
The UI-theme component is fully populated: a normalized spec,
a design-tokens reference, a
shared-contract, three
current-state docs, and an adoption GAPS
backlog. Shared = Technical-Light tokens + IBM Plex fonts + side-rail shell + widgets; left
per-project = each app's site.css page layout, route content, scoped .razor.css.
The shared RCL is built and lives in this repo at ZB.MOM.WW.Theme/
(.NET 10 Razor Class Library; single package; 44 bUnit tests; dotnet pack → 1 nupkg @ 0.2.0,
published to the Gitea feed). The build plan is at
docs/plans/2026-06-01-zb-mom-ww-theme-shared-library.md;
the adoption plan at docs/plans/2026-06-03-ui-theme-adoption.md.
Adopted across all three apps on 2026-06-03 (full canonical cutover, SPEC §7) on each repo's
feat/adopt-zb-theme branch — committed + spec/code-reviewed, then fast-forward-merged into each repo's local
default (master/main) and PUSHED to origin (gitea) (in sync; feat/* kept locally as history): OtOpcUa
→lmxopcua master@11de14d, ScadaBridge main@58352a6, MxGateway→mxaccessgw main@73e54e2. The 0.1.0 → 0.2.0 bump first promoted nav-expand persistence
into the kit (NavRailSection.Key/data-nav-key + a localStorage nav-state.js enhancer emitted by a new
<ThemeScripts/>), so all three apps share one persistence mechanism (OtOpcUa's bespoke cookie/JS-interop nav
island retired); MxGateway additionally gained a net-new Blazor <LoginCard> /login page over its existing
hardened endpoint. Per-app result in components/ui-theme/GAPS.md.
Build/test from ZB.MOM.WW.Theme/: dotnet test. Consumer matrix: all three apps consume
the single ZB.MOM.WW.Theme package (OtOpcUa AdminUI, MxGateway Server, ScadaBridge Host + CentralUI).
The health component is fully populated: a normalized spec, a
shared-contract, three
current-state docs, and an adoption GAPS
backlog. Shared = three-tier endpoint convention (ready/active/healthz) + canonical JSON writer +
IActiveNodeGate seam + GrpcDependencyHealthCheck + AkkaClusterHealthCheck + ActiveNodeHealthCheck
DatabaseHealthCheck<TContext>; left per-project = which probes each app registers, orchestrator wiring, and ScadaBridge's distributed health-monitoring pipeline.
The shared library is built and lives in this repo at ZB.MOM.WW.Health/
(.NET 10; 3 packages — ZB.MOM.WW.Health, ZB.MOM.WW.Health.Akka, ZB.MOM.WW.Health.EntityFrameworkCore;
58 tests; dotnet pack → 3 nupkgs @ 0.1.0).
Not yet adopted by the three apps — that's the follow-on tracked in components/health/GAPS.md.
Build/test from ZB.MOM.WW.Health/: dotnet test. Consumer matrix: MxAccessGateway → core only;
OtOpcUa & ScadaBridge → all three packages.
The observability component is fully populated: a normalized spec,
a metric-conventions reference, a
shared-contract, three
current-state docs, and an adoption GAPS
backlog. Shared = OTel Resource (service.name/site.id/node.role identity triple) + standard instrumentation
(ASP.NET Core, HttpClient, gRPC client, runtime, process) + Prometheus always-on exporter + OTLP opt-in
- Serilog two-stage bootstrap + SiteId/NodeRole/NodeHostname enrichers + TraceContextEnricher (trace_id/span_id)
- ILogRedactor seam; left per-project = application Meters/ActivitySources, sink config, per-operation enrichers, and redaction policies.
The shared library is built and lives in this repo at ZB.MOM.WW.Telemetry/
(.NET 10; 2 packages — ZB.MOM.WW.Telemetry, ZB.MOM.WW.Telemetry.Serilog; 19 tests;
dotnet pack → 2 nupkgs @ 0.1.0). Adopted across all three apps on 2026-06-01 (branch
feat/adopt-zb-telemetry per repo, behaviour-preserving): AddZbTelemetry (Resource + standard
instrumentation + Prometheus /metrics) everywhere; OtOpcUa + MxGateway on AddZbSerilog (MxGateway's
MEL→Serilog migration + metrics export both landed in this pass — they were not actually done
beforehand despite an earlier claim); ScadaBridge keeps its LoggerConfigurationFactory (min-level
governance) and only adds the shared TraceContextEnricher. Deferred: MxGateway ms→s + Meter
rename, ScadaBridge app instruments + Site-node HTTP/1.1 metrics listener, OTLP wiring. Per-repo
result tracked in components/observability/GAPS.md.
Build/test from ZB.MOM.WW.Telemetry/: dotnet test. Consumer matrix: all three apps consume both
packages after adoption (OtOpcUa, MxGateway Server, ScadaBridge Host + any instrumented project).
The configuration component is fully populated: a normalized spec, a
shared-contract, three
current-state docs, and an adoption GAPS
backlog. Shared = the IValidateOptions<T> failure-accumulation base (OptionsValidatorBase<T>) +
reusable rule primitives (ValidationBuilder: port / host:port / required / positive-duration / one-of /
min-count) + AddValidatedOptions<TOptions,TValidator>() (bind + validate + ValidateOnStart) + the
pre-host ConfigPreflight aggregator (generalizes ScadaBridge's StartupValidator, byte-compatible
message); left per-project = each app's options classes + domain rules, and OtOpcUa's
draft/generation-content validation (DB-side sp_ValidateDraft; its C# DraftValidator is dormant).
The shared library is built and lives in this repo at ZB.MOM.WW.Configuration/
(.NET 10; single package ZB.MOM.WW.Configuration; 27 tests; dotnet pack → 1 nupkg @ 0.1.0).
The implementation plan is at
docs/plans/2026-06-01-zb-mom-ww-configuration-shared-library.md.
Adopted across all three apps on 2026-06-01 (OtOpcUa, MxAccessGateway, ScadaBridge) on each repo's
local default branch (main/master) — merged, not yet pushed to remotes; the package was first
published to the Gitea feed. Behaviour-preserving onto OptionsValidatorBase/AddValidatedOptions
for MxGateway + ScadaBridge (validator messages byte-identical), StartupValidator → ConfigPreflight
for ScadaBridge, and net-new Ldap/OpcUa validators for OtOpcUa. Per-app result tracked in
components/configuration/GAPS.md.
Build/test from ZB.MOM.WW.Configuration/: dotnet test. Consumer matrix: all three apps consume the
single package; ScadaBridge is the heaviest adopter (per-module validators + StartupValidator →
ConfigPreflight); OtOpcUa adoption is additive (it has no IValidateOptions usage today).
The audit component is fully populated: a normalized spec, an
event-model reference, a
shared-contract, three
current-state docs, and an adoption GAPS
backlog. Common ground = canonical AuditEvent record + AuditOutcome enum + IAuditWriter /
IAuditRedactor seams + helpers (NullAuditRedactor, TruncatingAuditRedactor, NoOpAuditWriter,
CompositeAuditWriter, RedactingAuditWriter) + AddZbAudit DI registration; left per-project =
transport/storage and domain vocabulary. Closes the loop on Auth — audit's Actor field = the Auth
principal. IAuditRedactor is aligned with Telemetry's ILogRedactor seam convention.
The shared library is built and lives in this repo at ZB.MOM.WW.Audit/
(.NET 10; 1 package — ZB.MOM.WW.Audit; only non-BCL dependency Microsoft.Extensions.DependencyInjection.Abstractions;
19 tests; dotnet pack → 1 nupkg @ 0.1.0). Repo: https://gitea.dohertylan.com/dohertj2/zb-mom-ww-audit.
Adopted across all three apps on 2026-06-02 (audit GAPS #1–#6) on each repo's feat/adopt-zb-audit branch
(stacked on feat/adopt-zb-auth) — committed + reviewed, then merged into the repo's local default (main/master)
and PUSHED to origin (gitea) on 2026-06-03 (in sync). Depth =
DEEP adopt (the canonical 9-field AuditEvent is the record everywhere; domain fields ride in DetailsJson).
OtOpcUa: canonical record + AuditWriterActor : IAuditWriter + Outcome column/migration + ClusterAudit fix.
MxGateway: new canonical SQLite audit_event store + IAuditWriter + IApiKeyAuditStore→canonical adapter.
ScadaBridge: a full audit-subsystem re-architecture (the program's largest task) — canonical record everywhere via a
deterministic codec; site SQLite split into audit_event + an audit_forward_state forwarding sidecar; central
partitioned dbo.AuditLog collapsed to 10 canonical cols + persisted computed cols (CollapseAuditLogToCanonical
migration, MSSQL-verified). Phase 3 wires Actor from the Auth principal at authenticated emit sites (per-app
IAuditActorAccessor). Per-repo detail in components/audit/GAPS.md +
docs/plans/2026-06-02-auth-audit-normalization-phase2-deep.md + …-scadabridge-audit-rearch.md.
Build/test from ZB.MOM.WW.Audit/: dotnet test. Consumer matrix: all three apps consume the single
ZB.MOM.WW.Audit package (OtOpcUa, MxAccessGateway, ScadaBridge — DEEP-adopted as the canonical record).
The Galaxy Repository component normalizes the Galaxy object-hierarchy SQL browse + reusable gRPC service
that was previously embedded in mxaccessgw. Shared = canonical galaxy_repository.v1 proto (wire-compatible
with mxaccessgw's existing contract so OtOpcUa's GalaxyRepositoryClient is unaffected), the SQL browse
provider (HierarchySql / AttributesSql validated reverse-engineered queries), in-memory hierarchy cache +
snapshot + deploy-poll refresh BackgroundService, GalaxyHierarchyProjector, and AddZbGalaxyRepository /
MapZbGalaxyRepository DI extension. Left per-consumer = section path, subtree auth filtering, and any
app-specific paging defaults.
The shared library is built and lives in this repo at ZB.MOM.WW.GalaxyRepository/
(.NET 10; single package ZB.MOM.WW.GalaxyRepository; dotnet pack → 1 nupkg @ 0.1.0, locally built,
NOT yet published to the Gitea feed). The design doc is at
docs/plans/2026-06-23-historian-gateway-design.md (§10, component 1).
Consumed by HistorianGateway from the start (via cross-repo ProjectReference to this scadaproj tree).
mxaccessgw adoption is a tracked follow-on — once adopted, mxaccessgw's inline Galaxy browse code is replaced
by the shared lib (the galaxy_repository.v1 wire contract is already identical, so OtOpcUa and ScadaBridge
clients are unaffected). Build/test from ZB.MOM.WW.GalaxyRepository/: dotnet test.
Consumer matrix: HistorianGateway (initial); mxaccessgw (follow-on adoption).
Per-project primary commands
Run these from inside each project directory (not from scadaproj).
# OtOpcUa
dotnet build ZB.MOM.WW.OtOpcUa.slnx
dotnet test ZB.MOM.WW.OtOpcUa.slnx
dotnet test --filter "FullyQualifiedName~MyTestClass.MyMethod" # single test
# Docker fixtures run on shared host 10.100.0.35; control via `lmxopcua-fix` (in ~/bin)
# MxAccessGateway (PowerShell on Windows)
dotnet build src/MxGateway.sln
dotnet build src/MxGateway.Worker/MxGateway.Worker.csproj -p:Platform=x86 # worker MUST be x86
dotnet test src/MxGateway.Tests/MxGateway.Tests.csproj # no MXAccess needed (fake worker)
dotnet run --project src/MxGateway.Server/MxGateway.Server.csproj
# ScadaBridge (~/Desktop/ScadaBridge)
dotnet build ZB.MOM.WW.ScadaBridge.slnx
bash docker/deploy.sh # rebuild + redeploy the 8-node cluster
cd infra && docker compose up -d # local test services (SQL, OPC UA, SMTP, REST, Traefik) — LDAP is NOT here
# HistorianGateway (~/Desktop/HistorianGateway)
dotnet build ZB.MOM.WW.HistorianGateway.slnx
dotnet test ZB.MOM.WW.HistorianGateway.slnx # unit + golden; live integration tests skip without env vars
dotnet run --project src/ZB.MOM.WW.HistorianGateway.Server/ZB.MOM.WW.HistorianGateway.Server.csproj
# dashboard on :5220, gRPC h2c on :5221
# Live integration (need HISTORIAN_GRPC_HOST + HISTORIAN_GRPC_WRITE_SANDBOX_TAG + GALAXY_SQL_CONNSTR set)
dotnet test ZB.MOM.WW.HistorianGateway.slnx --filter "Category=LiveIntegration"
Shared GLAuth (all three apps + HistorianGateway): LDAP auth for every local dev/test stack is provided by a single
zb-shared-glauthcontainer on the Linux fixture host10.100.0.35:3893(baseDN dc=zb,dc=local, Transport=None). Source of truth and deploy runbook:scadaproj/infra/glauth/(config.toml+docker-compose.yml+README.md).
Refreshing this index
This file is meant to be re-scanned when scadaproj is opened in Claude Code:
- List sibling SCADA/OT directories:
find ~/Desktop -maxdepth 2 -iname "claude.md". - For each project the user wants indexed, read the top of its
CLAUDE.md(project overview + build/run sections) and update its row above. - Keep the project set curated — only the SCADA/OT/Wonderware/OPC-UA family belongs here.
- Flag new duplicates/overlaps and namespace mismatches rather than silently merging them.
Other workspace projects with a CLAUDE.md (not indexed — promote on request)
Listed so they can be pulled into the index above if you decide they belong.
SCADA/OT, de-indexed (still have a CLAUDE.md under ~/Desktop/):
- OpcUaTestServer — dual-instance OPC UA test server (.NET 10) for testing OPC UA clients / simulating automation.
- scada (ScadaLink) — design docs + scaffolding for the distributed SCADA platform (
ZB.MOM.ScadaLink.*). - scadalink-design-opcua-browser — ScadaBridge variant focused on OPC UA browser / Data Connection Layer work.
- DARS — DARS → Wonderware SCADA migration (design phase, Q2 2026 go-live).
- DARS_BU — backup snapshot of DARS.
- plan — 3-year SCADA IT/OT modernization roadmap (markdown).
Outside the SCADA family:
- delmia — DELMIA / Apriso (Intercim Velocity) MES customization export (ASP.NET
.asmx); MES-adjacent. - lightctrl — Raspberry Pi Python I/O control (edge hardware).
- codestats — Rust CLI for code statistics on .NET solutions/dirs (dev tooling for the .NET repos).
- servecli — Rust portable SSH/SFTP server for Windows remote task management (greenfield).
- JdeScopingTool — JD Edwards "LotFinder" .NET 4.8 → .NET 10 migration (ERP, not SCADA).
- chat — local-first roleplay chat engine.
- candy2 — candy.ai chat scraping / browser automation.
- menardslist — Menards.com cart → printable picklist PDF.