Skip to content

feat(workflows): run workflows with native threads, evidence, and recovery - #31

Open
Igloczek wants to merge 5 commits into
workflows/25-library-editorfrom
workflows/26-run-experience
Open

Igloczek wants to merge 5 commits into
workflows/25-library-editorfrom
workflows/26-run-experience

Conversation

@Igloczek

@Igloczek Igloczek commented Oct 9, 2026 •

Copy link
Copy Markdown

Closes #26 · Parent spec #3 · Stack layer 2/5 (base: #30 workflows/25-library-editor)

Rebuilt on the redesigned editor

The maintainer rejected the first UI after a browser review, and #25 was redesigned around a React Flow graph and native page chrome. This layer was replayed onto that base as a single commit and redesigned to match:

  • Runs list: settings-style rows with status icons.
  • Run workflow: a modal dialog with a single searchable workflow picker.
  • Run view: the read-only graph with a run-state overlay. It shows per-step status, ×N visit counts, and taken routes drawn bold, matched exactly for decision/join rules and by repeat kind for other routes. A one-line overview sits above the graph; compact timeline route history and an inspector with a collapsed Details section sit beside it.
  • Feedback: applied decisions show as toasts.
  • Chat header: the thread strip and the Run workflow action use chat-header chrome.

New generic host primitives: Dialog, Combobox, Tooltip, toast. Server, contracts and RPC are byte-identical to the previously approved layer.

Problem

Saved workflows could be authored but not started, inspected, or recovered from the client, and native T3 threads had no link back to the workflow attempt that owns them.

What this adds

  • One Run dialog from the library and the project header action (workflows.project-run):
    • The server resolves the saved identity and revision (plugins.workflows.launch → Workflow.startSaved); the client never sends a definition body.
    • Bounded task input, an execution preview from cached discovery, and a workspace choice: new worktree (default) or current checkout.
  • Idempotent start:
    • One immutable request ID per start intent, persisted in the host draft store and resent automatically on reload and reconnect.
    • The server checks the stored result before the catalog, so a lost response plus a catalog edit still gives one run.
    • The intent is released only on an authoritative workflow-service rejection. A pending intent for another workflow is shown with Retry/Discard instead of being auto-sent.
  • Run page:
    • Reuses the editor's Flow and Route list read-only, with Run steps, an evidence inspector, and a server-computed overview (visits, active attempts, review report-vs-settled counts, next action).
    • History opens newest-first. Visit and route history page independently, and the routing records related to a visit always travel with its page.
    • Deep links keep the exact run, node, branch and attempt; the server opens the page containing a deep-linked attempt.
  • Evidence:
    • Accepted reports are shown as claims, separate from execution settlement and check evidence.
    • Truthful missing, failed and interrupted states; recorded predicates and matches, chosen edges, repeat counters and limits. The client does no route evaluation.
  • Live, scoped updates:
    • A view-scoped watch stream and a streaming thread link, woken only by the affected run or binding through in-memory versions.
    • A failed stream marks the view "Not updating" and disables actions until Retry.
  • Native thread strip (workflows.thread): identifies the workflow, run, node and attempt, with Open workflow run and View route.
    • It is keyed per thread, updates live, and shows its last loaded state when disconnected.
    • Later manual messages don't reopen old attempts; threads not owned by a workflow are unaffected.
  • Actions:
    • Only the engine's allowedActions plus target permission: Cancel, Resume and Retry (via the server-owned Run.recovery target), and revision-bound gate decisions.
    • A stale response refreshes the view and explains itself. An unresolved gate result explains why ("Your decision was not applied: The pull request head changed after review.").
    • Server attention links carry the exact run selection.

