fix(sessions): mirror FailureSource + AdminMarkedAction in ETag force-write

UpdateSessionStatusAsync force-write fallback (after ETag retries are
exhausted) mirrored most fields but silently dropped FailureSource and
AdminMarkedAction. Under ETag contention at the terminal transition
(e.g. WhiteGlove drain racing an admin Mark Succeeded/Failed), this
neutralized the admin-driven AdminAction trigger sent to agents and
lost the failure attribution. Mirror both fields analogous to the
existing FailureSnapshotJson mirror.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Oliver Kieselbach
2026-06-05 15:15:21 +02:00
parent 467ee07810
commit ab90423b2c
@@ -1556,6 +1556,20 @@ namespace AutopilotMonitor.Functions.Services
if (status == SessionStatus.Failed && !string.IsNullOrEmpty(failureSnapshotJson)) if (status == SessionStatus.Failed && !string.IsNullOrEmpty(failureSnapshotJson))
forceUpdate["FailureSnapshotJson"] = failureSnapshotJson; forceUpdate["FailureSnapshotJson"] = failureSnapshotJson;
// Mirror FailureSource (failure attribution: agent / rule:<id> / manual)
// from the regular path — otherwise the force-merge fallback silently
// drops the origin of a Failed status under ETag contention.
if (status == SessionStatus.Failed && !string.IsNullOrEmpty(failureSource))
forceUpdate["FailureSource"] = failureSource;
// Mirror AdminMarkedAction — the authoritative trigger for the
// AdminAction response-field sent to agents (set only by Mark
// Succeeded/Failed). Dropping it here would silently neutralize an
// administrator-driven terminal override exactly when ETag retries
// are exhausted at the terminal transition.
if (!string.IsNullOrEmpty(adminMarkedAction))
forceUpdate["AdminMarkedAction"] = adminMarkedAction;
if (isPreProvisioned.HasValue) if (isPreProvisioned.HasValue)
forceUpdate["IsPreProvisioned"] = isPreProvisioned.Value; forceUpdate["IsPreProvisioned"] = isPreProvisioned.Value;