---
name: team-roster
description: Assigns each teammate a role + current task + blocker status, then surfaces the critical-path bottleneck. Use at the start of the build phase and any time the team feels stuck.
when_to_use: |
Trigger when the user says "who is doing what", "assign roles", "who is free", "who is blocked", or after scope-knife emits a plan with > 2 KEEP features. Do not invoke before scope-knife; without a plan, role assignment is guessing.


version: 1.0
category: scoping
tags: ["roles", "assignments", "bottleneck"]
dependencies: []
side_effects: ["roster"]
triggers: ["who does what", "team assignments", "role assignments", "who is blocked", "bottleneck"]
---

# team-roster

A 4-person team with no roles is 4 solo developers. A 4-person team with roles is a build crew. This skill forces the assignment into the open so the bottleneck is visible by minute 30, not by minute 30-of-9.

## Input contract

Required:

- `team_size`: integer >= 1
- `plan_features`: KEEP list from `.hackathon/state/plan.json`
- `team_members`: list of strings (names or handles)

Optional:

- `skills_per_member`: map of name -> [skill strings] (defaults to empty)
- `timezone_offsets`: map of name -> int (hours from UTC) for async overlap
- `blockers`: list of {member, blocker_text, since_minutes}

## Execution

### 1. Assign roles

For each team_member, default role by skill match:

| Role            | When to assign                                                    |
| --------------- | ----------------------------------------------------------------- |
| **PM / driver** | if no one has PM / lead / manager skill: pick the longest-tenured |
| **Frontend**    | has react / vue / svelte / typescript                             |
| **Backend**     | has python / node / go / rust / java                              |
| **AI / ML**     | has pytorch / tensorflow / llm / openai                           |
| **Data**        | has sql / pandas / etl / spark                                    |
| **Design**      | has figma / css / design / ux                                     |
| **Hardware**    | has arduino / esp32 / raspi                                       |
| **QA / verify** | anyone not yet assigned; rotation role                            |
| **Wildcard**    | last-resort assignment; helps whoever is blocked                  |

If no skill match, assign PM to member #1 and Wildcard to the rest.

### 2. Assign features

Greedy assignment:

```
remaining = plan_features (sorted by time_estimate_minutes desc)
for each role:
  while role has capacity AND remaining not empty:
    pick the top remaining feature whose role-skill matches
    assign to this member; remove from remaining
```

Capacity per role: 1 P0 + 1 P1 max, unless `team_size >= 4` then +1 P2.

### 3. Detect bottlenecks

For each member:

- count assigned P0 tasks
- if any blocker older than 60 min -> flag "stuck"
- if assigned zero tasks -> flag "free"

The bottleneck is the longest-stuck P0. The free member is the rescuer.

### 4. Emit the board

```
[PM]      alice  -> assign plan roles, coordinate, write README
[FE]      bob    -> KEEP: Auth UI     [stuck 90min: waiting on API key]
[BE]      carol  -> KEEP: Notes API   [ok]
[Wildcard] dave   -> KEEP: Billing    [free: help bob unblock]

Bottleneck: bob (P0 blocked 90min).
```

## Output contract

- `.hackathon/state/roster.json` (NEW schema)
- `.hackathon/artifacts/roster.md` (human-readable board)

## Acceptance criteria

- [ ] Every team_member has exactly one role.
- [ ] Every KEEP feature is assigned to exactly one member.
- [ ] Bottleneck section names the oldest-blocked P0.
- [ ] Free-member section names at least one member when any P0 is stuck.
- [ ] Output `roster.json` validates against `roster.schema.json`.

## Failure modes

- `team_size = 0` -> refuse; ask for at least one member.
- `plan_features` empty -> refuse; run `scope-knife` first.
- All members have identical skills -> assign PM to #1, rotate the rest.
- Single member -> assign all roles to them, flag "solo: consider merging with another team".

## Trigger phrases (for agent intent matching)

- "who is doing what"
- "assign roles"
- "who is free"
- "who is blocked"
- "who is on what"
- "team assignments"
