fix(galaxy): #872 detail-0 failure rows route on category, not detected_by

Every raw detected_by value names an MXAccess layer (requesting/responding
LMX, NMX, automation object); the gateway's own failures arrive as
ProtocolStatus. The 'non-zero source = transport failure' rule made a failure
the responding object detected a comms error. Item 1 of #872 (Warning/Pending
categories) stays open pending a captured row.

Claude-Session: https://claude.ai/code/session_01GT67AD99zQQqpLCVm3p7xk
This commit is contained in:
Joseph Doherty
2026-11-11 15:15:05 -05:00
parent 970f2159ad
commit 1a08b4f746
2 changed files with 17 additions and 13 deletions
@@ -128,14 +128,12 @@ internal static class StatusCodeMap
// generic Bad (#866, a stopped platform's ScanState on VD03), MX_E_InvalidObjectId (8) surfaced as
// BadNotConnected, MX_E_Overflow (20) as BadCommunicationError. A failure row is also never Good or
// Uncertain, whatever its detail.
if (status.Detail != 0) return FromCategory(status, logger);
// detected_by != Mxaccess (raw_detected_by != the MXAccess source enum) implies
// the failure happened pre-call (gateway, worker, transport) — surface as a
// communication error rather than a generic Bad.
if (status.RawDetectedBy != 0) return BadCommunicationError;
return Bad;
//
// Detail 0 routes the same way. It used to become BadCommunicationError whenever raw_detected_by != 0, on
// the belief that a non-zero source meant a pre-MXAccess transport failure — but every detected_by value
// names an MXAccess layer (0 requesting LMX, 1 responding LMX, 2/3 NMX, 4/5 automation object; the
// gateway's own failures arrive as ProtocolStatus, never as a status row), so the category decides (#872).
return FromCategory(status, logger);
}
/// <summary>
@@ -140,12 +140,18 @@ public sealed class StatusCodeMapTests
logger.Entries.Count.ShouldBe(1);
}
/// <summary>Verifies that non-zero DetectedBy maps to communication error when detail is zero.</summary>
[Fact]
public void FromMxStatus_SuccessZero_DetailZero_DetectedByNonZero_IsCommunicationError()
/// <summary>
/// #872: detected_by names an MXAccess layer (3 = responding NMX), not a transport failure, so a detail-0
/// failure row routes on its category — a communication-category row is still BadCommunicationError.
/// </summary>
[Theory]
[InlineData(MxStatusCategory.Unspecified, 0x80000000u)]
[InlineData(MxStatusCategory.CommunicationError, 0x80050000u)]
[InlineData(MxStatusCategory.ConfigurationError, 0x80890000u)]
public void FromMxStatus_SuccessZero_DetailZero_RoutesByCategory_NotDetectedBy(MxStatusCategory category, uint expected)
{
var s = new MxStatusProxy { Success = 0, Detail = 0, RawDetectedBy = 3 };
StatusCodeMap.FromMxStatus(s).ShouldBe(StatusCodeMap.BadCommunicationError);
var s = new MxStatusProxy { Success = 0, Detail = 0, RawDetectedBy = 3, Category = category };
StatusCodeMap.FromMxStatus(s).ShouldBe(expected);
}
/// <summary>Verifies that all-zero status maps to Bad status code.</summary>