Summary
A design exploration into making multi-agent behavior legible inside GitLab Duo sessions. This wasn’t a shipped feature. The goal was to give the team a concrete, testable sense of what subagent attribution could feel like, with running prototypes and a set of visual treatments they could react to, before engineering committed to a direction. The exploration also doubled as an early test of a new internal design system on real product UI.
Challenge
GitLab planned to roll out a customer-facing subagents experience in Duo. Sessions already contained multi-agent activity, but nothing distinguished the primary agent’s output from a subagent’s, or made the sequence of contributions obvious. Left unaddressed, more complex custom flows and multi-agent compositions would open a debugging and trust gap: users wouldn’t understand why the agent behaved a certain way, or where to look when something went wrong.
The bar for v1 was basic traceability, not analytics. Users should at least be able to tell when a subagent stepped in and what it contributed, within a single session. The constraints were firm. The single-session model stayed unchanged, and everything had to be driven from minimal metadata: a stable agent ID, a human-readable name, and a primary-vs-subagent flag.
My role
I led the design exploration, working directly from the engineering brief and its constraints. The deliverable wasn’t a spec; it was interaction direction the team could evaluate against something real.
Approach
Starting from the brief
I fed the brief and its constraints to Claude directly and iterated from its interpretations. Starting from the actual v1 requirements kept every exploration honest: anything that needed more than the minimal agent metadata, or touched the session model, was out of bounds by construction.

Exploring multiple treatments
Rather than polishing a single idea, I generated a series of attribution treatments, from a lo-fi restructuring of the raw session log through five progressively refined visual directions. Each varied how agent identity, hand-offs, and subagent contributions were expressed: labels, color, indentation, and grouping.

The later treatments pushed past the v1 floor to show what the same metadata could support: explicit hand-off rows between agents, subagent invocations labeled in place, and statuses like self-correction made visible in the trace.

Stress-testing a new design system
The treatments were built in a new internal design system rather than the current product UI. A dense, streaming session view is a demanding surface: typographic hierarchy, statuses, and color coding all compete at scale. That made it a useful first test of the system’s visual language, including its dark theme, on real product UI rather than sample screens.
Building prototypes that run
The treatments became running prototypes of the session view, with streaming output, multiple subagents interleaving, and both live and historical states. Attribution is an interaction problem, not a styling problem: whether a treatment stays legible depends on how it behaves while a session is actually unfolding, and a static frame can’t answer that.
Validating with the team
I shared the running prototypes with engineers and product and gathered reactions: which treatments read clearly at a glance, which collapsed under multiple subagents, and which interactions felt worth the metadata they would require.
Outcomes
This work didn’t ship. The value was in what the exploration produced:
- The team got concrete, running interaction directions to react to, instead of debating attribution in the abstract
- Feedback separated the treatments that stayed legible under real multi-agent traffic from the ones that only worked in a screenshot
- The working method proved itself: from brief to Claude-built running prototype to team reaction in days rather than weeks
- The exploration doubled as a real-world stress test of the new design system, showing how its visual language held up on dense multi-agent UI
Key learnings
Running prototypes surface truths static frames can’t. Streaming, interleaving, and clutter at scale are exactly the failure modes that decide whether an attribution treatment works, and none of them exist in a still image.