Skip to content

feat(web): show Claude workflow phases and members in Lineage - #12598

Open
Bil0000 wants to merge 36 commits into
pingdotgg:t3code/codex-turn-mappingfrom
Bil0000:workflow-visualization-v2
Open

Bil0000 wants to merge 36 commits into
pingdotgg:t3code/codex-turn-mappingfrom
Bil0000:workflow-visualization-v2

Conversation

@Bil0000

@Bil0000 Bil0000 commented Sep 19, 2026 •

Copy link
Copy Markdown
Contributor

Claude workflows need to show their phases and member agents, with a way to open each result. This adds that view to the Lineage card and projects workflow progress into normal child threads.

A workflow coordinator stays an ordinary lineage row and gains a settled count beside its elapsed time plus a disclosure, using the split-row pattern the merge-back row already uses. Expanding it lists each phase as a header, closed by default, carrying its own wall clock, a status dot for running, failed, done or not started, and a settled count; the running phase is tinted so the active step is findable at a glance. A phase's time is the span from its first member starting to its last finishing, and it ticks while the phase is still running.

Opening a phase reveals its members as the same row every other subagent gets: provider glyph with status badge, title, elapsed time, and the shared hover card for model, status and result. Member rows open their own chat through the environment-scoped route. Phase headers share the member row's height, radius and columns, so a running phase's tint and a row hover draw the same band, and titles and trailing numbers line up down the whole tree. The lineage list keeps its compact height and only trades it for the taller tree while a workflow is open.

The server reads the bounded tail of each member transcript, preserves answer formatting, and settles remaining members when a workflow stops or fails. Existing workflow script RPC formats are preserved.

Validation for the UI update at 3eec9c7c69: the lineage tests pass, including navigation for every phase member, unphased members, phase titles, counts, reported status and phase duration, and per-phase collapse and reopen. Web type checking and targeted lint pass. In the real client with sample workflow data whose members start at staggered times, each phase reported a span wider than any single member's run, the running phase ticked, phase and member bands measured the same height, each phase opened on its own, every member row opened its own chat, and the hover card showed model, status, elapsed time and result. This UI update changes no server behaviour or wire format.

These are unedited screenshots from the running PR build with safe sample workflow data. They show the actual UI, not a live Claude workflow run.

Expanded workflow with its phases closed, each showing its duration, status dot and settled count, and the running phase tinted

Two phases opened, listing their member agents in the same row style as any other subagent

Hover card on the running member, whose row band matches the running phase's band

Julius still needs to re-review the changes; his earlier changes-requested review remains. Macroscope requires human approval for this feature.

Original implementation: Claude Opus 5 in Claude Code. Review fixes: GPT-6 in Codex. Lineage restyle: Claude Opus 5 in Claude Code.

@github-actions github-actions Bot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:XXL 1,000+ changed lines (additions + deletions). labels Sep 19, 2026
Comment thread apps/web/src/components/chat/ThreadLineageWorkflowRow.tsx Outdated
Comment thread apps/web/src/components/chat/ThreadLineageWorkflowRow.tsx Outdated
@macroscopeapp

This comment has been minimized.

Comment thread packages/contracts/src/orchestrationV2.ts
@macroscopeapp

This comment has been minimized.

Comment thread apps/server/src/orchestration-v2/Adapters/ClaudeAdapterV2.ts Outdated
Comment thread apps/web/src/components/chat/ThreadLineageWorkflowRow.tsx Outdated
Comment thread apps/server/src/orchestration-v2/Adapters/ClaudeAdapterV2.ts
Comment thread apps/server/src/orchestration/workflowAgentAnswers.ts Outdated
Comment thread apps/server/src/orchestration-v2/Adapters/ClaudeAdapterV2.ts Outdated
Comment thread apps/server/src/orchestration/workflowFileRead.ts
@macroscopeapp

This comment has been minimized.

@macroscopeapp

macroscopeapp Bot commented Sep 19, 2026 •

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Not approved

Macroscope's review found this PR not approvable — This PR introduces a substantial end-to-end workflow capability spanning Claude orchestration, persisted projections, filesystem-backed transcript reads, runtime state, contracts, recovery, and interactive Lineage UI. It also changes the initial phase-expansion behavior and adds static-analysis suppression directives, making human review appropriate.

You can add or adjust custom eligibility rules. Learn more.

Comment thread apps/server/src/orchestration/workflowAgentAnswers.ts
Comment thread apps/server/src/orchestration-v2/Adapters/ClaudeAdapterV2.ts
Comment thread apps/server/src/orchestration/workflowAgentAnswers.ts
Comment thread apps/server/src/orchestration-v2/Adapters/ClaudeAdapterV2.ts
@macroscopeapp

