From b0779066318289e715980d1d0af0cbde3d23864f Mon Sep 17 00:00:00 2001 From: Don Garrett Date: Tue, 29 Sep 2026 17:17:19 +0000 Subject: [PATCH] Let the live milestone test expect a waiting state after execution It drove the orchestrator until EXECUTING and accepted EXECUTING as the end state, which with no publisher configured was the stranding this branch removes: the milestone now finishes in PR_OPEN. Return once 'start milestone 1' is sent, since the milestone runs inside it, and expect PR_OPEN or AWAIT_INPUT. Co-Authored-By: Claude Opus 5.5 (1M context) Claude-Session: https://claude.ai/code/session_01PPQ14L3LikyefCMFBqEbKE --- tests/integration/test_milestone_live.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/tests/integration/test_milestone_live.py b/tests/integration/test_milestone_live.py index a10e63c..18337b1 100644 --- a/tests/integration/test_milestone_live.py +++ b/tests/integration/test_milestone_live.py @@ -16,6 +16,7 @@ from nisse_dev.control import ( AWAIT_INPUT, AWAIT_MILESTONE_SIGNOFF, EXECUTING, + PR_OPEN, Orchestrator, ) from nisse_dev.executor import LLMExecutor @@ -45,7 +46,9 @@ def _drive_to_execution( if state.state == AWAIT_INPUT: transport.receive("don", "Use your best judgement and proceed.") elif state.state == AWAIT_MILESTONE_SIGNOFF and gate.get("approved"): + # The milestone runs to completion inside this command. transport.receive("don", "start milestone 1") + return elif state.state in (AWAIT_ARCH_SIGNOFF, AWAIT_MILESTONE_SIGNOFF): transport.receive("don", "approve") else: @@ -85,7 +88,9 @@ def test_plan_approve_execute_produces_a_real_file( state = store.get_state() assert state is not None - assert state.state in (EXECUTING, AWAIT_INPUT) + # Never EXECUTING at rest: with no publisher a finished milestone waits in + # PR_OPEN, and one that stopped short waits for the operator. + assert state.state in (PR_OPEN, AWAIT_INPUT) created = list(workspace.root.rglob("*.py")) assert created, f"executor created no Python file; said: {transport.outbound[-1]}"