Skip to content

refactor(*): the dag card hands its graph to the desk task pane - #611

Merged
gloryfromca merged 2 commits into
refactor/ui_web_architecturefrom
refactor/dag_card_opens_desk_task
Sep 21, 2026
Merged

gloryfromca merged 2 commits into
refactor/ui_web_architecturefrom
refactor/dag_card_opens_desk_task

Conversation

@0xKT

@0xKT 0xKT commented Sep 21, 2026

Copy link
Copy Markdown
Member

Summary

The orchestration card in the transcript (a run_subagent_dag or load_playbook
row, expanded) drew a graph of its own and, under it, a node panel whose "open the
run" link raised the old agents-panel record window. The desk's task pane already
draws the same graph and reads the same dag.node record, node by node, so the
card was a second renderer for work the desk owns. The prototype's card is the grid
alone, with the task cell as the door to the run. This PR makes the card that.

Two commits, the second deleting only what the first killed:

  1. The card hands its graph to the desk. The card keeps its grid (task, scale,
    playbook, state, cost, run id, replanned-into) and nothing else. The task cell is
    a door -- role=button, a title, a standing arrow -- whenever the run has an
    id, and opens the run's task pane on the desk. openDagRun goes through the
    tasks seam: openRun when the tasks store holds the row, one tasks.list read
    when it does not, the tasks tab when neither answers (a branched conversation
    replaying its parent's delivered row lands there). The delivered row already
    went through openDagRun and follows. The node panel, the openDagNode seam,
    features/dag/open.ts, the 21 catalogue keys only the panel read and the
    dag-renderer gate go.
  2. The renderer's default box goes. The desk's board is DagGraph's only
    caller and hands it its own node card, so the default SVG box, the card
    surface, the label trimming, the mark table and the per-node clock had no
    reader left.

User-visible changes besides the door: the first failed node is no longer opened
unasked inside the card (the desk pane's failure banner names it, one click away);
a node's internal dependencies are read off the board's edges rather than a list;
the node id, which the deleted panel spelled out, rides on the desk node panel's
title.

Left for a follow-up, deliberately: features/dag/mount.ts and store.ts (the run
state state/session/resume.ts still writes and nothing reads) -- deleting them
means either a new row on domain-shape's shrink-only exceptions or dissolving
features/dag/ into its two remaining consumers, which is a decision of its own.

Type

  • Fix
  • Feature
  • Docs
  • CI / tooling
  • Refactor
  • Other

Verification

  • npm test --prefix ui-web -- 188 files, 2464 tests, all pass (three suites
    fewer than the base: the two deleted gates and the deleted label suite)
  • npm run type-check --prefix ui-web -- clean
  • npm run lint --prefix ui-web -- 0 errors (4 pre-existing warnings in
    CronPage/SubagentsPage, untouched here)
  • node ui-web/scripts/check-class-namespace.mjs -- OK; the transcript and dag
    pins lowered to what the tool prints
  • npm run --prefix ui-tui lint:i18n -- generated catalogue up to date
  • npm run --prefix ui-web build && python3 ui-web/build.py -- boot-snapshot OK
    (235 nodes match golden)

Driven on a real host (raven serve from this branch on an isolated RAVEN_HOME
built from a real config, deepseek as the default model, every channel off), with
a playwright driver against the served page:

Step Result
Expand the card of a running three-node graph grid only, no graph, no node panel; task cell is role=button with a title and the arrow; a long title is cut and the arrow stays in view
Click the task cell exactly one desk pane, task:dag:<run_id>, headed by the run's summary, showing the board
Click a node on the board the desk's node panel with the node's record
Click the task cell again no second pane
Click the delivered row after the run settles the same pane
Reload, expand the restored card, click the same pane
A graph with one node on a lane that cannot reach its model the card's state row counts 1 failed; the desk pane shows the failure banner before any node is picked; the banner opens the failed node
The board before and after commit 2 screenshots identical (node cards, edges, lane frames)
  • Relevant tests pass locally
  • Relevant lint / type checks pass locally
  • User-facing docs or screenshots are updated when needed

Risk

Web UI only; no server or wire change. The transcript card loses its graph and
node panel on purpose; every fact they showed is on the desk's task pane, reached
from the card's task cell and from the delivered row. features/dag/mount.ts keeps
running unchanged. Rollback is reverting the squash commit.

  • Security impact considered
  • Backward compatibility considered
  • Rollback path is clear for risky changes

Related Issues

N/A

0xKT and others added 2 commits September 22, 2026 00:41
The orchestration card in the transcript drew its own graph and, under it,
a node panel whose "open the run" link raised the old agents-panel record
window. The desk's task pane already draws the same graph and reads the
same dag.node record, node by node, so the card was a second renderer for
work the desk owns. The prototype's card is the grid alone, with the task
cell as the door to the run.

- The card keeps its grid and nothing else. The task cell is a door
  (role=button, title, a standing arrow) whenever the run has an id, and
  opens the run's task pane on the desk; a playbook load has it as soon as
  dag.run_started names the run, before dag.get supplies a title.
- openDagRun goes through the tasks seam: openRun when the store holds the
  row, one tasks.list read when it does not, the tasks tab when neither
  answers. The delivered row already went through openDagRun and follows.
- The node panel, its inputs and template rows, the openDagNode seam and
  features/dag/open.ts go; so do the 21 catalogue keys only the panel read,
  the dag-renderer gate whose CSS is gone, and the four import-direction
  rows those imports held.
- The desk's node panel carries the node id on its title, which the
  deleted panel used to spell out; the first failed node is no longer
  opened unasked -- the desk pane's banner names it.
- Five binding tests for dagFeed read the node states through a test seam
  now that the card draws none.

Co-authored-by: Claude (claude-sonnet-5) <noreply@anthropic.com>
Co-authored-by: Claude (claude-fable-5-1) <noreply@anthropic.com>
With the transcript card gone, the desk's task board is DagGraph's only
caller and it hands the renderer its own node card. The default SVG box
-- rect, status mark, two-line label, tooltip -- its card surface and
five-layer cap, the shared-prefix label trimming and the per-node clock
had no reader left.

- DagGraph draws layout, edges, selection and the node's click and
  keyboard handling; renderNode is required and surface is gone.
- graph.ts keeps depths, layout (dims required), layers and shape; the
  sheet and card dims, the mark table and took go.
- labels.ts, the dag-label-css gate, the box's rules in page.css and the
  board's override of the group dimming those rules did go with it, as do
  the one catalogue key the layer cap read, nodes.ts's settled (the clock
  was its last reader) and the composer's svg work glyph, whose only reader
  was the box.

Co-authored-by: Claude (claude-sonnet-5) <noreply@anthropic.com>
Co-authored-by: Claude (claude-fable-5-1) <noreply@anthropic.com>
@0xKT
0xKT requested a review from gloryfromca September 21, 2026 16:49
@gloryfromca
gloryfromca merged commit 4b005ad into refactor/ui_web_architecture Sep 21, 2026
22 checks passed
@gloryfromca
gloryfromca deleted the refactor/dag_card_opens_desk_task branch September 21, 2026 16:55

@gloryfromca gloryfromca 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.

No blockers; suggestions only, and they are marked inline.

The refactor has one task renderer after the transcript card hands off through the tasks seam, and the removed DAG renderer surface, CSS, catalogue keys, and tests have no remaining callers. The new summary/door behavior and the narrowed caller-supplied DagGraph contract are covered well.

I checked AGENTS.md/CLAUDE.md and the Web UI context, the full diff, surrounding callers, commit history, compatibility of the removed exports and i18n keys, and that the tests were replaced with state/door assertions rather than merely weakened. I found one nonblocking stale-response race in the fallback opener, marked inline.

Verification: npm test (188 files, 2,464 tests passed); npm run type-check (passed); npm run lint (passed with four existing hook warnings in untouched files). git diff --check passed.

Comment thread ui-web/src/features/transcript/source.ts
gloryfromca pushed a commit that referenced this pull request Sep 21, 2026
## Summary

The orchestration card in the transcript (a `run_subagent_dag` or
`load_playbook`
row, expanded) drew a graph of its own and, under it, a node panel whose
"open the
run" link raised the old agents-panel record window. The desk's task
pane already
draws the same graph and reads the same `dag.node` record, node by node,
so the
card was a second renderer for work the desk owns. The prototype's card
is the grid
alone, with the task cell as the door to the run. This PR makes the card
that.

Two commits, the second deleting only what the first killed:

1. **The card hands its graph to the desk.** The card keeps its grid
(task, scale,
playbook, state, cost, run id, replanned-into) and nothing else. The
task cell is
a door -- `role=button`, a title, a standing arrow -- whenever the run
has an
id, and opens the run's task pane on the desk. `openDagRun` goes through
the
tasks seam: `openRun` when the tasks store holds the row, one
`tasks.list` read
when it does not, the tasks tab when neither answers (a branched
conversation
replaying its parent's delivered row lands there). The delivered row
already
went through `openDagRun` and follows. The node panel, the `openDagNode`
seam,
`features/dag/open.ts`, the 21 catalogue keys only the panel read and
the
   `dag-renderer` gate go.
2. **The renderer's default box goes.** The desk's board is `DagGraph`'s
only
caller and hands it its own node card, so the default SVG box, the card
surface, the label trimming, the mark table and the per-node clock had
no
   reader left.

User-visible changes besides the door: the first failed node is no
longer opened
unasked inside the card (the desk pane's failure banner names it, one
click away);
a node's internal dependencies are read off the board's edges rather
than a list;
the node id, which the deleted panel spelled out, rides on the desk node
panel's
title.

Left for a follow-up, deliberately: `features/dag/mount.ts` and
`store.ts` (the run
state `state/session/resume.ts` still writes and nothing reads) --
deleting them
means either a new row on `domain-shape`'s shrink-only exceptions or
dissolving
`features/dag/` into its two remaining consumers, which is a decision of
its own.

## Type

- [ ] Fix
- [ ] Feature
- [ ] Docs
- [ ] CI / tooling
- [x] Refactor
- [ ] Other

## Verification

- `npm test --prefix ui-web` -- 188 files, 2464 tests, all pass (three
suites
fewer than the base: the two deleted gates and the deleted label suite)
- `npm run type-check --prefix ui-web` -- clean
- `npm run lint --prefix ui-web` -- 0 errors (4 pre-existing warnings in
  CronPage/SubagentsPage, untouched here)
- `node ui-web/scripts/check-class-namespace.mjs` -- OK; the transcript
and dag
  pins lowered to what the tool prints
- `npm run --prefix ui-tui lint:i18n` -- generated catalogue up to date
- `npm run --prefix ui-web build && python3 ui-web/build.py` --
boot-snapshot OK
  (235 nodes match golden)

Driven on a real host (`raven serve` from this branch on an isolated
`RAVEN_HOME`
built from a real config, deepseek as the default model, every channel
off), with
a playwright driver against the served page:

| Step | Result |
| --- | --- |
| Expand the card of a running three-node graph | grid only, no graph,
no node panel; task cell is `role=button` with a title and the arrow; a
long title is cut and the arrow stays in view |
| Click the task cell | exactly one desk pane, `task:dag:<run_id>`,
headed by the run's summary, showing the board |
| Click a node on the board | the desk's node panel with the node's
record |
| Click the task cell again | no second pane |
| Click the delivered row after the run settles | the same pane |
| Reload, expand the restored card, click | the same pane |
| A graph with one node on a lane that cannot reach its model | the
card's state row counts `1 failed`; the desk pane shows the failure
banner before any node is picked; the banner opens the failed node |
| The board before and after commit 2 | screenshots identical (node
cards, edges, lane frames) |

- [x] Relevant tests pass locally
- [x] Relevant lint / type checks pass locally
- [ ] User-facing docs or screenshots are updated when needed

## Risk

Web UI only; no server or wire change. The transcript card loses its
graph and
node panel on purpose; every fact they showed is on the desk's task
pane, reached
from the card's task cell and from the delivered row.
`features/dag/mount.ts` keeps
running unchanged. Rollback is reverting the squash commit.

- [x] Security impact considered
- [x] Backward compatibility considered
- [x] Rollback path is clear for risky changes

## Related Issues

N/A

---------

Co-authored-by: Claude (claude-sonnet-5) <noreply@anthropic.com>
LivXue pushed a commit that referenced this pull request Oct 12, 2026
## Summary

The orchestration card in the transcript (a `run_subagent_dag` or
`load_playbook`
row, expanded) drew a graph of its own and, under it, a node panel whose
"open the
run" link raised the old agents-panel record window. The desk's task
pane already
draws the same graph and reads the same `dag.node` record, node by node,
so the
card was a second renderer for work the desk owns. The prototype's card
is the grid
alone, with the task cell as the door to the run. This PR makes the card
that.

Two commits, the second deleting only what the first killed:

1. **The card hands its graph to the desk.** The card keeps its grid
(task, scale,
playbook, state, cost, run id, replanned-into) and nothing else. The
task cell is
a door -- `role=button`, a title, a standing arrow -- whenever the run
has an
id, and opens the run's task pane on the desk. `openDagRun` goes through
the
tasks seam: `openRun` when the tasks store holds the row, one
`tasks.list` read
when it does not, the tasks tab when neither answers (a branched
conversation
replaying its parent's delivered row lands there). The delivered row
already
went through `openDagRun` and follows. The node panel, the `openDagNode`
seam,
`features/dag/open.ts`, the 21 catalogue keys only the panel read and
the
   `dag-renderer` gate go.
2. **The renderer's default box goes.** The desk's board is `DagGraph`'s
only
caller and hands it its own node card, so the default SVG box, the card
surface, the label trimming, the mark table and the per-node clock had
no
   reader left.

User-visible changes besides the door: the first failed node is no
longer opened
unasked inside the card (the desk pane's failure banner names it, one
click away);
a node's internal dependencies are read off the board's edges rather
than a list;
the node id, which the deleted panel spelled out, rides on the desk node
panel's
title.

Left for a follow-up, deliberately: `features/dag/mount.ts` and
`store.ts` (the run
state `state/session/resume.ts` still writes and nothing reads) --
deleting them
means either a new row on `domain-shape`'s shrink-only exceptions or
dissolving
`features/dag/` into its two remaining consumers, which is a decision of
its own.

## Type

- [ ] Fix
- [ ] Feature
- [ ] Docs
- [ ] CI / tooling
- [x] Refactor
- [ ] Other

## Verification

- `npm test --prefix ui-web` -- 188 files, 2464 tests, all pass (three
suites
fewer than the base: the two deleted gates and the deleted label suite)
- `npm run type-check --prefix ui-web` -- clean
- `npm run lint --prefix ui-web` -- 0 errors (4 pre-existing warnings in
  CronPage/SubagentsPage, untouched here)
- `node ui-web/scripts/check-class-namespace.mjs` -- OK; the transcript
and dag
  pins lowered to what the tool prints
- `npm run --prefix ui-tui lint:i18n` -- generated catalogue up to date
- `npm run --prefix ui-web build && python3 ui-web/build.py` --
boot-snapshot OK
  (235 nodes match golden)

Driven on a real host (`raven serve` from this branch on an isolated
`RAVEN_HOME`
built from a real config, deepseek as the default model, every channel
off), with
a playwright driver against the served page:

| Step | Result |
| --- | --- |
| Expand the card of a running three-node graph | grid only, no graph,
no node panel; task cell is `role=button` with a title and the arrow; a
long title is cut and the arrow stays in view |
| Click the task cell | exactly one desk pane, `task:dag:<run_id>`,
headed by the run's summary, showing the board |
| Click a node on the board | the desk's node panel with the node's
record |
| Click the task cell again | no second pane |
| Click the delivered row after the run settles | the same pane |
| Reload, expand the restored card, click | the same pane |
| A graph with one node on a lane that cannot reach its model | the
card's state row counts `1 failed`; the desk pane shows the failure
banner before any node is picked; the banner opens the failed node |
| The board before and after commit 2 | screenshots identical (node
cards, edges, lane frames) |

- [x] Relevant tests pass locally
- [x] Relevant lint / type checks pass locally
- [ ] User-facing docs or screenshots are updated when needed

## Risk

Web UI only; no server or wire change. The transcript card loses its
graph and
node panel on purpose; every fact they showed is on the desk's task
pane, reached
from the card's task cell and from the delivered row.
`features/dag/mount.ts` keeps
running unchanged. Rollback is reverting the squash commit.

- [x] Security impact considered
- [x] Backward compatibility considered
- [x] Rollback path is clear for risky changes

## Related Issues

N/A

---------

Co-authored-by: Claude (claude-sonnet-5) <noreply@anthropic.com>
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.

2 participants