This comment has been minimized.

@macroscopeapp

This comment has been minimized.

@macroscopeapp

This comment has been minimized.

@juliusmarminge juliusmarminge left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed at 9aee040. The feature is worth having and the server-side design (members as ordinary subagents, additive merge, between-turn refresh) is the right shape. Two correctness problems block, and the UI needs another pass before this ships.

Blocking: correctness

1. Members never settle when the coordinator stops or fails.

Member status is derived only from member.state in the last snapshot (ClaudeAdapterV2.ts:3385). You cite the CLI emitter guard (status !== "running" → return) to argue no stale frame can arrive after the notification; I confirmed the guard is there in 2.1.236. The flip side is that when the run is interrupted, killed, or the script throws while members are start, the last snapshot is the one that says they are running, the task_notification arrives as stopped/failed, and neither updateClaudeSubagentNode nor applyWorkflowProgressWithoutTurn walks workflow.agents to close them. workflowMemberStates is never touched on coordinator terminal. Members also carry runId: null, so the run's interrupt cascade in RunExecutionService does not know about them either.

Result: press Stop on a running workflow and the coordinator row goes cancelled while every in-flight member row spins forever, and each member child thread keeps a root_turn node stuck running.

Fix: in the task_notification branch, when the coordinator goes terminal, map every member still running/queued to cancelled (stopped) or failed, emit the same node/subagent updates, and record them in workflowMemberStates. Test: existing wake harness, snapshot with a member in start, then task_notification with status: "stopped"; assert the member's last subagent.updated is terminal.

2. Truncated transcripts are the common case, not the edge case, and the fallback presents the excerpt as the final answer.

TRANSCRIPT_BYTE_CAP is 512 KiB and a truncated read returns [], so the capped resultPreview is emitted as the member's answer. On my machine 22 of 111 real workflow-member transcripts exceed 512 KiB, so roughly one in five members would get a few-hundred-character preview rendered as a complete assistant message in a thread that otherwise looks whole. The read is already positional; when stat.size > byteCap, read the tail 512 KiB instead of the head and drop the first partial line (the parser already tolerates a cut line). That recovers the final answer, which is the thing the user opened the thread for.

Blocking: UI

I looked at the three screenshots closely. It does not read as a finished T3 surface yet. Concrete things:

Lineage card

  • Phase headers (LIST 2/2, RANK 1/1) are uppercase mono in green while the member rows below them are proportional sentence case. Three type treatments inside one small tree. The panel's existing rows use one.
  • The coordinator row shows ●●● plus 24s. Three green dots with no legend means nothing to a user; the Agents tab already solves this with 4 done. Pick one vocabulary.
  • The collapsed rows (queue-choice, index-strategy) also show ●●● and a duration but give no indication they are workflows rather than plain subagents until you expand them. The Lineage list already had a way to show a subagent; this adds a second, different-looking row type next to it.
  • Member rows use a filled green dot as their icon while the coordinator uses the provider glyph and phases use a check. Three icon systems in a 4-level tree.

Agents tab

  • The phase rail (✓ Collect ●●●● › ✓ Check ●●●● › ✓ Wrapup ●) repeats the same information as the phase group headers directly below it (✓ COLLECT 4 done). One of the two should go; the group headers already scroll with the content and carry the count.
  • Every member row is three lines: title, Completed, then sonnet-5 · 96.6k tok · 0 tools, with a check and duration on the right. Completed and the check say the same thing, and a nine-member run becomes ~30 lines of near-identical text. One line per member (title left, model/tokens/duration right, status carried by the row icon) would show the whole run without scrolling.
  • Mixed mono and proportional again: titles proportional, metadata mono, phase labels mono uppercase, 9/9 settled mono. The rest of the app does not do this.
  • Collapsed workflow rows at the bottom (cache-review, retry-policy) look like a different component from the expanded card above them: no card, different padding, right chevron instead of a header disclosure.

Member thread

  • Breadcrumb says server / list:refresh while the badge says Subagent of · Review session auth. The user's own workflow label is list:refresh; the badge should name the workflow (or the coordinator) so the two agree. Right now the thread tells you which project it is in but not which workflow it belongs to.
  • The Lineage back-link at the bottom right says Review session auth with no indication it is a workflow, so you cannot tell you are inside a fan-out at all from this view.

