# Health — current state: MxAccessGateway **Verified 2026-11-09 at `mxaccessgw@de86f8b8` (`origin/main`)** for scadaproj#11. Read-only `git grep` / `git show` against the origin default branch; all paths relative to the repo root (`~/Desktop/MxAccessGateway`). The pre-adoption state (verified 2026-06-01: a hardcoded `/health/live` `MapGet`, a dead `AddHealthChecks()`, no probes) is gone; see git history of this file. - **Package:** `ZB.MOM.WW.Health` **0.3.0**, core only (`src/ZB.MOM.WW.MxGateway.Server/ZB.MOM.WW.MxGateway.Server.csproj:20`). No `.Akka`, no `.EntityFrameworkCore` — the gateway has no Akka cluster and no EF context. - **Registration:** `builder.Services.AddGatewayHealthChecks()` (`GatewayApplication.cs:118`) → `src/ZB.MOM.WW.MxGateway.Server/Diagnostics/GatewayHealthCheckExtensions.cs:19-41`. - **Mapping:** `endpoints.MapZbHealth()` with default paths/writer (`GatewayApplication.cs:346`), anonymous unconditionally (the Overview dashboard polls `/health/active` without credentials). ## Per-endpoint contents | Endpoint | Checks run | Can return 503 when | |---|---|---| | `/healthz` (live) | none (`_ => false`) | never (process up) | | `/health/ready` | `auth-store`, `worker-executable`, `galaxy-sql` | auth SQLite unreachable; worker exe missing; Galaxy SQL unreachable or > 5 s | | `/health/active` | `mxaccess-sessions` | every open session is `Faulted` (zero sessions = Healthy) | No check is tagged `live` (asserted by `GatewayHealthCheckRegistrationTests`). ## Checks All registered with `AddTypeActivatedCheck`, `failureStatus: null` (the check's own status is used). Files under `src/ZB.MOM.WW.MxGateway.Server/Diagnostics/`. | Name | Class | Tag | Probes | Failure | |---|---|---|---|---| | `auth-store` | `AuthStoreHealthCheck` | ready | Opens the API-key SQLite store via `AuthSqliteConnectionFactory`, runs `SELECT 1` | Unhealthy | | `worker-executable` | `WorkerExecutableHealthCheck` | ready | `File.Exists(Path.GetFullPath(MxGateway:Worker:ExecutablePath))` — same resolution as `WorkerProcessLauncher.ResolveExecutablePath` | Unhealthy (missing or invalid path) | | `galaxy-sql` | `GalaxySqlHealthCheck` | ready | `IGalaxyRepository.TestConnectionAsync` bounded by a 5 s `TimeProvider` timeout | Unhealthy (false, throw, or timeout) | | `mxaccess-sessions` | `SessionHealthCheck` | active | Buckets `ISessionRegistry.Snapshot()` by state; `data` = total/ready/faulted/starting/closing | Healthy if 0 faulted (incl. 0 sessions); Degraded if some faulted; Unhealthy if all usable sessions faulted | `worker-executable` and `galaxy-sql` are new on `main` `8c21678c` (mxaccessgw#206, closed 2026-11-09). They check that the worker **binary exists** and that **Galaxy SQL answers**; neither checks a running worker or the named-pipe IPC (workers are per-session and only exist while a client holds a session). No LDAP check was added (#206 comment: deliberately out of scope). `galaxy-sql` is unconditional: `AddZbGalaxyRepository` is always registered (`GatewayApplication.cs:167`), so a gateway whose Galaxy SQL is down drops out of readiness even though its MXAccess data path does not use SQL. That is the #206 design ("must take the gateway out of rotation"), not an accident. ## Active-node gating None. The gateway is a singleton per host (no cluster), registers no `IActiveNodeGate`, and uses no `RequireActiveNode()`. The `active` tier is used for a **session-health** signal instead of an active/standby signal, so every gateway answers 200 on `/health/active` unless all its sessions are faulted. ## Other endpoints `MapZbMetrics()` (`:347`, anonymous by default, see `MetricsOptions`), `MapZbGalaxyRepository()` (`:359`), dashboard routes. No bespoke health endpoint remains. ## vs SPEC | SPEC | Status | Note | |---|---|---| | §1 three tiers via `MapZbHealth`, canonical tags | ✅ | default paths | | §1 nothing on `live` | ✅ | test-asserted | | §2.1 `DatabaseHealthCheck` | n/a | no EF; custom SQLite + Galaxy SQL checks | | §2.3 active tier = oldest `Up` member | 🟡 deviation | no cluster; active tier carries `mxaccess-sessions` (deliberate, documented in `SessionHealthCheck`) | | §2.4 `GrpcDependencyHealthCheck` for the worker | ⛔ not used | worker IPC is named pipes, not gRPC; `worker-executable` is a presence proxy (see GAPS P2) | | §3 canonical JSON writer | ✅ | `MapZbHealth` default | | §4 `IActiveNodeGate` | n/a | no active/standby |