Skip to content

fix(macapp): acknowledge run-control failures and preserve pending user input #994

Description

@dennisonbertram

Parent: #991

Summary

High-stakes run-control requests are fire-and-forget. Cancel, approve, deny, and answer use try? or otherwise discard failures. answer() removes pendingQuestions before the server acknowledges the response, and the form considers an answer complete based only on dictionary key count.

Evidence

  • macapp/Sources/GoCodeUI/RunSession.swift:128-149 — cancel/approve/deny swallow request failures.
  • RunSession.swift:169-173 — pending questions are cleared before an acknowledged answer and submission errors are swallowed.
  • macapp/Sources/GoCodeUI/ChatView.swift:813-855 — Send is enabled by answers.count; typing then deleting a required freeform answer leaves an empty value counted as complete.
  • The first failed cancel sets cancelRequested = true; the next click can abandon the stream locally while the server run continues.

Impact

The GUI can claim or imply that a decision was delivered when it was not. A pending question can disappear permanently on a transient failure, and a failed cooperative stop can turn the next click into a local-only force stop.

Scope

  • Introduce explicit pending/succeeded/failed action state for cancel, approve, deny, plan approval, and user answers.
  • Clear a pending question only after the server acknowledges the answer.
  • Validate trimmed non-empty required answers; preserve entered answers and focus on error.
  • Reset cancel escalation when the cooperative request fails.
  • Surface retryable errors inline at the action that failed and announce them accessibly.
  • Prevent duplicate submissions while a request is in flight.

Tests first

  • Stub-client tests for success, transport failure, structured server failure, retry, and duplicate-click suppression for each action family.
  • Regression: an answer failure keeps pendingQuestions and the answer draft.
  • Regression: an erased-to-empty freeform answer does not enable Send.
  • Regression: failed first cancel does not arm local force-cancel.

Acceptance criteria

  • No run-control endpoint failure is swallowed.
  • Pending questions remain visible and editable until acknowledged.
  • Empty required answers cannot be sent.
  • Action controls show in-flight state and reject duplicate requests.
  • Failure messages give a retry path and are VoiceOver-announced.
  • swift test, Swift build, formatting, strict format lint, and a live daemon control smoke pass.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingcorrectnessCorrectness bugs and logic errorsmacappNative macOS app (macapp/)mediumMedium effort: 1-3 daysreliabilityReliability and resilience concernswell-specifiedIssue is clear, scoped, and ready to implement

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions