Skip to content

iOS history conflates sandbox liveness with outcome and labels failed sessions Done #286

Description

@yxlyx

Summary

The iOS history list can label a failed cube session Done (green check) solely because its sandbox is not currently started. Sandbox liveness is not a reliable task outcome, and a failed sandbox-list request is also treated as if every cube were not started.

Physical-device observation

Environment:

  • Graff iOS 0.1
  • iPhone 16 Pro Max, iOS 26.5.2
  • Account-synced cube session

The physical-device accessibility snapshot showed the session row as:

canvaspilot, Done, codegraff, cube, 3 hr ago

At the same time, the current synced transcript ended in four entries with:

Transport error: The network connection was lost.

The associated sandbox was stopped. A stopped sandbox caused the row to present the work as successfully Done, despite the persisted failed turns.

Root cause

SessionsListView.loadHistory() reconstructs account-history status from sandbox liveness only:

let live = (try? await Gateway.sandboxes()) ?? []
let started = Set(live.filter { $0.state == "started" }.map(\.id))
// ...
s.status = started.contains(sb) ? .idle : .done

This has two incorrect implications:

  1. Every stopped, gone, pending, or otherwise non-started sandbox means the agent completed successfully.
  2. Any Gateway.sandboxes() error is suppressed to [], which labels every cube-backed row Done.

AppSessionRow has no persisted outcome field, so the list cannot distinguish success, transport failure, interruption, or unknown state.

Expected behavior

  • Done must represent a persisted successful terminal outcome, not the absence of a running sandbox.
  • A transport-failed or interrupted turn should be surfaced as failed/needs attention.
  • Sandbox liveness should be displayed separately from task outcome.
  • Failure to load sandbox state should remain unknown and must not become Done.

Acceptance criteria

  • A stopped sandbox alone never changes a session outcome to Done.
  • A failed sandbox-list request does not manufacture successful statuses.
  • Successful, failed/interrupted, active, and unknown outcomes have distinct persisted representations.
  • The physical-device case above renders failed/needs attention, not Done.
  • Tests cover stopped/gone sandboxes and a failed Gateway.sandboxes() request.

Related

Metadata

Metadata

Assignees

Labels

No labels
No labels

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions