Funnel ForgePane — run history + bottleneck (guide)
How to use the two new surfaces on the dwarves funnel pane, and how to drive them headless (the robot / state_json seam).
In the UI
-
Open the Funnel tab (dwarves-gui). The DAG grows live (
● live/⏸); the submit strip lets you funnel an idea/error. -
Once the funnel has grown a bit, a run-history picker appears:
◷ latest (live)plus one entry per past run, newest first —run #3 · 7 nodes / 9 edges · running.- Pick a past run → the pane re-draws that run's final DAG and shows
viewing run #3 · 7 nodes / 9 edges · running. - Click
● live(or pick◷ latest (live)) to return to the live view.
- Pick a past run → the pane re-draws that run's final DAG and shows
-
Above the DAG, an amber
clear next · <node title>hint points at the bottleneck — the node that, once cleared, unblocks the most downstream work. It updates for whichever DAG is shown (live or a selected past run).
Driving it headless (robot / tests)
Everything is drivable over the pane's JSON seam — the same channel nornir-robotui uses:
// select a past run by its stable seq (from state_json.runs[].seq)
{"select_run": 2}
// return to the live/latest view
{"select_run": null}
// drop the whole run log and go back to live
{"clear_runs": true}
Read back from state_json:
{
"runs": [{ "seq": 1, "node_count": 2, "edge_count": 1, "outcome": "running", "captured_at_s": 10.0 }, ...],
"run_count": 3,
"selected_run": 2, // null when the live view is shown
"bottleneck": "node:n-001", // top-bottleneck id (or null)
"bottleneck_title": "implement foo",
"critical_path": ["...","..."], // the longest chain, as data
"plandag": { "node_count": 3, "top_bottleneck": "node:n-001", ... } // the SHOWN DAG
}
Feeding runs without a live server (hosts / tests)
FunnelPanel::record_run(model, outcome, at_s) is the public capture seam refresh() uses. A host — or a test with no nornir-server — can push a snapshot directly, then drive {"select_run":…}. See nornir-funnel-embed's run_picker_views_a_past_run_and_surfaces_its_bottleneck (headless, red-when-broken) and run_picker_and_bottleneck_hint_paint (egui_kittest render leg).
Tests / matrix
nornir-funnel-embed:run_log_dedups_caps_and_addresses_by_seq,run_picker_views_a_past_run_and_surfaces_its_bottleneck(RED-when-broken — neutralizeselect_runand the selection/bottleneck assertions fail),run_picker_and_bottleneck_hint_paint(egui_kittest),offline_pane_exposes_empty_run_history_shape. Matrix cellfunnel_run_history_picker_and_bottleneck.dwarves-gui:robot_funnel_run_history_and_bottleneck_over_the_seam(shell-level, offline shape + control drivability). Matrix cellfunnel_run_history_bottleneck_drivable.