Conversation
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
ApprovabilityVerdict: 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. |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
juliusmarminge
left a comment
There was a problem hiding this comment.
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
●●●plus24s. Three green dots with no legend means nothing to a user; the Agents tab already solves this with4 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, thensonnet-5 · 96.6k tok · 0 tools, with a check and duration on the right.Completedand 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 settledmono. 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:refreshwhile the badge saysSubagent of · Review session auth. The user's own workflow label islist: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 authwith 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,
[]vsundefinedframes) are correct; no action. applyWorkflowProgressWithoutTurnonly 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.
|
UI follow-up complete at 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. |
This comment has been minimized.
This comment has been minimized.
a1f8051 to
0337dd6
Compare
f31e78c to
7a238b3
Compare
|
Rebased this PR onto the current What changed on the branch
Verified
Left for you / a maintainer
Rebased and touched up by a maintainer's agent; a human will re-review. |
|
UI consistency review found one Posted via Macroscope — UI Consistency |
|
UI consistency review found one styled raw bulk-action button in Posted via Macroscope — UI Consistency |
This comment has been minimized.
This comment has been minimized.
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.
e155392 to
2017f24
Compare
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.
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.