Skip to content

fix(workflows): keep follow-up Working visible - #2057

Merged
flora131 merged 4 commits into
mainfrom
fix/workflow-followup-working-lifecycle
Jul 29, 2026
Merged

fix(workflows): keep follow-up Working visible#2057
flora131 merged 4 commits into
mainfrom
fix/workflow-followup-working-lifecycle

Conversation

@flora131

@flora131 flora131 commented Jul 29, 2026

Copy link
Copy Markdown
Collaborator

Summary

Keep the attached workflow-stage Working indicator visible for workflow-authored follow-up turns from admission through retained-session restore, prompt startup, pre-turn compaction, and agent handoff. Correlated delivery ownership also prevents late or overlapping lifecycle events from clearing or restarting the indicator at the wrong time.

Changes

  • Add a workflow delivery-activity channel with replay for late attach and remount.
  • Start Working before lazy retained-session restore and settle it on success, no-turn, failure, replacement, or disposal.
  • Preserve Working through pre-turn compaction and restore the terminal stale-event fence after the final delivery settles.
  • Prevent one overlapping delivery from clearing a lifecycle generation still owned by another delivery.
  • Cover direct attach, late attach, post-mortem restore, pause, terminal races, overlapping leases, compaction, stale events, and cleanup with deterministic tests.
  • Update the workflow UI contract and [Unreleased] changelog entry.

Validation

  • Focused lifecycle suite: 146 passed, 0 failed
  • bun run test:unit: 4,386 passed, 2 skipped, 0 failed
  • bun run test:integration: 288 passed, 1 skipped, 0 failed
  • bun run typecheck: passed
  • bun run lint: passed
  • bun run check:file-length: passed
  • bunx tsgo -p packages/coding-agent/tsconfig.build.json --noEmit: passed
  • git diff --check origin/main...HEAD: passed
  • Two fresh reviewers approved the final repair.

Tmux evidence

This is the exact tmux capture-pane output from a fresh deterministic terminal replay. It runs the real workflow delivery channel and StageChatView lifecycle in a Bun test harness; it is not a live-provider/full Atomic CLI screenshot. The replay proves that Working remains visible while delivery B still owns the reconciled lifecycle, clears after the final settlement, and cannot be restarted by a stale terminal event.

Fresh tmux replay
AGENT=1 bun test /tmp/workflow-overlap-review-opus.test.ts; echo "EXIT=$?"
bun test v1.3.14 (0d9b296a)

../../../../private/tmp/workflow-overlap-review-opus.test.ts:
delivery_start A (workflow-authored sendUserMessage accepted)
delivery_start B (overlapping accepted delivery)
pre-turn compaction reconciled -> status: ∀ Working...
after settling A (B accepted, agent_start still pending) -> glyph=true animation=true status: ∀ Working...
B public agent_start -> animation=true
after final settlement -> glyph=false animation=false status: <no status line>
stale post-terminal start -> glyph=false animation=false
REVIEWER REPLAY OK

 1 pass
 0 fail
Ran 1 test across 1 file. [2.89s]
EXIT=0

A second independent tmux replay produced the same state sequence:

delivery_start A
delivery_start B
compaction_start
compaction_end / reconciled
after first settlement: Working=true, animation=true
after final settlement: Working=false, animation=false
stale terminal start: Working=false, animation=false
1 pass, 0 fail, EXIT=0

Notes

No package versions or generated artifacts changed. Commits are conventional and carry Assistant-model attribution.


View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need. Autofix is disabled.

Greptile Summary

Implements a correlated delivery-activity lifecycle for workflow-authored follow-up turns.

  • Replays active delivery leases when a stage chat attaches or remounts.
  • Keeps Working visible through retained-session restoration, prompt startup, compaction, and agent handoff.
  • Coordinates overlapping delivery ownership and fences stale lifecycle events after terminal settlement.
  • Adds deterministic unit and integration coverage plus workflow documentation and changelog updates.

Confidence Score: 5/5

The PR appears safe to merge.

No blocking failure remains.

T-Rex T-Rex Logs

What T-Rex did

  • Baseline revision failed both integration lifecycle cases because Working was absent before agent_start.
  • The PR revision passed both integration lifecycle cases.
  • The complete focused plan passed 27/27 tests with exit code 0.
  • Four log artifacts were uploaded to document the test results and evidence.

View all artifacts

T-Rex Ran code and verified through T-Rex

Important Files Changed

