diff --git a/src/ZB.MOM.WW.ScadaBridge.CentralUI/Components/Pages/Deployment/InstanceConfigure.razor b/src/ZB.MOM.WW.ScadaBridge.CentralUI/Components/Pages/Deployment/InstanceConfigure.razor
index 6412f759..77497d9e 100644
--- a/src/ZB.MOM.WW.ScadaBridge.CentralUI/Components/Pages/Deployment/InstanceConfigure.razor
+++ b/src/ZB.MOM.WW.ScadaBridge.CentralUI/Components/Pages/Deployment/InstanceConfigure.razor
@@ -549,7 +549,7 @@
@* Tri-state: blank = inherit the template alarm's flag.
"Not reportable" is a real override, not a clear — it
pins a reportable template alarm off for this instance. *@
- MES reportable
+ MES reportable override
Inherited (@(_editingAlarm.IsMesReportable ? "reportable" : "not reportable"))
Reportable
@@ -1579,17 +1579,6 @@
return parts.Count == 0 ? "(empty)" : string.Join(", ", parts);
}
- ///
- /// The save-time delta rule: does the modal carry anything worth persisting?
- /// When it does not, DELETES any existing
- /// override — so every override term must be represented here or it would be
- /// silently dropped on save. A false MES-reportable choice counts: it
- /// pins a reportable template alarm off for this instance, which is a real
- /// override and not the same as inheriting.
- ///
- internal static bool HasOverrideDelta(string? overrideJson, int? priority, bool? mesReportable)
- => !string.IsNullOrWhiteSpace(overrideJson) || priority.HasValue || mesReportable.HasValue;
-
///
/// Opens the override editor modal pre-populated with the merged
/// (inherited + existing override) config so the user sees the effective
diff --git a/src/ZB.MOM.WW.ScadaBridge.CentralUI/Components/Pages/Deployment/InstanceConfigure.razor.cs b/src/ZB.MOM.WW.ScadaBridge.CentralUI/Components/Pages/Deployment/InstanceConfigure.razor.cs
index 833ec62d..d3177571 100644
--- a/src/ZB.MOM.WW.ScadaBridge.CentralUI/Components/Pages/Deployment/InstanceConfigure.razor.cs
+++ b/src/ZB.MOM.WW.ScadaBridge.CentralUI/Components/Pages/Deployment/InstanceConfigure.razor.cs
@@ -115,6 +115,17 @@ public partial class InstanceConfigure
return new CsvOverrideImportOutcome(overrides, Array.Empty());
}
+ ///
+ /// The save-time delta rule for the alarm-override modal: does it carry anything
+ /// worth persisting? When it does not, SaveOverrideFromModal DELETES any
+ /// existing override — so every override term must be represented here or it
+ /// would be silently dropped on save. A false MES-reportable choice
+ /// counts: it pins a reportable template alarm off for this instance, which is a
+ /// real override and not the same as inheriting.
+ ///
+ internal static bool HasOverrideDelta(string? overrideJson, int? priority, bool? mesReportable)
+ => !string.IsNullOrWhiteSpace(overrideJson) || priority.HasValue || mesReportable.HasValue;
+
///
/// One validated native-alarm-source retarget from an imported CSV: the source
/// binding's name plus the three optional override fields (null = keep the
diff --git a/tests/ZB.MOM.WW.ScadaBridge.CentralUI.PlaywrightTests/Deployment/InstanceConfigureTests.cs b/tests/ZB.MOM.WW.ScadaBridge.CentralUI.PlaywrightTests/Deployment/InstanceConfigureTests.cs
index ef603199..9e391a5c 100644
--- a/tests/ZB.MOM.WW.ScadaBridge.CentralUI.PlaywrightTests/Deployment/InstanceConfigureTests.cs
+++ b/tests/ZB.MOM.WW.ScadaBridge.CentralUI.PlaywrightTests/Deployment/InstanceConfigureTests.cs
@@ -527,7 +527,9 @@ public sealed class InstanceConfigureTests : IClassFixturemesReportable — and that switching back to Inherited removes it again.
+ /// naming mesReportable — that switching to "Not reportable" persists false
+ /// (verified against the read-back document, since an absent/null field there would mean the
+ /// negative pin was dropped), and that switching back to Inherited removes the override again.
///
///
///
@@ -563,6 +565,31 @@ public sealed class InstanceConfigureTests : IClassFixture
+ o.GetProperty("alarmCanonicalName").GetString() == _cfg.AlarmName);
+
+ Assert.True(entry.TryGetProperty("isMesReportableOverride", out var flag),
+ "alarmOverrides entry is missing isMesReportableOverride.");
+ // JSON false specifically — an absent/null field would mean the negative pin was
+ // dropped and the alarm silently fell back to the template's flag.
+ Assert.Equal(JsonValueKind.False, flag.ValueKind);
+ }
+
// Reopen → back to Inherited (blank) → Save. With nothing else set that is now a
// no-delta save, which clears the override outright.
await row.Locator("[data-test='alarm-edit-btn']").ClickAsync();
diff --git a/tests/ZB.MOM.WW.ScadaBridge.CentralUI.Tests/Deployment/InstanceConfigureMesReportableTests.cs b/tests/ZB.MOM.WW.ScadaBridge.CentralUI.Tests/Deployment/InstanceConfigureMesReportableTests.cs
index 5dafbfff..a5ce1365 100644
--- a/tests/ZB.MOM.WW.ScadaBridge.CentralUI.Tests/Deployment/InstanceConfigureMesReportableTests.cs
+++ b/tests/ZB.MOM.WW.ScadaBridge.CentralUI.Tests/Deployment/InstanceConfigureMesReportableTests.cs
@@ -46,6 +46,9 @@ public class InstanceConfigureMesReportableTests
var selectEnd = markup.IndexOf(" ", selectStart, StringComparison.Ordinal);
Assert.True(selectEnd > selectStart, "MES reportable select is not closed.");
+ // Label mirrors the adjacent "Priority override" control.
+ Assert.Contains("MES reportable override", markup);
+
var selectBody = markup[selectStart..selectEnd];
var optionCount = selectBody.Split("