Validation

  • Server (Bun): WorkflowsRun.integration.test.ts 9/9. Covers:
    • saved start, lost response plus catalog edit, Run again
    • recovery targets
    • cancel vs completion in both orderings
    • 57-visit paging and route reachability
    • deep-linked attempt pages
    • live thread links
    • restart
  • Server workflow suite: all pass except 6 cases (WorkflowsMissingReportTime lostack-*, WorkflowsTimeout committed-crash). These fail identically on the Browse, author, and save workflows in one editor #25 base (verified in a temporary worktree at d80dcd1).
  • Web integration (Bun, real servers, authenticated WebSocket, two environments) — WorkflowRun, WorkflowAuthoring, PluginClientPermissions, PluginPage, PluginClient and PluginReconnect all pass. Covers:
    • both start entry points
    • reconnect auto-reconcile
    • held-cancel race
    • frozen-head gate
    • stale-stream Retry
    • thread switch and strip staleness
    • run-history boundary
    • read-only vs operate tokens
    • subscription cleanup
  • Unit: run.test.ts (step states, taken routes) + flowGraph.test.ts + editing.test.ts pass after the rebuild.
  • Unit: plugin and web plugin tests pass. Typecheck, lint and fmt are clean for touched packages.

Independent review

Rounds 4–6 reviewed the rebuilt layer:

  • Round 4 found a MAJOR: a run stopped or canceled at a gate showed that gate as "Not visited". It also found minors: two different visit counts, false "Not visited" on paged history, View route focus in graph view, and truncated check output.
  • Round 5 approved a40b5638a5 with one minor: an Approve route lit a repeat's At-limit edge when both reached the same step. That was fixed with a test.
  • Final verdict, round 6: APPROVED 7b3d34606c1f007dd7209467997bcc0ba4238530. One nit remains: a repeat route sent to the whole-run limit, when that limit is the same step as the repeat's own At-limit, lights the .repeat edge.

Earlier, on the pre-redesign base: three rounds by a separate Claude Opus 5.5 reviewer. All five round-1 MAJORs were fixed:

  • the thread strip leaking across threads
  • the stale strip
  • the wrong attempt on deep links
  • unreachable route history
  • stale actions after a stream failure

Final verdict: APPROVED 0dc217d8bab4407ce577b69b207e34f580483248. Remaining NITs: no test for the thread-stream failure + Retry path or for the unchanged-link skip; Retry is shown but inert while offline after an earlier failure.

UI evidence

Verified live in a real browser (agent-browser, isolated dev server, scratch project) with a no-agent workflow: two checks → human gate. The flow was:

  • start from the library row in the Run dialog;
  • the checks complete;
  • the gate waits;
  • Request changes repeats (×2, back edge taken);
  • Approve completes, with a toast;
  • a second run canceled at the gate shows the gate as Stopped, with the reason.

Screenshots are attached separately. The thread context strip couldn't be exercised live without agent threads; its behaviour is covered by WorkflowRun.integration.test.tsx.

Limitations

Implemented by Claude Opus 5.5 implementation agents and reviewed by an independent Claude Opus 5.5 agent (gilfoyle), orchestrated in Claude Code running in T3 Code.

🤖 Generated with Claude Code

@Igloczek
Igloczek added this pull request to stack #32 October 9, 2026 01:02
@Igloczek
Igloczek force-pushed the workflows/26-run-experience branch 3 times, most recently from 7b3d346 to d4fef87 Compare October 10, 2026 07:16
@Igloczek
Igloczek marked this pull request as ready for review October 10, 2026 13:07
@Igloczek
Igloczek force-pushed the workflows/26-run-experience branch 2 times, most recently from 32715d6 to 6f3a356 Compare October 10, 2026 18:04
Igloczek and others added 5 commits October 10, 2026 20:23
…overy

Start saved workflows from a run dialog, follow each run on the read-only workflow graph
with per-step state, taken routes and repeat counts, inspect each visit's thread, report,
check result and routing, act on human gates and recovery, and link owned threads back to
their run from the chat header. Rebuilt on the redesigned #25 editor and page chrome.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Show a step the run stopped at as stopped, light only the routes the recorded routing
took, use one visit count, mark steps outside the loaded history page, land View route
focus in the graph, and show full check output.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ken edges

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… in run views

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…helper

Address #26 post-sync review: drop the stale publication doc comment and
replace three copy-pasted stream families with one typed helper.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@Igloczek
Igloczek force-pushed the workflows/26-run-experience branch from 6f3a356 to f92222d Compare October 10, 2026 18:23

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

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Run workflows with native threads, evidence, and recovery

1 participant