# Agent Team Collaboration Architecture

## System Design

### Shared Blackboard Pattern

```go
type SharedBoard struct {
    mu      sync.RWMutex
    entries []BoardEntry
}

type BoardEntry struct {
    Author  string
    Content string
    Type    string // "draft" | "challenge"
}
```

**Thread-safe operations**:
- `Add()`: Appends entries with write lock
- `ToContext()`: Reads all entries with read lock, formats as XML

### Execution Flow

```
HandleUserMessage()
    ↓
Master Planning Loop (iteration 0-4)
    ├─ Master analyzes user request
    ├─ Outputs ASSIGN:member:task lines
    ├─ parseAssignments() extracts tasks
    ├─ Creates new SharedBoard{}
    │
    ├─ runMembersParallel()
    │   ├─ For each assignment, spawn goroutine
    │   ├─ Each member sees current board snapshot
    │   ├─ Member executes task
    │   ├─ Result added to board as "draft"
    │   └─ WaitGroup ensures all complete
    │
    ├─ runChallengeRound()
    │   ├─ Filter members with CanChallenge=true
    │   ├─ For each challenger, spawn goroutine
    │   ├─ Challenger sees full board
    │   ├─ Outputs CHALLENGE:... or AGREE
    │   ├─ CHALLENGE entries added to board
    │   └─ WaitGroup ensures all complete
    │
    ├─ Master Review
    │   ├─ Receives board.ToContext()
    │   ├─ Sees all drafts and challenges
    │   ├─ Decides: DONE or re-ASSIGN
    │   └─ Loop continues if re-ASSIGN
    │
    └─ updateMasterMemory() (async)
```

### Concurrency Model

**Parallel Execution Phase**:
```go
var wg sync.WaitGroup
for memberName, task := range assignments {
    wg.Add(1)
    go func(name, t string) {
        defer wg.Done()
        // Execute task
        board.Add(name, result, "draft")
    }(memberName, task)
}
wg.Wait()  // Wait for all members
```

**Challenge Round Phase**:
```go
var wg sync.WaitGroup
for _, name := range challengers {
    wg.Add(1)
    go func(n string) {
        defer wg.Done()
        // Review board
        if strings.Contains(result, "CHALLENGE:") {
            board.Add(n, result, "challenge")
        }
    }(name)
}
wg.Wait()  // Wait for all challenges
```

### Context Injection

**Initial Draft Phase**:
```
Member System Prompt = Soul + Memory + [empty board]
```

**Challenge Round Phase**:
```
Member System Prompt = Soul + Memory + <team_board>
  <entry type="draft" author="member1">...</entry>
  <entry type="draft" author="member2">...</entry>
</team_board>
```

**Master Review Phase**:
```
Master Feedback = Team results + <team_board>
  <entry type="draft" author="member1">...</entry>
  <entry type="draft" author="member2">...</entry>
  <entry type="challenge" author="member1">...</entry>
</team_board>
```

### Event Streaming

Events emitted during execution:

1. **Parallel Phase**:
   - `EvtAgentMessage` with `role: "member"` (streaming)
   - `EvtTaskAssign` (task assignment)
   - `EvtWorkspaceFile` (if document generated)

2. **Challenge Phase**:
   - `EvtAgentMessage` with `role: "challenge"` (streaming)

3. **Status Updates**:
   - `EvtRoomStatus` with `status: "working"` → `"thinking"` → `"pending"`

### Configuration

**Agent AGENT.md**:
```yaml
---
name: agent_name
role: member
can_challenge: true  # Enable challenge participation
---
```

**Agent SOUL.md**:
- Includes challenge instructions
- Specifies how to output `CHALLENGE:...`
- Defines acceptance of challenges

## Benefits

1. **Parallelism**: Members work simultaneously, not sequentially
2. **Transparency**: All members see each other's work via board
3. **Quality Control**: Challenge round catches issues early
4. **Collaboration**: Members can question and improve each other's work
5. **Master Awareness**: Master sees full context before deciding
6. **Thread-Safe**: Concurrent access protected by mutexes
7. **Scalable**: Works with any number of members

## Backward Compatibility

- Existing master/member roles unchanged
- Challenge role is additive (new event type)
- Members without `can_challenge: true` skip challenge round
- No breaking changes to existing APIs