Filename Overview
packages/workflows/src/runs/foreground/stage-delivery-activity.ts Adds correlated active-delivery leases with synchronous replay for late subscribers and deterministic settlement.
packages/workflows/src/runs/foreground/stage-runner-controller.ts Integrates retained-session preparation and delivery activity with serialized message admission and disposal.
packages/workflows/src/runs/foreground/stage-runner-send-user-message.ts Emits activity around admitted idle delivery paths while leaving streaming follow-up and steering deliveries under the existing turn lifecycle.
packages/workflows/src/tui/stage-chat-view-delivery-activity.ts Maps correlated delivery leases onto host lifecycle generations, including overlap, compaction reconciliation, and terminal fencing.
packages/workflows/src/tui/stage-chat-view-live-events.ts Reconciles delivery-owned activity after compaction and suppresses stale terminal lifecycle starts.
packages/workflows/src/tui/stage-chat-view-state.ts Subscribes to delivery activity before SDK events and cleans up lifecycle state during terminal transitions and disposal.
packages/coding-agent/src/modes/interactive/components/chat-session-host-runtime.ts Exposes generation-aware APIs for beginning, reasserting, and settling externally submitted prompt activity.

Sequence Diagram

sequenceDiagram
  participant Workflow
  participant Controller as StageSessionController
  participant Activity as StageDeliveryActivity
  participant View as StageChatView
  participant Host as ChatSessionHost
  participant Session as AgentSession
  Workflow->>Controller: sendUserMessage()
  Controller->>Activity: delivery_start(id)
  Activity-->>View: delivery_start(id)
  View->>Host: beginExternalPromptLifecycle()
  Host-->>View: lifecycle generation
  Controller->>Session: restore and deliver prompt
  Session-->>View: compaction / agent lifecycle events
  View->>Host: reconcile lifecycle after compaction
  Session-->>Controller: delivery settles
  Controller->>Activity: delivery_settled(id)
  Activity-->>View: delivery_settled(id)
  View->>Host: settle lifecycle after final owner
Loading

Reviews (2): Last reviewed commit: "Merge origin/main into fix/workflow-foll..." | Re-trigger Greptile

flora131 added 3 commits July 28, 2026 14:53
An attached workflow-stage chat sat idle while a workflow-authored idle
follow-up was already running: nothing told the chat a delivery had been
admitted until the public agent_start cleared the session's ordered
extension event queue.

Report accepted idle-delivery start and settlement on a workflow-internal
channel and map it onto the chat's ordinary Working lifecycle. The channel
replays active deliveries to late subscribers, so attaching or remounting
mid-delivery paints immediately. A pre-turn compaction_end reasserts the
lifecycle for a still-active delivery while preserving factual status text,
and a terminal transition drops its pre-terminal leases so a leftover
agent_start or turn_start cannot restart Working on a finished stage.

Live-turn followUp/steer queueing, controlled pause, terminal-root
rejection, post-mortem chat, and retry/fallback/compaction/error status
precedence are unchanged.

Assistant-model: Claude Opus 5
Start one correlated delivery lease before lazy session preparation while preserving the final SDK admission guard. Rearm stale lifecycle fencing after the last post-terminal delivery settles.

Assistant-model: GPT-5.6 Sol
A pre-turn compaction_end clears the host Working lifecycle, so the stage
chat reasserts one lifecycle and writes that same generation into every
delivery lease still open. Two overlapping workflow-authored deliveries
then aliased one token, and settling the first one called
settleExternalPromptLifecycle() with the current generation, stopping
Working and its animation while the second lease was still accepted and
its public agent_start still pending.

Settle a host generation only when no remaining active lease references
that exact token. Distinct generations, including stale ones, still reach
the host's own generation fence unchanged, and the terminal stale-start
fence stays map-wide so it rearms only after the last lease settles.

Assistant-model: Claude Opus 5
@mintlify

mintlify Bot commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

Preview deployment for your docs. Learn more about Mintlify Previews.

Project Status Preview Updated (UTC)
bastani 🟢 Ready View Preview Jul 29, 2026, 12:39 AM

💡 Tip: Enable Workflows to automatically generate PRs for you.

# Conflicts:
#	packages/coding-agent/CHANGELOG.md
@flora131
flora131 merged commit a1d233c into main Jul 29, 2026
10 checks passed
@flora131
flora131 deleted the fix/workflow-followup-working-lifecycle branch August 14, 2026 01:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant