fix(host): fatal-log, flush and exit non-zero when the host fails to start (#618)

Claude-Session: https://claude.ai/code/session_01Ef2ozxS7QPanGT8uoATbTe
This commit is contained in:
Joseph Doherty
2026-10-08 06:52:54 -04:00
parent 3baa332d6b
commit 413bc5c04f
5 changed files with 94 additions and 1 deletions
+10
View File
@@ -108,6 +108,16 @@ plane (writes, alarm acks, the alerts emit, the alarm-history drain) on the wron
*higher* address so the two orderings genuinely disagree. `NodeRedundancyState.IsRoleLeaderForDriver`
was renamed `IsDriverPrimary` to stop the name asserting the old derivation.
**Accepted residual (#620): the election's role match is case-sensitive.** `RedundancyStateActor`
delegates to `ZB.MOM.WW.Health.Akka`'s `ClusterActiveNode.OldestUpMember`, which matches roles with
Akka's own ordinal `Member.HasRole`. A peer gossiping a miscased plain role (`Driver`) is therefore
invisible to the election — which only happens in a mixed rolling-upgrade window with a pre-R3-04
build (fixed builds normalize roles before gossip). Deliberately **not** patched: the library is a
family-shared package, and making either it or a local role pre-filter case-insensitive would split the
Primary election from `ClusterSingletonManager` placement (also ordinal) — recreating the "Primary not
on the singleton node" defect above. Case-sensitive on both sides is the consistent behaviour; finish
the rolling upgrade rather than working around it.
> **RESOLVED by Phase 6 — the election is now per application `Cluster`, not per Akka mesh.**
> Phase 6 of the per-cluster mesh program split the single fleet-wide Akka mesh into one independent
> 2-node mesh per application `Cluster` (see [Per-cluster meshes (Phase 6)](#per-cluster-meshes-phase-6)
+8
View File
@@ -453,6 +453,14 @@ takes no realm and no node.
### Node ACL enforcement (`Security:Acl:Enabled`)
> **ns=0 standard nodes stay ungated, deliberately (#617).** A session with no grants can still connect
> and read the standard OPC UA server nodes (`ServerStatus`, `NamespaceArray`, `ServiceLevel`, ...) and
> browse ns=0. Those are served by the SDK's core node manager outside our authorizer, and gating them
> would break session setup (clients read them for connection and redundancy health). They carry no plant
> data; every raw/UNS node, event subscription and HistoryRead is still gated. The boot warning says so
> ("can still connect and read the standard server nodes ... but sees no plant data") — earlier wording
> ("can connect and see nothing") overstated it.
| Key | Default | Effect |
|---|---|---|
| `Security:Acl:Enabled` | `false` | `true` makes scoped `NodeAcl` grants decide **every** data-plane operation — read, browse, subscribe, write, alarm commands and HistoryRead |