docs/features/teams.md

Teams

A Team is a group of agents with one Lead and its specialists. You brief the Lead in plain language; it decides what matters, routes work to the right specialist, and assembles their output into something a human can act on. The org chart of a deployment.

Why teams

A single agent wired to a dozen skills becomes a blunt instrument — it does everything passably and nothing sharply. Real work divides: someone owns the pipeline read, someone owns follow-ups, someone owns proposals. Vocion models that division directly.

A Team retires the old "sub-agent" framing. Specialists are first-class agents — each with its own prompt, skills, evals, and connector access — not anonymous helpers buried inside one agent's config. The Lead is the one you talk to; the specialists are the ones it dispatches.

Roles and modes

Every agent now carries three grouping fields:

FieldValuesMeaning
rolelead | specialistWhether this agent coordinates the team or does focused work within it.
agentTypemission | workflow | operationalThe work mode the agent is built for — open-ended goal work, structured step sequences, or recurring operational duties.
teamany slugThe team this agent belongs to. Agents with no team fall under Unassigned.

A team is exactly one lead + its specialists grouped by a shared team slug. You reach the team through its Lead; the Lead runs Missions and Workflows, delegating to specialists as the work demands.

Authoring

Teams are pure workspace config — no code. Set the three fields on each agent YAML under workspace/<org>/agents/:

slug: revenue-lead
name: Revenue Lead
description: Coordinates the Revenue Operations team — triages, assigns, assembles.
active: true
role: lead
agentType: mission
team: revenue-operations
slug: pipeline-analyst
name: Pipeline Analyst
active: true
role: specialist
agentType: operational
team: revenue-operations

Teams themselves are also authored files. Add a teams/<slug>.yaml next to agents/ (the slug comes from the filename) naming the team, its lead, and — optionally — the human accountable for its output:

# workspace/<org>/teams/revenue-operations.yaml
name: Revenue Operations
description: Pipeline hygiene and forecast accuracy.
lead: revenue-lead
accountableUser: jordan@example.com   # optional — omit to inherit the workspace default

Once a teams/ directory exists, each agent's team: is validated as a reference to one of these files (workspaces without a teams/ directory keep the legacy free-text behavior). A team may exist before its lead is chosen — it renders as "no lead yet" rather than disappearing — and the lead is auto-assigned to the team it leads.

Above the teams sits the workspace lead: one agent that runs the whole workspace and consults the team leads. Declare it — plus the workspace-default accountable human — at the top level of workspace.yaml:

# workspace/<org>/workspace.yaml
lead: revenue-director
accountableUser: you@example.com

accountableUser emails are resolved to user ids at apply time (an unresolved email is a non-fatal error). Teams that omit their own accountableUser inherit the workspace default at read time — the UI labels which is which — so accountability is never baked into the export.

Then apply:

npm run workspace:apply      # sync to DB; records a workspace_version row

The applier persists role / agentType / team on each agent row. No migration to write, no restart — the team appears once the workspace version lands.

In the app

The dashboard's Teams view (/dashboard/teams) renders the deployment as its org chart: the workspace lead in a band on top (with a one-click "ask how the quarter is going" deep link into chat), team cards beneath — each showing its Lead, member count, and accountable owner with provenance (an inherited owner reads "Name (workspace default)") — and a "not on a team yet" strip so unassigned agents never vanish. It's the fastest way to see, at a glance, who's on a deployment and who owns what.

Each team gets a detail page at /dashboard/teams/<slug>: owner and Lead in the rail, the member roster (Lead first), and a plain-language approval boundary derived from the members' wired skills — which reads run freely and which writes wait in Review. The underlying teams/<slug>.yaml is tucked behind an "under the hood" disclosure.

Teams shape the working surfaces too:

  • Chat (/dashboard/chat) defaults to the workspace lead, greets per-agent, and limits the agent switcher to the workspace + team leads — specialists are reached through their Lead. The team leads are merged into the workspace lead's subagents, so a workspace-level question fans out per team (lead-less teams are named "no lead yet", never silently omitted).
  • Missions owned by the workspace lead resolve their roster to each team's lead from the team table; other leads keep their own specialists.
  • MCP exposes the org chart read-only as a teams_list tool — workspace lead, every team with its roster, and the resolved accountable human with provenance. Teams are authored YAML, so the write path stays workspace_apply.

The sample workspace

A workspace with no teams yet shows a one-click seed on /dashboard/teams that loads Meridian Outdoor — Revenue, a bundled sample: one workspace lead over four teams (RevOps, Deal Desk, Founder GTM, Marketing) with leads, specialists, and two operations. It applies through the same pipeline as workspace:apply (audited as a workspace version), is admin-gated and first-run only — any existing team blocks it — and injects your email as the workspace-default owner so accountability lands on a real person in your account.

Connection to other resources

  • Agents — the members of a team; each is a full agent in its own right.
  • Missions — the open-ended, goal-driven work a Lead coordinates across the team.
  • Workflows — the structured procedures a team runs.
  • Skills — what each specialist actually does.

Next