Skip to content

goal stop

Kazushi Kamegawa edited this page Oct 10, 2026 · 2 revisions

Stop Active Goals — Issue #174

日本語

Date: 2026-10-11 Tracking: Issue #174 Status: Approved plan (2026-10-11).

Summary

Keep the composer Stop action available while a Goal is Active, including between turns and during automatic continuation. Stop pauses the Goal and interrupts the current turn in the selected thread, with state scoped to the current owner and connection generation.

Design

  • Treat Goal state from ExecuteGoalAsync, Goal update/deletion notifications, and thread/goal/get as one thread-scoped state stream. Refresh after explicit selection or Join; reject stale reads and notifications across owner, thread, or connection-generation changes. Reconnection does not replay Stop or other work.
  • Show Stop as the composer primary action for an Active Goal even when no turn is currently running. Show a non-repeatable stopping state while the request is in flight and, after pausing, until the targeted turn completes. Paused, Complete, Blocked, usage/ budget limited, or deleted Goals return to normal composer behavior; Resume returns to Stop while Active.
  • Add a dedicated Extension–Worker StopThreadGoalAsync request using the existing owner-scoped envelope and target thread. Advance the Worker contract from v21 to the next unused version. The Worker validates the captured owner, connection generation, and joined thread before and after each RPC.
  • On Stop, cancel queued commands for that thread, preserve unsent composer input and attachments, and prevent already-dequeued commands (including queued Resume) from dispatching after the stop begins. Do not replay work after disconnect or timeout.
  • The Worker reads the Goal state and attempts thread/goal/set with only status: "paused" when Active, then identifies the latest running turn for that same thread and interrupts it. The explicit Stop instruction authorizes this interrupt without a second confirmation, including during automatic continuation. Attempt interruption even when pausing fails or has an unknown outcome; if no turn runs, report the pause outcome without interrupting. Preserve Goal objective, budget, and usage.
  • Report pause and interrupt outcomes independently. Keep Paused if interrupt fails; if pause fails while interrupt succeeds, report a partial outcome and do not claim the Goal is Paused. Treat an acknowledgement as distinct from turn/completed; handle unknown outcomes with a read-only state check and require an explicit user retry. Keep the existing local-start restriction for ordinary turn interruption. Do not block the dedicated Stop path solely because authentication state changed.
  • Bind Remote UI state with DataMember and change notifications. Keep one Stop control, with matching icon, tooltip, and UI Automation name/help. Keyboard send must honor the same stopping/disabled state as the visible button.
  • Decisions confirmed during the integration review (2026-10-11): Ctrl+Enter only sends and is disabled while the primary action is a Goal action; slash commands such as /goal pause stay available while a Goal is Active and are rejected only while a stop is unresolved; the Worker still attempts the status-only pause when the Goal read fails and still interrupts the latest same-thread turn when the Goal ended or was cleared after the click; overlapping stops are serialized; a request timeout is an unknown outcome; the Goal is refreshed read-only only after a reconnect; an unsupported server returns the composer to ordinary Send and Interrupt.

Implementation phases

Phase Work Acceptance
P0 Amend the current design and plan records with Stop ordering, target scope, and failure behavior English canonical text and Japanese translations agree
P1 Add the Worker contract, owner/thread/generation checks, queue cancellation, pause/interrupt sequence, and Fake App Server scenarios Ordered calls, no cross-thread effects, no automatic replay
P2 Unify Goal state synchronization and expose Stop/stopping state in the composer Active/Paused/terminal states render and operate as specified
P3 Review Worker races and WPF behavior; complete automated and Experimental Instance validation All required checks and visual evidence are recorded

Verification

  • Cover Goal start, automatic continuation, between-turn, approval/input-waiting, Resume, pause, completion, deletion, and concurrent completion/deletion.
  • Verify pause is attempted before interrupt; interruption still follows a failed/unknown pause attempt; no-turn pause returns its result; objective/budget/usage remain intact; interruption acknowledgement is not treated as completion; target the latest same-thread turn after the pause attempt without another confirmation and never redirect to another thread.
  • Exercise double-click, queued Resume, dequeued command, delayed read/notification, owner/thread/generation changes, disconnect/reconnect, and zero replay.
  • Verify independent pause/interrupt failures, partial outcomes, unknown outcomes, unsupported API, and authentication-state changes. Regress ordinary Send/Steer/interruption and cross-thread rejection.
  • Run Core/UI suites, Debug/Release warning-free builds, pinned 0.159.1 contract checks and 0.155.1 regression checks, and VSIX DTO/XAML consistency checks.
  • In the Experimental Instance, inspect Light, Dark, High Contrast, narrow width, keyboard/focus, and UI Automation. Record screenshots for running, stopping, stopped, and reconnected states. Any unobserved criterion remains incomplete.

Scope

Issue #173, CLI/SDK/NuGet upgrades, backward-compatibility work, and data migration are excluded. Existing Send/Steer behavior for ordinary turns remains governed by current rules. Completion requires the implementation and validation evidence above.

References

Clone this wiki locally