diff --git a/src/Shared/AutopilotMonitor.DecisionCore/Engine/DecisionEngine.Classic.cs b/src/Shared/AutopilotMonitor.DecisionCore/Engine/DecisionEngine.Classic.cs
index 2ea6e231..d8e2601c 100644
--- a/src/Shared/AutopilotMonitor.DecisionCore/Engine/DecisionEngine.Classic.cs
+++ b/src/Shared/AutopilotMonitor.DecisionCore/Engine/DecisionEngine.Classic.cs
@@ -243,6 +243,15 @@ namespace AutopilotMonitor.DecisionCore.Engine
/// Handle . Mirror of the Hello handler:
/// records , and if Hello has already
/// resolved the session completes here.
+ ///
+ /// Hello-disabled fast-path: when is
+ /// explicitly false AND we have reached AccountSetup (so the Hello-skip is the
+ /// genuine post-ESP state rather than a premature mid-DeviceSetup classification),
+ /// synthesise HelloOutcome="Skipped" here and route directly through Finalizing.
+ /// This avoids waiting out the full 5-min HelloSafety window when the policy reader
+ /// already told us no Hello wizard is expected. Belt-and-suspenders alongside the
+ /// EspExiting → HelloSafety reducer path: the path that fires first wins.
+ ///
///
private DecisionStep HandleDesktopArrivedV1(DecisionState state, DecisionSignal signal)
{
@@ -254,6 +263,32 @@ namespace AutopilotMonitor.DecisionCore.Engine
var helloAlreadyResolved = state.HelloResolvedUtc != null;
+ // Hello-disabled fast-path. Both guards required:
+ // 1. HelloPolicyEnabled?.Value == false — policy reader confirmed no Hello wizard
+ // 2. AccountSetupEnteredUtc != null — same gate as ShouldTransitionToAwaitingHello,
+ // prevents a premature pre-AccountSetup completion if HelloPolicyDetected fires
+ // before AccountSetup is observed.
+ // Skipping unknown policy (HelloPolicyEnabled == null) preserves the prior pessimistic
+ // behaviour: keep waiting for Hello / HelloSafety.
+ if (!helloAlreadyResolved
+ && state.HelloPolicyEnabled?.Value == false
+ && state.AccountSetupEnteredUtc != null)
+ {
+ builder.HelloResolvedUtc = new SignalFact(signal.OccurredAtUtc, signal.SessionSignalOrdinal);
+ builder.HelloOutcome = new SignalFact("Skipped", signal.SessionSignalOrdinal);
+ // Cancel HelloSafety if it was armed by an earlier EspExiting — we're completing
+ // now via the fast-path, the deadline would otherwise fire post-Completion and
+ // dead-end in the reducer.
+ builder.CancelDeadline(DeadlineNames.HelloSafety);
+
+ return TransitionToFinalizing(
+ state: state,
+ signal: signal,
+ preparedBuilder: builder,
+ nextStepIndex: nextStep,
+ trigger: nameof(DecisionSignalKind.DesktopArrived) + ":HelloDisabledFastPath");
+ }
+
// Plan §5 Fix 6: mirror of HandleHelloResolvedV1. When both prerequisites are in,
// go through Finalizing (non-terminal) instead of jumping straight to Completed.
if (helloAlreadyResolved)