Repository navigation
feat(teams): teams you send work to, with managers, on the composition - #36
Merged
piotrlaczkowski merged 2 commits intoSep 9, 2026
Merged
Conversation
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
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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>-triageagent 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 --explainprints the teams.Verification
go test ./...(incl.cmdandtest/e2e),-raceon 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 inpkg/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