I do not have a specific mockup to hand you. The direction I would take: one row type for a workflow member that matches the existing subagent row, phase grouping done with the panel's existing section-header style rather than a new mono uppercase label, drop the dot-strings in favor of n/m counts, and lose either the rail or the group headers. If it helps, do the UI as a follow-up PR on top of the server change once the two blockers above are fixed; the server piece can stand on its own.

Non-blocking, for the record

  • Your rebuttals on the Macroscope threads (symlink intermediate dir, task-id scoping, [] vs undefined frames) are correct; no action.
  • applyWorkflowProgressWithoutTurn only reaches the projection while the launching run's event subscription is still open, which holds because the coordinator subagent is non-terminal. Worth one comment line so nobody assumes it works after the run stream closes.

@Bil0000

Bil0000 commented Sep 21, 2026 •

Copy link
Copy Markdown
Contributor Author

UI follow-up complete at df6346235ab473342d1dfea1e725fd0aa5d988d9, on top of the maintainer rebase.

The Lineage workflow group now follows the Agents tab on main: a bordered group, status dots, activity previews, model and usage details, and elapsed time. Member rows open their normal chats. The workflow title and count use separate lines, and the list has more room. The shared row-style finding is fixed and resolved.

Validation: 16 focused UI/client tests passed, including every phase, failed/running members, unphased members, and collapse/reopen. Web type checking, targeted lint, and the web build passed. In the real client, all five sample members opened the correct chat, across all three phases; the parent workflow link also worked. Real before/after and member-chat screenshots are in the PR description. The screenshots use isolated sample data, not a live provider run.

Final CI is green on this SHA, including all three server shards. The earlier unrelated Git diff test failure did not reproduce locally and passes in this run. Macroscope correctness, Effect conventions, and UI consistency checks pass. No unresolved review threads or new actionable findings remain.

The PR is CLEAN and MERGEABLE. Julius still needs to re-review: his earlier changes-requested review remains, and Macroscope requires human approval for this feature. The PR remains open.

Comment thread apps/server/src/orchestration-v2/Adapters/ClaudeAdapterV2.ts
Comment thread apps/server/src/orchestration-v2/Adapters/ClaudeAdapterV2.ts
Comment thread apps/web/src/components/AgentsPanel.tsx Outdated
Comment thread apps/server/src/orchestration-v2/Adapters/ClaudeAdapterV2.ts
Comment thread packages/client-runtime/src/state/subagentRuntime.ts Outdated
Comment thread apps/server/src/orchestration/workflowAgentAnswers.ts
Comment thread apps/server/src/orchestration/workflowFileRead.ts
@macroscopeapp

This comment has been minimized.

@juliusmarminge
juliusmarminge force-pushed the t3code/codex-turn-mapping branch 2 times, most recently from a1f8051 to 0337dd6 Compare September 21, 2026 05:40
@Bil0000 Bil0000 changed the title feat: visualize dynamic workflows in the Agents tab and Lineage card feat(web): show Claude workflow phases and members in Lineage Sep 21, 2026
@juliusmarminge
juliusmarminge force-pushed the workflow-visualization-v2 branch from f31e78c to 7a238b3 Compare September 21, 2026 20:30
@juliusmarminge

Copy link
Copy Markdown
Member

Rebased this PR onto the current t3code/codex-turn-mapping at 4a4c22b29c.

