Skip to content

[Bug]: ACP plan drops a CANCELLED task's entire subtree, hiding its live subtasks #173

Description

@julianmesa-gitkraken

What happened?

The recursive walk that converts Auggie's task tree into ACP plan entries returns early on a CANCELLED task, before recursing into its subtasks. From the bundle (augment.mjs 0.36.0):

function CTr(t,e=[],n=0){
  if(t.state==="CANCELLED") return e;                       // ← returns before the recursion
  if(n>0) e.push({content:t.name, priority:K8o(n), status:j8o(t.state)});
  if(t.subTasksData && Array.isArray(t.subTasksData))
    for(let r of t.subTasksData) CTr(r,e,n+1);
  return e;
}

Consequences:

  1. A cancelled parent silently deletes its live children from the plan. Cancel a phase that still has NOT_STARTED or IN_PROGRESS subtasks under it, and every one of those subtasks vanishes from the ACP plan the client renders, even though Auggie still tracks them and may still work on them. The client shows a plan that is missing real work.
  2. Entries disappear rather than resolve. ACP plan entries are positional in most clients; dropping a subtree mid-run makes the list shrink and the remaining steps shift, which reads as corruption rather than as a cancellation.

There is also dead code just below: j8o has a case "CANCELLED": return "pending", but CTr filters cancelled tasks out before ever calling it, so that branch is unreachable for a cancelled node itself.

What did you expect to happen?

Skip the cancelled node's own entry, but keep walking its subtasks:

function CTr(t,e=[],n=0){
  const cancelled = t.state === "CANCELLED";
  if(!cancelled && n>0) e.push({content:t.name, priority:K8o(n), status:j8o(t.state)});
  if(t.subTasksData && Array.isArray(t.subTasksData))
    for(const r of t.subTasksData) CTr(r, e, cancelled ? n : n+1);
  return e;
}

Alternatively, if hiding a cancelled subtree wholesale is the intent, cascade the cancellation in the task store so Auggie's own tree and the emitted plan agree — today they diverge.

Worth deciding separately: ACP PlanEntryStatus has no cancelled member, so a cancelled task genuinely has no faithful representation. Dropping it is defensible for a leaf; dropping its live descendants is not.

Steps to reproduce

  1. Run Auggie in --acp mode.
  2. Have it create a nested task list — a parent with several subtasks.
  3. Cancel the parent (update_tasks with state: CANCELLED) while its subtasks are still NOT_STARTED/IN_PROGRESS.
  4. Observe the next plan session update: the parent and all of its subtasks are gone, not just the parent.

Auggie version

0.36.0 (commit 7c61e5bb)

Environment details

macOS, Node v24.20.0, npm @augmentcode/auggie, --acp mode driven by an ACP client (GitKraken Kepler).

Anything else we need to know?

Found while tracing a separate stale-plan problem in the same code path; this one is static analysis of the bundle rather than an observed incident, since the session I was debugging had no cancelled tasks.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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