.nornir/assets/funnel-run-history-bottleneck.svg
<svg xmlns="http://www.w3.org/2000/svg" width="920" height="430" font-family="monospace" font-size="13">
<style>
.box{fill:#0f2233;stroke:#6fd3f5;stroke-width:1.5}
.reuse{fill:#12331f;stroke:#7fe0a0;stroke-width:1.5}
.bn{fill:#33260f;stroke:#f5b76f;stroke-width:1.5}
.t{fill:#dbeafe}.dim{fill:#9fb6c6}.acc{fill:#7fe0a0}.wire{fill:#f5d76f}.amber{fill:#f5b76f}
.arr{stroke:#6fd3f5;stroke-width:1.5;fill:none;marker-end:url(#a)}
.arr2{stroke:#7fe0a0;stroke-width:1.5;fill:none;marker-end:url(#b)}
.arr3{stroke:#f5b76f;stroke-width:1.5;fill:none;marker-end:url(#c)}
</style>
<defs>
<marker id="a" markerWidth="9" markerHeight="9" refX="7" refY="3" orient="auto"><path d="M0,0 L7,3 L0,6 Z" fill="#6fd3f5"/></marker>
<marker id="b" markerWidth="9" markerHeight="9" refX="7" refY="3" orient="auto"><path d="M0,0 L7,3 L0,6 Z" fill="#7fe0a0"/></marker>
<marker id="c" markerWidth="9" markerHeight="9" refX="7" refY="3" orient="auto"><path d="M0,0 L7,3 L0,6 Z" fill="#f5b76f"/></marker>
</defs>
<text x="12" y="20" class="acc">nornir-funnel-embed — run history + bottleneck (GREEN = REUSED facett-plandag, AMBER = the constraint hint)</text>
<!-- live poll -->
<text x="12" y="48" class="acc">every ~1.5 s auto-poll</text>
<rect class="box" x="12" y="60" width="188" height="76"/>
<text x="24" y="84" class="t">refresh()</text>
<text x="24" y="102" class="dim">Funnel.Show → PlanDag</text>
<text x="24" y="120" class="dim">→ view_from_dag (live)</text>
<path class="arr" d="M200,98 L252,98"/>
<!-- record run -->
<rect class="box" x="252" y="60" width="212" height="76"/>
<text x="264" y="84" class="t">FunnelRunLog.record()</text>
<text x="264" y="102" class="dim">snapshot PlanModel (Clone)</text>
<text x="264" y="120" class="dim">de-dup by (n,e,outcome)·cap 32</text>
<path class="arr" d="M464,98 L516,98"/>
<!-- picker -->
<rect class="box" x="516" y="60" width="200" height="76"/>
<text x="528" y="84" class="t">run-picker ComboBox</text>
<text x="528" y="102" class="dim">◷ latest (live)</text>
<text x="528" y="120" class="dim">run #3 · #2 · #1 …</text>
<path class="arr" d="M716,98 L768,98"/>
<!-- select -->
<rect class="box" x="768" y="60" width="140" height="76"/>
<text x="780" y="84" class="t">select_run(seq)</text>
<text x="780" y="102" class="dim">{"select_run":n}</text>
<text x="780" y="120" class="dim">| null ⇒ live</text>
<!-- selected snapshot re-render (REUSE) -->
<text x="12" y="188" class="acc">selected run → re-render its DAG through the SAME view</text>
<rect class="reuse" x="12" y="200" width="232" height="70"/>
<text x="24" y="224" class="acc">view_from_model(run.model)</text>
<text x="24" y="242" class="dim">facett_plandag::PlanDagView</text>
<text x="24" y="260" class="dim">(no second renderer — L5)</text>
<path class="arr2" d="M244,235 L300,235"/>
<!-- current view -->
<rect class="reuse" x="300" y="200" width="196" height="70"/>
<text x="312" y="224" class="acc">current_view()</text>
<text x="312" y="242" class="dim">snapshot if picked,</text>
<text x="312" y="260" class="dim">else the live view</text>
<path class="arr2" d="M496,235 L552,235"/>
<!-- plandag state_json -->
<rect class="reuse" x="552" y="200" width="356" height="70"/>
<text x="564" y="224" class="acc">PlanDagView.state_json() (CONSUMED)</text>
<text x="564" y="242" class="dim">nodes[] · top_bottleneck · critical_path</text>
<text x="564" y="260" class="dim">(facett-plandag constraint analysis)</text>
<!-- bottleneck hint -->
<path class="arr3" d="M730,270 L730,310"/>
<rect class="bn" x="552" y="310" width="356" height="70"/>
<text x="564" y="334" class="amber">bottleneck_hint() → "clear next · <title>"</text>
<text x="564" y="352" class="dim">match top_bottleneck id → node title</text>
<text x="564" y="370" class="dim">state_json.{bottleneck,bottleneck_title,critical_path}</text>
<!-- funnel state_json out -->
<rect class="box" x="12" y="310" width="472" height="70"/>
<text x="24" y="334" class="t">FunnelPanel.state_json()</text>
<text x="24" y="352" class="dim">runs · run_count · selected_run (the picker, AS DATA)</text>
<text x="24" y="370" class="dim">+ bottleneck · plandag (the shown DAG) → robot-observable</text>
<path class="arr3" d="M552,345 L484,345"/>
</svg>