What changed on the branch

  • The branch carried two merge commits from the base plus a number of base-branch commits that had since landed on v2 in their own form. I dropped all of that and cherry-picked only the 13 workflow-specific commits in their original order (from "capture workflow telemetry" through "retain reported workflow phase titles"). The server, contracts and client-runtime commits all applied cleanly; the expected conflicts in ClaudeAdapterV2.ts, Orchestrator.ts, ProjectionStore.ts, ProviderFailure.ts and TurnStartReads.test.ts did not materialize because v2 already contains the same base commits.
  • apps/web/src/components/AgentsPanel.tsx was removed on v2 (refactor(web): remove the agents right panel #12835), so every change to it was dropped. That includes the whole of "keep pending agent tooltips accessible" (4979d689c8), which only touched that file, and the Agents-tab halves of "correct member timing..." and "simplify workflow rows and phase groups". The Lineage-card path (ThreadLineageWorkflowRow.tsx, ThreadRelationshipsControl.tsx) is intact. ThreadRelationshipsControl.tsx needed two small merges: the AgentElapsed import now comes from ./AgentElapsed (where v2 moved it), and the shared relationshipLink uses v2's RelationshipPopup (hover card for subagents) instead of the plain TooltipPopup.
  • One commit of my own on top: ThreadLineageWorkflowRow.tsx imported AgentElapsed from ../AgentsPanel; it now imports from ./AgentElapsed.
  • 47084b9698 ("load shared checkpoint scopes for queued turns") was left out. v2 already has an equivalent fix in ProjectionStore.ts (the checkpoint scope query now selects by the nodes' checkpointScopeId values), so it is not needed here. If you think there is still a gap, please open it as a separate PR.
  • I read the "settle workflow members when the coordinator's turn stops" logic (ee94883211 / c7a850fb28) in the rebased ClaudeAdapterV2.ts; the run-id guard and failed/cancelled mapping are present.

Verified

  • vp test run in apps/server for ClaudeAdapterV2.test.ts, claudeWorkflowProgress.test.ts, workflowAgentAnswers.test.ts, workflowScriptQuery.test.ts: 146 passed.
  • vp test run src/state/subagentWorkflowProjection.test.ts in packages/client-runtime: 13 passed.
  • vp test run for ThreadRelationshipsControl.test.tsx and ThreadRelationshipsControl.agents.test.tsx in apps/web: 6 passed.
  • vpr typecheck in packages/contracts, packages/client-runtime, apps/server, apps/web: clean.

Left for you / a maintainer

  • The Agents-tab half of this PR no longer has a target; the PR title and description should drop it and describe only the Lineage card.
  • No browser pass was done on the Lineage rendering after the rebase.

Rebased and touched up by a maintainer's agent; a human will re-review.

Comment thread apps/web/src/components/chat/ThreadRelationshipsControl.tsx
@macroscopeapp

macroscopeapp Bot commented Sep 21, 2026

Copy link
Copy Markdown
Contributor

UI consistency review found one Button height override in ThreadRelationshipsControl.tsx; the inline review comment identifies the shared size or panel variant fix.

Posted via Macroscope — UI Consistency

Comment thread apps/web/src/components/chat/ThreadLineageWorkflowRow.tsx Outdated
@macroscopeapp

macroscopeapp Bot commented Sep 21, 2026 •

Copy link
Copy Markdown
Contributor

UI consistency review found one styled raw bulk-action button in ThreadLineageWorkflowRow.tsx; the inline review comment identifies the shared Button variant fix. The per-phase semantic disclosure rows are not included in this finding.

Posted via Macroscope — UI Consistency

@macroscopeapp

This comment has been minimized.

Bil0000 and others added 29 commits September 25, 2026 13:02
AgentsPanel was removed on the v2 branch (pingdotgg#12835); the Lineage workflow row
now imports AgentElapsed from ./AgentElapsed.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The workflow card stacked its own three-line rows, status dots and mono
metadata inside Lineage, so an expanded workflow looked nothing like the
subagent rows beside it.

Members now use the same row as every other subagent: provider glyph with
status badge, title, elapsed time, and the shared hover card for model,
status and result. Phases become small labels with a settled count, the
coordinator carries "settled/total" beside its elapsed time, and its
disclosure reuses the existing split-row pattern instead of a bespoke
height override.
An expanded workflow opened every phase at once, so a long run pushed its
own coordinator row out of view.

Phases now start closed and each header toggles its own members, with an
Expand all / Collapse all control above them when a workflow has more than
one phase.
Phase headers only carried a settled count, so a long workflow gave no
sign of which step was running, and their chevron sat in the trailing
column where member rows put elapsed time.

Each phase now carries a status dot for running, failed, done or not
started, and the running phase is tinted so the active step is findable
at a glance. Its chevron moved to the leading glyph column, and the
nested list reserves the coordinator's disclosure width, so phase titles
line up with member titles and every count lines up with every elapsed
time. The Expand all control is gone with the alignment it cost.
A phase reported how many of its members had settled but not how long it
ran, so the only timings in the tree were per member and per workflow.

Each phase header now carries its own wall clock, the span from its first
member starting to its last finishing, ticking while the phase is still
running. Phase groups also gain a small gap so a long tree reads as steps
rather than one list.
A phase header was shorter than a member row, so the running phase tint
and a row hover drew two different bands, they touched with no breathing
room, and the gap between phases was wider than the tree needed.

Phase headers now use the member row's height and radius, the member list
starts a hair below its header, and the gap between phases is smaller. A
settled phase whose members never reported an end instant no longer
reports a span measured against the current time.
@juliusmarminge
juliusmarminge force-pushed the workflow-visualization-v2 branch from e155392 to 2017f24 Compare September 25, 2026 20:03

This branch has not been deployed

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

Labels

size:XXL 1,000+ changed lines (additions + deletions). vouch:trusted PR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants