diff --git a/src/ZB.MOM.WW.ScadaBridge.Commons/Types/Alarms/AlarmConditionState.cs b/src/ZB.MOM.WW.ScadaBridge.Commons/Types/Alarms/AlarmConditionState.cs
new file mode 100644
index 00000000..b8b57a63
--- /dev/null
+++ b/src/ZB.MOM.WW.ScadaBridge.Commons/Types/Alarms/AlarmConditionState.cs
@@ -0,0 +1,24 @@
+using ZB.MOM.WW.ScadaBridge.Commons.Types.Enums;
+
+namespace ZB.MOM.WW.ScadaBridge.Commons.Types.Alarms;
+
+///
+/// Unified, read-only alarm condition state. The OPC UA Part 9 sub-conditions
+/// are orthogonal, and MxAccess's ACTIVE / ACTIVE_ACKED / INACTIVE map cleanly
+/// onto them, so they are modeled as independent flags plus a 0–1000 severity.
+/// Computed alarms populate this from State + Priority; native alarms mirror it
+/// from the source.
+///
+/// Active vs Inactive.
+/// Acked vs Unacked.
+/// Confirmed vs Unconfirmed; null when the condition is not confirmable.
+/// Shelving sub-state.
+/// Whether the source has suppressed the condition.
+/// Severity on the unified 0–1000 scale.
+public record AlarmConditionState(
+ bool Active,
+ bool Acknowledged,
+ bool? Confirmed,
+ AlarmShelveState Shelve,
+ bool Suppressed,
+ int Severity);
diff --git a/src/ZB.MOM.WW.ScadaBridge.Commons/Types/Alarms/NativeAlarmTransition.cs b/src/ZB.MOM.WW.ScadaBridge.Commons/Types/Alarms/NativeAlarmTransition.cs
new file mode 100644
index 00000000..02cbeb6e
--- /dev/null
+++ b/src/ZB.MOM.WW.ScadaBridge.Commons/Types/Alarms/NativeAlarmTransition.cs
@@ -0,0 +1,39 @@
+using ZB.MOM.WW.ScadaBridge.Commons.Types.Enums;
+
+namespace ZB.MOM.WW.ScadaBridge.Commons.Types.Alarms;
+
+///
+/// Protocol-neutral alarm transition emitted by an
+/// IAlarmSubscribableConnection adapter (OPC UA A&C or MxGateway).
+/// Keyed by ; routed to instances by
+/// .
+///
+/// Stable per-condition key (e.g. "Tank01.Level.HiHi").
+/// Owning source object used for instance routing (e.g. "Tank01").
+/// Source alarm type (e.g. "AnalogLimitAlarm.HiHi").
+/// Transition classification, incl. snapshot replay sentinels.
+/// Mirrored condition state.
+/// Source taxonomy/category.
+/// Human-readable description from the source template.
+/// Event message text.
+/// Operator principal on ack transitions (display-only).
+/// Operator comment on ack transitions (display-only).
+/// When the condition originally became active, if known.
+/// When this transition occurred.
+/// Current source value (display-only).
+/// Limit/threshold value for limit alarms (display-only).
+public record NativeAlarmTransition(
+ string SourceReference,
+ string SourceObjectReference,
+ string AlarmTypeName,
+ AlarmTransitionKind Kind,
+ AlarmConditionState Condition,
+ string Category,
+ string Description,
+ string Message,
+ string OperatorUser,
+ string OperatorComment,
+ DateTimeOffset? OriginalRaiseTime,
+ DateTimeOffset TransitionTime,
+ string CurrentValue,
+ string LimitValue);
diff --git a/src/ZB.MOM.WW.ScadaBridge.Commons/Types/Enums/AlarmKind.cs b/src/ZB.MOM.WW.ScadaBridge.Commons/Types/Enums/AlarmKind.cs
new file mode 100644
index 00000000..cb99bbc7
--- /dev/null
+++ b/src/ZB.MOM.WW.ScadaBridge.Commons/Types/Enums/AlarmKind.cs
@@ -0,0 +1,17 @@
+namespace ZB.MOM.WW.ScadaBridge.Commons.Types.Enums;
+
+///
+/// Distinguishes how an alarm's state is produced: computed at the site from
+/// attribute triggers, or mirrored read-only from a native source.
+///
+public enum AlarmKind
+{
+ /// Evaluated at the site by an AlarmActor from attribute triggers.
+ Computed,
+
+ /// Mirrored from an OPC UA Alarms & Conditions server.
+ NativeOpcUa,
+
+ /// Mirrored from the MxAccess Gateway alarm feed.
+ NativeMxAccess
+}
diff --git a/src/ZB.MOM.WW.ScadaBridge.Commons/Types/Enums/AlarmShelveState.cs b/src/ZB.MOM.WW.ScadaBridge.Commons/Types/Enums/AlarmShelveState.cs
new file mode 100644
index 00000000..d6f28274
--- /dev/null
+++ b/src/ZB.MOM.WW.ScadaBridge.Commons/Types/Enums/AlarmShelveState.cs
@@ -0,0 +1,13 @@
+namespace ZB.MOM.WW.ScadaBridge.Commons.Types.Enums;
+
+///
+/// OPC UA Part 9 shelving sub-state of an alarm condition. Mirrored read-only
+/// from the source; computed alarms are always .
+///
+public enum AlarmShelveState
+{
+ Unshelved,
+ OneShotShelved,
+ TimedShelved,
+ PermanentShelved
+}
diff --git a/src/ZB.MOM.WW.ScadaBridge.Commons/Types/Enums/AlarmTransitionKind.cs b/src/ZB.MOM.WW.ScadaBridge.Commons/Types/Enums/AlarmTransitionKind.cs
new file mode 100644
index 00000000..96cb23e6
--- /dev/null
+++ b/src/ZB.MOM.WW.ScadaBridge.Commons/Types/Enums/AlarmTransitionKind.cs
@@ -0,0 +1,18 @@
+namespace ZB.MOM.WW.ScadaBridge.Commons.Types.Enums;
+
+///
+/// Classifies a NativeAlarmTransition emitted by an
+/// IAlarmSubscribableConnection adapter. and
+/// carry the initial active-condition replay
+/// produced on every (re)subscribe so consumers can re-seed state.
+///
+public enum AlarmTransitionKind
+{
+ Snapshot,
+ SnapshotComplete,
+ Raise,
+ Acknowledge,
+ Clear,
+ Retrigger,
+ StateChange
+}
diff --git a/tests/ZB.MOM.WW.ScadaBridge.Commons.Tests/Types/Alarms/AlarmConditionStateTests.cs b/tests/ZB.MOM.WW.ScadaBridge.Commons.Tests/Types/Alarms/AlarmConditionStateTests.cs
new file mode 100644
index 00000000..376a52e5
--- /dev/null
+++ b/tests/ZB.MOM.WW.ScadaBridge.Commons.Tests/Types/Alarms/AlarmConditionStateTests.cs
@@ -0,0 +1,36 @@
+using ZB.MOM.WW.ScadaBridge.Commons.Types.Alarms;
+using ZB.MOM.WW.ScadaBridge.Commons.Types.Enums;
+
+namespace ZB.MOM.WW.ScadaBridge.Commons.Tests.Types.Alarms;
+
+public class AlarmConditionStateTests
+{
+ [Fact]
+ public void AlarmConditionState_DefaultsAreNormalUnshelved()
+ {
+ var s = new AlarmConditionState(
+ Active: false, Acknowledged: true, Confirmed: null,
+ Shelve: AlarmShelveState.Unshelved, Suppressed: false, Severity: 0);
+
+ Assert.False(s.Active);
+ Assert.Equal(AlarmShelveState.Unshelved, s.Shelve);
+ Assert.Equal(0, s.Severity);
+ }
+
+ [Fact]
+ public void NativeAlarmTransition_CarriesSourceAndCondition()
+ {
+ var t = new NativeAlarmTransition(
+ SourceReference: "Tank01.Level.HiHi", SourceObjectReference: "Tank01",
+ AlarmTypeName: "AnalogLimitAlarm.HiHi", Kind: AlarmTransitionKind.Raise,
+ Condition: new AlarmConditionState(true, false, null, AlarmShelveState.Unshelved, false, 800),
+ Category: "Process", Description: "High level", Message: "level high",
+ OperatorUser: "", OperatorComment: "",
+ OriginalRaiseTime: null, TransitionTime: DateTimeOffset.UnixEpoch,
+ CurrentValue: "92.1", LimitValue: "90");
+
+ Assert.Equal("Tank01", t.SourceObjectReference);
+ Assert.Equal(800, t.Condition.Severity);
+ Assert.Equal(AlarmTransitionKind.Raise, t.Kind);
+ }
+}