Team report: each team and member as an outcome contract, activity underneath as evidence
Release notes 2026-09-15 — the team report (vocion-core#326, merged) reads worker runs against the org chart and states purpose, owner, KPIs, autonomy and spend weight per team and member; board and red-team runs are labelled as judgement.

Shipped: vocion-core#326, merged to main on 2026-09-15 as 775c5e10. Part of the 2026-09-15 release notes.
The outcome
A person responsible for a team of agents should be able to say, for each team and each member, what it is for, who owns the result, how it is measured, how it is doing, and what share of the spend it takes — without reading a log. Run counts, tokens and dollars are operational metrics. They belong underneath.
What it is
/dashboard/team-report reads worker_run rows (the long-running worker record from ADR 0004) against the org chart and presents an outcome contract per team and per member:
- Purpose — the team's
goal:and the agent's description. - Owner — the accountable human, with whether it was set on the team or inherited from the workspace (
TeamService). - KPI · baseline → current → target — from a new
kpis:list on the team manifest. - Permissions and autonomy — approval-policy keys, enabled trust rules, and the highest active mission autonomy level, read-only.
- Escalation — a link to the Needs-you inbox.
- Spend weight — the member's share of the team's cents beside its share of the team's KPI attainment.
Runs, tokens and cents sit in a closed Evidence disclosure. Runs of kind board and red-team are labelled judgement and quality and carried separately, so a review cycle is never counted as output.
How it is authored
Two manifest additions (packages/core/src/libs/workspace/schemas.ts):
# teams/engineering.yaml
name: Engineering
goal: Keep main releasable every day with fewer human review hours
kpis:
- key: prsMerged
label: PRs merged
target: 6
baseline: 2
unit: per 7d
source: counts.prsMerged
window: 7d
source: counts.<key> sums whatever a worker reports in its run's counts — any key a worker heartbeats becomes measurable. workspace.yaml gains a top-line goal: that heads the page. Older cores strip unknown keys, so a workspace can add these before the core that reads them is deployed.
What changed in the worker contract
POST /api/v1/worker-runs accepts kind (lead | board | worker | red-team | compact | snapshot, default worker) and model; POST /:id/complete accepts summary; GET /api/v1/worker-runs?kind= filters. Migration 0092 adds worker_run.kind, model, summary and team.goal, team.kpis, all with defaults. Existing rows read as kind = 'worker'; existing teams show "Nothing measured yet" with the YAML key to add.
The activity feed gains worker runs as a kind, with board and red-team rows badged.
Why the framing
The page follows the Product Design Manifesto: outcomes over activity; accountability with an owner; hide complexity, never hide truth. Its "outcome contract" — purpose, owner, KPI, baseline, target, permissions, quality threshold, escalation, current performance, autonomy level — is the manifesto's core model made visible.
The screenshot is a local workspace on the bundled engineering-team template; the numbers are fixtures.
Docs: [docs/entities/team.md](https://github.com/vocion/vocion-core/blob/main/docs/entities/team.md), [docs/entities/worker-run.md](https://github.com/vocion/vocion-core/blob/main/docs/entities/worker-run.md).
Where this lives in the repo
- Migration:
packages/core/migrations/0092_worker_run_kind_team_kpis.sql—worker_run.kind text NOT NULL DEFAULT 'worker',worker_run.model,worker_run.summary,team.goal,team.kpis jsonb DEFAULT '[]'. - Manifest schema:
packages/core/src/libs/workspace/schemas.ts—TeamKpiSchemaandTeamManifestSchema.kpis(keys unique per team),WorkspaceManifestSchema.goal. - Aggregation and the math:
packages/core/src/services/TeamReportService.ts—buildTeamReport(pure),kpiProgress(current = sum ofworker_run.counts[key]over the team's agents in the window; attainment = (current − baseline) / (target − baseline), clamped), member outcome share = mean of the member's per-KPI share over KPIs with a non-zero team total, spend weight = member cents / team cents; tests inTeamReportService.test.ts. - Worker contract:
packages/core/src/services/WorkerRunService.ts, routesapp/api/v1/worker-runs/route.ts(create withkind,model; list with?kind=) and[id]/complete/route.ts(summary). - Pages and components:
app/[locale]/(auth)/dashboard/team-report/page.tsx,[agentSlug]/page.tsx,features/dashboard/team-report/{ContractGrid,KpiMeter,MemberTable,WeightStrip,RunKindBadge}.tsx. - Docs:
docs/entities/team.md("Outcome contract"),docs/entities/worker-run.md.
There is no feature flag; the page is on main from 775c5e10. related_version above is the core tag the post was verified against.