One lead has 37% of its context left. Three members are idle. All three last worked six days ago, share a managed worktree, and carry provenance chips that trace how they entered the team. I can read the organization from one card in the middle of a conversation.

The useful part is not how much the card shows. It is where the card appeared.
The lead needed to distinguish an old authorized setup from the team that was active now, so it called gg_team_status. The tool returned structured state to the lead. The product rendered that result as a roster for me. One operation, two readings.
Before the card, the agent wrote the interface
Earlier, the same kind of check looked like this:

The lead assembled a Markdown table of agents, roles, and statuses, then printed the target branch and SHA underneath. It was useful, but model-authored. The lead chose which sources to inspect, which fields to include, and how to phrase each status. The team sidebar and Git panel already held pieces of the same world while the model redrew them with pipes and text.
Markdown like this is often a missing interface making itself obvious. The model was already drawing a roster. When the report becomes a pattern, application code should own it. The fix was not better Markdown. It was moving the recurring parts into the product.
A sidebar is not a team
A sidebar tells me which conversations exist and perhaps which one is streaming. That organizes windows, not work. To direct a team, I need roles, activity, remaining capacity, shared work, and a history of delegation. Without those facts, four agent chats are still four tabs I have to keep straight in my head.
Every field changes a decision. The title tells me how to use a member, and the name how to address it. State and last activity reveal whether work is moving or stale. Context remaining tells me whether to reuse an agent or rotate it out. The worktree ties the agent to a line of work. Added by records the delegation chain and points to whoever is most likely to know why that member exists.
The card also refuses to guess. The Rust runtime derives status in a fixed order from a failed session, any active turn, and then the last turn’s outcome. Only then does a member become idle. Activity comes from the newest established team timestamp, context from the latest provider snapshot, worktree details from its managed identity, and added_by from persisted membership. Missing values stay missing.
Those facts do not contain policy. 37% Context Left does not decide whether an agent gets another assignment. That threshold lives in a skill, where I can change it in plain English. The tool measures. The workflow decides.
One system, two readers
An instrument panel works because the pilot and the autopilot read the same sensors. One consumes structured values and the other reads gauges, but altitude cannot have two owners. The model and I have the same relationship to team state: it reads the tool result, and I read the card.
The easy mistake is to build those surfaces separately. Give the model a tool schema and JSON result, then build the human dashboard through another query path with status rules recreated in React. Now the product has two altimeters. Eventually one says an agent is working while the other says idle, or one has the latest context snapshot while the other holds an estimate.
goldengoose avoids that split with one backend-owned aggregation. Codex reaches it through a dynamic tool. MCP-backed providers reach the same router through their own transport. The frontend unwraps either path and renders the same data. The card is a projection of runtime state, not a second owner of it.
The model asks. Product code answers.
The lead decides when team status would help and emits a typed tool call. Its creative authority ends there. Application code defines what team status means, derives the fields, and renders the roster. The model does not generate React, choose icons, or improvise what idle means.
The most trustworthy model-driven UI is barely generative. The model chooses the question. Product code owns the answer.
The conversation is the right place for the result because it preserves the reason for the question. A dashboard would make me leave the lead’s reasoning, find the team state, then mentally join the two again. Here the answer appears inside the decision that needed it.
The tool call does not sit behind that interface. The tool call is the interface.