Skip to content

feat(teams): teams you send work to, with managers, on the composition - #36

Merged
piotrlaczkowski merged 2 commits into
mainfrom
claude/teams-page-pipeline-composition-d6v8vx
Sep 9, 2026
Merged

piotrlaczkowski merged 2 commits into
mainfrom
claude/teams-page-pipeline-composition-d6v8vx

Conversation

@piotrlaczkowski

Copy link
Copy Markdown
Contributor

Why

The Teams page could author a team but not put one to work, and a run's team decision was made in a different place from its pipeline decision: the dynamic composer knew nothing about library teams, Studio never sent per-run teams, builtin teams had no visible manager, nothing showed what managers decided, and a resumed run silently lost its org chart.

What changes

Composition knows the teams. The team decision is made once per run from the library and stamped onto composer.Composition (teams, team_mode, team_note), each team with its resolved manager and the evidence that chose it. The composer model is told the teams and cannot change them. One pinned team now staffs the run: its worker, reviewer and tester take the loop, its skills are pinned, its charter and territory ride in the handoff, and its manager triages its rejected work. The charter phase keeps that answer instead of asking the model to invent a second team.

Teams page. Send a request previews the selected teams, who staffs and manages each, what the selection does to the run, and the pipeline the composer would assemble; Run starts the run with those teams pinned, Activate writes the org chart. Cards show the effective manager; Give it a manager creates a dedicated <team>-triage agent seeded with the team's charter (POST /api/teams/{id}/manager). How the teams worked (GET /api/teams/activity) lists manager decisions, reassignments, cross-team waits, gates and integration, filterable by team, live during a run.

Live view and board. A Teams control on the command bar pins teams for one run; the run setup panel shows the teams and managers; the composition preview honors per-run pins. A task can be assigned to a team on the board, refused with the owner named when its files belong to another team.

Fixes. Resume restores the saved squad plan when the board carries its team stamps. A long-lived Studio process no longer carries a stale plan into a run after teams are switched off. The manager-resolution rule lives once in agents.ResolveManager.

Docs: docs/squads.md, docs/studio.md, changelog. CLI: slmcode compose --explain prints the teams.

Verification

go test ./... (incl. cmd and test/e2e), -race on the changed packages, the coverage floor, golangci-lint (built with the module's Go 1.26.7 toolchain; the one remaining finding is pre-existing in pkg/autoresearch/propose.go), and the web lint, typecheck, tests and production build all pass.

🤖 Generated with Claude Code

https://claude.ai/code/session_011RfCkcsbJZgHoQLzwkqFUL


Generated by Claude Code

The Teams page was a library plus an org-chart editor: it could author a team
but not put one to work, and a run's team decision was made in a different
place from its pipeline decision. This makes teams the thing a request is sent
to, and makes the harness show what the managers and teams then did.

Composer / orchestrator
- composer.Composition carries Teams, TeamMode and TeamNote: the library teams
  the run will use, each with its resolved manager (the team's own when it
  answers the triage contract, else the run default, marked) and the evidence
  that chose it. Stamped deterministically from the library before the
  language hint; the composer model is told the teams and cannot change them.
- One pinned team STAFFS the run: its worker, reviewer and tester take the
  execute loop, its skills are pinned, its charter and territory ride in the
  handoff. Two or more run in parallel as before. Neither, and why, is said.
- Resume restores the saved squad plan when the board's tasks are stamped
  with its teams; a run started after squads was switched off no longer
  inherits the previous run's plan.

Server
- GET /api/teams/activity: the run's team-relevant events classified — manager
  decisions, reassignments, cross-team waits, contract clauses, gates,
  integration — with one summary row per manager; ?query= reads a past run.
- POST /api/teams/{id}/manager creates <team>-triage (tool-less, seeded with
  the team's charter, people and territory) and points the team at it.
- PATCH /api/tasks/{id} accepts `squad`, refused with the owner named when the
  task's files belong to another team.
- Team views report effective_manager / manager_default; preselect reports
  mode, note and per-team staffing; the composition preview honours per-run
  team pins.

Studio
- Teams page: Send a request (preselect with staffing and managers, the
  composer's pipeline, Run with these teams, Activate), manager rows and
  "Give it a manager" on cards and in the editor, and "How the teams worked".
- Live view: a Teams control on the command bar pins teams for one run; the
  run setup panel shows the teams and their managers.
- Board: a task can be assigned to a team.

Docs: squads.md, studio.md, changelog. CLI: compose --explain prints teams.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011RfCkcsbJZgHoQLzwkqFUL
Review of the teams work found ten defects; all fixed here.

- The library's "one team" is a decision: assembleSquads no longer asks the
  manager model to invent a second team behind a composition that had just
  said "one stream". Only a library with nothing to say hands the question
  to the model, and the composition note says so.
- A single-team run now asks the team's OWN manager about a rejected
  delivery, with the team's people first in the roster; there is no squad
  plan for one team, so the composition's team is kept on the run and
  rendered as a one-squad staffing (singleTeamPlan / staffingPlan).
- The team decision is computed once per run and handed to the composer
  prompt, the composition and the charter phase (teamDecision), instead of
  three registry loads and workspace walks that could disagree.
- The "manager must answer the triage contract, else the run default" rule
  lives once, in agents.ResolveManager, used by the Teams page, the
  composition and the loop's triage call.
- A composition preview with pinned teams goes through the orchestrator's
  factory (PreviewCompositionWithTeams), so seats the run would clear and
  managers it would replace are previewed as the run will have them; the
  Teams page previews the composition against the same pins as the
  preselection.
- PATCH /api/tasks/{id}: files are applied before the ownership check, so a
  move that changes files is judged on the new files; un-assigning a task
  whose files one team owns is refused like a wrong assignment would be.
- GET /api/teams/activity reads a past run's whole event log rather than
  its first 5000 records, and attributes the saved org chart to the current
  run only when the board's tasks were built under it.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011RfCkcsbJZgHoQLzwkqFUL
@piotrlaczkowski
piotrlaczkowski merged commit da67f50 into main Sep 9, 2026
7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants