diff --git a/docs/Raw.md b/docs/Raw.md
index f49f90d3..098c1fc5 100644
--- a/docs/Raw.md
+++ b/docs/Raw.md
@@ -68,6 +68,16 @@ removed later.
auto-creates nested groups; typed columns win over `TagConfigJson` on conflict (flagged in
the review grid). **Import is all-or-nothing** — any invalid row blocks the whole commit.
Export round-trips the same shape.
+- **Native alarm section (Gitea #642)** — the Edit-tag modal carries a shared `NativeAlarmEditor`
+ below the per-driver editor / JSON textarea: a "Native alarm (Part 9 condition)" switch plus
+ `alarmType`, `severity` (1..1000) and `historizeToAveva` (default/yes/no), writing the
+ driver-agnostic `alarm` object of `TagConfig`. Offered only for `IAlarmSource` drivers (MTConnect,
+ AbCip, FOCAS, OpcUaClient, Galaxy — `NativeAlarmModel.SupportsNativeAlarms`); on any other driver an
+ existing `alarm` object is shown with a "no effect" note and a Remove button, never silently
+ dropped. Switching it off REMOVES the `alarm` key. Validation is advisory only (warnings) — the
+ deploy gate has no `alarm` rule and the server clamps severity, so the editor is never stricter.
+ Every edit re-parses the latest `ConfigJson` (`NativeAlarmModel.Edit`), so it composes with the
+ driver editor in either order. Not yet on the manual-entry grid (use JSON/CSV there).
- **Browse device…** — enabled per the two-tier resolution (bespoke `IDriverBrowser` →
universal `DiscoveryDriverBrowser` when the driver's `ITagDiscovery.SupportsOnlineDiscovery`
is true → grayed out otherwise). Multi-selected leaves become raw `Tag` rows under the
diff --git a/src/Server/ZB.MOM.WW.OtOpcUa.AdminUI/Components/Shared/Raw/RawTagModal.razor b/src/Server/ZB.MOM.WW.OtOpcUa.AdminUI/Components/Shared/Raw/RawTagModal.razor
index 6f1438aa..474922f4 100644
--- a/src/Server/ZB.MOM.WW.OtOpcUa.AdminUI/Components/Shared/Raw/RawTagModal.razor
+++ b/src/Server/ZB.MOM.WW.OtOpcUa.AdminUI/Components/Shared/Raw/RawTagModal.razor
@@ -9,6 +9,7 @@
@using Microsoft.AspNetCore.Components.Forms
@using ZB.MOM.WW.OtOpcUa.AdminUI.Uns
@using ZB.MOM.WW.OtOpcUa.AdminUI.Uns.TagEditors
+@using ZB.MOM.WW.OtOpcUa.AdminUI.Components.Shared.Uns.TagEditors
@using ZB.MOM.WW.OtOpcUa.Commons.Types
@using ZB.MOM.WW.OtOpcUa.Configuration.Enums
@inject IRawTreeService Svc
@@ -90,6 +91,9 @@
Schemaless per driver type. Validated server-side at deploy.
}
+
}
@if (!string.IsNullOrWhiteSpace(_error))
diff --git a/src/Server/ZB.MOM.WW.OtOpcUa.AdminUI/Components/Shared/Uns/TagEditors/NativeAlarmEditor.razor b/src/Server/ZB.MOM.WW.OtOpcUa.AdminUI/Components/Shared/Uns/TagEditors/NativeAlarmEditor.razor
new file mode 100644
index 00000000..b5e5bb68
--- /dev/null
+++ b/src/Server/ZB.MOM.WW.OtOpcUa.AdminUI/Components/Shared/Uns/TagEditors/NativeAlarmEditor.razor
@@ -0,0 +1,104 @@
+@* Shared native-alarm section (Gitea #642): authors the driver-agnostic TagConfig `alarm` object
+ (alarmType / severity / historizeToAveva) for a raw tag. A thin shell over NativeAlarmModel — all rules
+ live there. It sits OUTSIDE the per-driver typed editor (Galaxy has none) and writes the same ConfigJson.
+
+ Order-safety: every change goes through NativeAlarmModel.Edit(ConfigJson, ...), which re-parses the
+ LATEST json, so it can never clobber a key the driver editor just wrote; the driver models in turn
+ preserve the `alarm` key (pinned by NativeAlarmEditorModelTests).
+
+ Plain input/select + @onchange (no InputNumber/EditForm binding — see the AdminUI binding pitfalls). *@
+@using ZB.MOM.WW.OtOpcUa.AdminUI.Uns.TagEditors
+
+@if (_m.IsAlarm || _supported)
+{
+
+ @if (!_supported)
+ {
+ @* Never hide an authored alarm silently: show it and offer removal rather than dropping it. *@
+
+ This tag carries an alarm object, but driver type
+ @DriverType does not raise native alarms, so it has no effect.
+