From 81a075e684e8d00e3c4c23b1a84ed492d5703ae3 Mon Sep 17 00:00:00 2001 From: codex Date: Mon, 3 Aug 2026 17:21:08 +0300 Subject: [PATCH] fix: exit lifecycle probe without document command queue --- .../FirstLimitedApplyAutomation.cs | 10 ++++++++++ .../tests/PRecAnnot.Core.Tests/FoundationTests.cs | 3 ++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/Plant3D2026/P_Rec_Annot/src/PRecAnnot.Plant3D2026/FirstLimitedApplyAutomation.cs b/Plant3D2026/P_Rec_Annot/src/PRecAnnot.Plant3D2026/FirstLimitedApplyAutomation.cs index 08b3758..619ed4f 100644 --- a/Plant3D2026/P_Rec_Annot/src/PRecAnnot.Plant3D2026/FirstLimitedApplyAutomation.cs +++ b/Plant3D2026/P_Rec_Annot/src/PRecAnnot.Plant3D2026/FirstLimitedApplyAutomation.cs @@ -330,6 +330,16 @@ internal sealed class FirstLimitedApplyAutomationCoordinator { if (exitHandlerSubscribed) AcadApplication.Idle -= OnExitIdle; exitHandlerSubscribed = false; + // LifecycleProbe deliberately opens no drawing. It is already + // executing in the first verified Idle callback, where the managed + // quit API has been runtime-confirmed to terminate AutoCAD cleanly. + if (document is null && string.Equals(config?.Phase, "LifecycleProbe", StringComparison.OrdinalIgnoreCase)) + { + transitions.Add("LifecycleProbeApplicationQuitRequested"); + TryWriteEvidence(state == CoordinatorState.Completed, null); + AcadApplication.Quit(); + return; + } if (document is null) throw new InvalidOperationException("AUTOMATION_EXIT_DOCUMENT_UNAVAILABLE"); transitions.Add("NativeQuitCommandQueued"); // Persist the exit boundary before handing control back to AutoCAD; diff --git a/Plant3D2026/P_Rec_Annot/tests/PRecAnnot.Core.Tests/FoundationTests.cs b/Plant3D2026/P_Rec_Annot/tests/PRecAnnot.Core.Tests/FoundationTests.cs index e3d669a..e121b67 100644 --- a/Plant3D2026/P_Rec_Annot/tests/PRecAnnot.Core.Tests/FoundationTests.cs +++ b/Plant3D2026/P_Rec_Annot/tests/PRecAnnot.Core.Tests/FoundationTests.cs @@ -105,7 +105,7 @@ public sealed class FoundationTests Assert.Contains("AcadApplication.Idle += OnExitIdle", source); Assert.Contains("NativeQuitCommandQueued", source); Assert.Contains("document.SendStringToExecute(\"_.QUIT _N \", true, false, false);", source); - Assert.DoesNotContain("AcadApplication.Quit();", source); + Assert.Contains("LifecycleProbeApplicationQuitRequested", source); } [Fact] public void Callback_AfterDocumentDestroyed_DoesNotAccessDocument() @@ -120,6 +120,7 @@ public sealed class FoundationTests var source = File.ReadAllText(Path.Combine(ProjectRoot, "src", "PRecAnnot.Plant3D2026", "FirstLimitedApplyAutomation.cs")); Assert.DoesNotContain("MdiActiveDocument", source[source.IndexOf("private void DispatchNativeQuit", StringComparison.Ordinal)..]); Assert.Contains("AUTOMATION_EXIT_DOCUMENT_UNAVAILABLE", source); + Assert.Contains("if (document is null && string.Equals(config?.Phase, \"LifecycleProbe\"", source); } [Fact] public void TerminalState_IgnoresFurtherCallbacks()