part = 4 / 5

Panels for a three-level world

Take the premise seriously: sessions, traces, and spans are all objects a user should be able to reason about, debug, and richly annotate — with equal standing. Almost every layout decision follows from that premise plus two rules. Wireframes below.

The diagnosis, briefly

Phoenix's current organization treats each level as a different place: a traces table you leave to enter a trace page, a sessions table you leave to enter a session page, a span drawer that opens inside either. The inspector's shape changes at each hop, annotation is offered only at the span level (Part 1), and "where am I in the hierarchy" lives in the browser's back button. The individual screens are fine; the seams between levels are where users lose state, and the seams are exactly where AI debugging happens — you find the bad turn in a session, drop into its trace, read one span, and pop back up to judge the conversation. That loop crosses all three levels every time. An interface that makes level-crossing expensive taxes the core loop.

Two rules that generate the layout

Rule two is the one that fixes annotation. If the inspector is level-agnostic and always states its target, then "Annotate" on a session annotates the session — because the session is what's selected, and the panel says so. The current bug (turn-level annotate button writes to the root span) can't be expressed in this layout without the label visibly lying.

Panel organization schemes
Click any panel for its role. These are altitude maps, not pixel specs — the argument is about which panels exist, what stays constant, and where selection state lives.

Scheme A is the recommendation. Why:

Scheme B — a single full-bleed canvas with a breadcrumb zoom stack — is the same information architecture minus the persistent tree, and is the right compact variant (small screens, embedded views). It costs you the always-visible structural map, which matters most for the pathological traces where you need it most. Scheme C is today's model, included because seeing "navigation = page transitions, inspector changes shape at each hop, annotation exists at one level" drawn as boxes makes the critique concrete.

The annotation rail: one component, three altitudes

The piece to build once and mount everywhere. Identity of layout across levels is what teaches users that sessions, traces, and spans are equally first-class — no documentation does this, panels do.

Same rail, different target The level chip and the roll-up line are the only differences
session
resolutionresolved ✓
user_sentiment0.72
rollup: 3 traces · 2 annotated · 1 flagged span
+ Annotate session…
trace
correctnessincorrect ✗
hallucination (eval)0.91
rollup: 9 spans · 1 flagged
+ Annotate trace…
span
tool_choicewrong tool
note“stale order db”
2 document annotations on retrieved chunks
+ Annotate span…
Everything here already exists in the schema and the GraphQL API, including session annotations (project_session_annotations, Part 1). The rail is a frontend unification project: one composer, one list, one summary component, parameterized by target type.

Details that make or break it

part 4 in one sentence Make selection a visible session/trace/span path, let the canvas re-project per altitude, and mount one unchanging inspector-with-annotation-rail beside it — at which point equal annotatability stops being a feature request and becomes a side effect of the layout.