Skip to content

[Bug]: Mobile looks idle while background subagents are still working #4962

Description

@Zeus-Deus

Before submitting

  • I searched existing issues and did not find an exact duplicate.
  • I included enough detail to reproduce or investigate the problem.

Area

apps/mobile

Steps to reproduce

  1. Open a thread in the native mobile app.
  2. Start a provider turn that launches a background subagent/task.
  3. Let the parent/foreground turn emit a final-looking assistant message and settle while the child task continues running.
  4. Keep the thread open or return to the mobile thread list.
  5. Observe the thread until the child sends another update or completes.

Use synthetic project, thread, task, and branch names when testing.

Expected behavior

Mobile should continue to show that work is in progress while any child/background task belonging to the thread is active.

At minimum:

  • the thread list should remain in a visible Working state;
  • the open thread should show a persistent indicator such as Background task working or 1 subagent active;
  • a completed-looking parent response or Worked for ... fold must not make the whole thread look idle while child work continues;
  • the indicator should clear only when the outstanding background tasks complete, fail, or are cancelled.

Actual behavior

The mobile UI can look completely idle after the parent turn settles even though a background subagent is still running. The open thread shows a completed-looking Worked for ... section and normal composer, with no durable child-work indicator. The thread list can also resolve to ready.

When the child later emits another provider update, the parent session may become running again and the ordinary working UI returns. This creates an intermittent idle/working presentation that does not represent the actual aggregate workload.

Impact

Major UX degradation for delegated work. Users cannot tell whether the agent stopped, finished, or is still changing files and running tests in the background. Sending another prompt can also queue or steer work unintentionally.

Version or commit

Current upstream main at 90f3913a.

Environment

Native mobile app on iOS with a remote T3 environment. This is a presentation/state-aggregation issue and should be testable without a physical iOS device.

Source observations

The orchestration stream already records child lifecycle activity such as:

  • task.started
  • task.progress
  • task.completed
  • collab_agent_tool_call with an in-progress lifecycle

However, mobile derives aggregate activity from the parent session/latest turn:

  • resolveThreadListV2Status() reports working only when thread.session.status is running or starting.
  • resolveThreadStatus() has the same parent-session dependency.
  • use-thread-composer-state.ts derives activeWorkStartedAt from latestTurn plus the parent session.
  • deriveWorkLogEntries() intentionally omits task.started, so an outstanding child has no durable row until progress is emitted.

A background task can outlive the parent turn/session's foreground-running state. Consequently, the server has enough child lifecycle evidence to know work remains, but the mobile list/screen has no aggregate outstanding-task state to render.

Suggested regression coverage

Add deterministic tests using synthetic IDs for:

  1. parent turn running + child task started → Working;
  2. parent turn ready/completed + child still started/in-progress → still Working/background task active;
  3. child emits progress while parent is ready → indicator remains active and can show the latest safe summary;
  4. child completed/failed/cancelled → indicator clears;
  5. multiple child tasks → clears only after the last task settles;
  6. stale or duplicate lifecycle events do not leave a permanent Working state.

The fix may require projecting an aggregate outstanding-background-task count/status onto the thread shell, because thread-list rows do not carry the full activity history.

Related issues checked

Privacy

No private screenshot is attached. Reproduction tests and fixtures should use only synthetic identifiers and content.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions