Refactor team collaboration skills and update documentation

- Renamed `team-lifecycle-v5` to `team-lifecycle` across various documentation files for consistency.
- Updated references in code examples and usage sections to reflect the new skill name.
- Added a new command file for the `monitor` functionality in the `team-iterdev` skill, detailing the coordinator's monitoring events and task management.
- Introduced new components for dynamic pipeline visualization and session coordinates display in the frontend.
- Implemented utility functions for pipeline stage detection and status derivation based on message history.
- Enhanced the team role panel to map members to their respective pipeline roles with status indicators.
- Updated Chinese documentation to reflect the changes in skill names and descriptions.
This commit is contained in:
catlog22
2026-03-04 11:07:48 +08:00
parent 5e96722c09
commit ffd5282932
132 changed files with 2938 additions and 18916 deletions

View File

@@ -11,21 +11,23 @@ Deep collaborative analysis team skill. Splits monolithic analysis into 5-role c
## Architecture
```
+-------------------------------------------------------------+
| Skill(skill="team-ultra-analyze") |
| args="topic description" or args="--role=xxx" |
+----------------------------+--------------------------------+
| Role Router
+---- --role present? ----+
| NO | YES
v v
Orchestration Mode Role Dispatch
(auto -> coordinator) (route to role.md)
|
+-----+------+----------+-----------+
v v v v v
coordinator explorer analyst discussant synthesizer
EXPLORE-* ANALYZE-* DISCUSS-* SYNTH-*
+---------------------------------------------------+
| Skill(skill="team-ultra-analyze") |
| args="<topic-description>" |
+-------------------+-------------------------------+
|
Orchestration Mode (auto -> coordinator)
|
Coordinator (inline)
Phase 0-5 orchestration
|
+-------+-------+-------+-------+
v v v v
[tw] [tw] [tw] [tw]
explor- analy- discu- synthe-
er st ssant sizer
(tw) = team-worker agent
```
## Command Architecture
@@ -65,13 +67,13 @@ Parse `$ARGUMENTS` to extract `--role` and optional `--agent-name`. If `--role`
### Role Registry
| Role | File | Task Prefix | Type | Compact |
|------|------|-------------|------|---------|
| coordinator | [roles/coordinator/role.md](roles/coordinator/role.md) | (none) | orchestrator | **compress: must re-read** |
| explorer | [roles/explorer/role.md](roles/explorer/role.md) | EXPLORE-* | parallel worker | compress: must re-read |
| analyst | [roles/analyst/role.md](roles/analyst/role.md) | ANALYZE-* | parallel worker | compress: must re-read |
| discussant | [roles/discussant/role.md](roles/discussant/role.md) | DISCUSS-* | pipeline | compress: must re-read |
| synthesizer | [roles/synthesizer/role.md](roles/synthesizer/role.md) | SYNTH-* | pipeline | compress: must re-read |
| Role | Spec | Task Prefix | Inner Loop |
|------|------|-------------|------------|
| coordinator | [roles/coordinator/role.md](roles/coordinator/role.md) | (none) | - |
| explorer | [role-specs/explorer.md](role-specs/explorer.md) | EXPLORE-* | false |
| analyst | [role-specs/analyst.md](role-specs/analyst.md) | ANALYZE-* | false |
| discussant | [role-specs/discussant.md](role-specs/discussant.md) | DISCUSS-* | false |
| synthesizer | [role-specs/synthesizer.md](role-specs/synthesizer.md) | SYNTH-* | false |
> **COMPACT PROTECTION**: Role files are execution documents, not reference material. When context compression occurs and role instructions are reduced to summaries, you **must immediately `Read` the corresponding role.md to reload before continuing execution**. Never execute any Phase based on compressed summaries alone.
@@ -338,51 +340,43 @@ Beat 1 2 3 3a... 4
## Coordinator Spawn Template
When coordinator spawns workers, use background mode (Spawn-and-Stop pattern). The coordinator determines the depth (number of parallel agents) based on selected perspectives.
### v5 Worker Spawn (all roles)
**Phase 1 - Spawn Explorers**: Create depth explorer agents in parallel (EXPLORE-1 through EXPLORE-depth). Each explorer receives its assigned perspective/domain and agent name for task matching. All spawned with run_in_background:true. Coordinator stops after spawning and waits for callbacks.
When coordinator spawns workers, use `team-worker` agent with role-spec path. The coordinator determines depth (number of parallel agents) based on selected perspectives.
**Phase 2 - Spawn Analysts**: After all explorers complete, create depth analyst agents in parallel (ANALYZE-1 through ANALYZE-depth). Each analyst receives its assigned perspective matching the corresponding explorer. All spawned with run_in_background:true. Coordinator stops.
**Phase 1 - Spawn Explorers**: Create depth explorer team-worker agents in parallel (EXPLORE-1 through EXPLORE-depth). Each receives its assigned perspective/domain and agent name for task matching.
**Phase 3 - Spawn Discussant**: After all analysts complete, create 1 discussant. It processes all analysis results and presents findings to user. Coordinator stops.
**Phase 2 - Spawn Analysts**: After all explorers complete, create depth analyst team-worker agents in parallel (ANALYZE-1 through ANALYZE-depth).
**Phase 3a - Discussion Loop** (Deep mode only): Based on user feedback, coordinator may create additional ANALYZE-fix and DISCUSS tasks. Loop continues until user is satisfied or 5 rounds reached.
**Phase 3 - Spawn Discussant**: After all analysts complete, create 1 discussant. Coordinator stops.
**Phase 4 - Spawn Synthesizer**: After final discussion round, create 1 synthesizer. It integrates all explorations, analyses, and discussions into final conclusions. Coordinator stops.
**Phase 3a - Discussion Loop** (Deep mode only): Based on user feedback, coordinator may create additional ANALYZE-fix and DISCUSS tasks.
**Quick mode exception**: When depth=1, spawn single explorer, single analyst, single discussant, single synthesizer -- all as simple agents without numbered suffixes.
**Phase 4 - Spawn Synthesizer**: After final discussion round, create 1 synthesizer.
**Single spawn example** (worker template used for all roles):
**Quick mode exception**: When depth=1, spawn single explorer, single analyst, single discussant, single synthesizer without numbered suffixes.
**Single spawn template** (worker template used for all roles):
```
Task({
subagent_type: "general-purpose",
subagent_type: "team-worker",
description: "Spawn <role> worker",
team_name: <team-name>,
team_name: "ultra-analyze",
name: "<agent-name>",
run_in_background: true,
prompt: `You are team "<team-name>" <ROLE> (<agent-name>).
Your agent name is "<agent-name>", use it for task discovery owner matching.
prompt: `## Role Assignment
role: <role>
role_spec: .claude/skills/team-ultra-analyze/role-specs/<role>.md
session: <session-folder>
session_id: <session-id>
team_name: ultra-analyze
requirement: <topic-description>
agent_name: <agent-name>
inner_loop: false
## Primary Instruction
All work must be executed by calling Skill for role definition:
Skill(skill="team-ultra-analyze", args="--role=<role> --agent-name=<agent-name>")
Current topic: <task-description>
Session: <session-folder>
## Role Rules
- Only process <PREFIX>-* tasks where owner === "<agent-name>"
- All output prefixed with [<role>] identifier
- Communicate only with coordinator
- Do not use TaskCreate for other roles
- Call mcp__ccw-tools__team_msg before every SendMessage
## Workflow
1. Call Skill -> load role definition and execution logic
2. Execute role.md 5-Phase process
3. team_msg + SendMessage result to coordinator
4. TaskUpdate completed -> check next task`
Read role_spec file to load Phase 2-4 domain instructions.
Execute built-in Phase 1 (task discovery, owner=<agent-name>) -> role-spec Phase 2-4 -> built-in Phase 5 (report).`
})
```
@@ -419,6 +413,31 @@ Session: <session-folder>
| +-- issues.md
```
## Completion Action
When the pipeline completes (all tasks done, coordinator Phase 5):
```
AskUserQuestion({
questions: [{
question: "Ultra-Analyze pipeline complete. What would you like to do?",
header: "Completion",
multiSelect: false,
options: [
{ label: "Archive & Clean (Recommended)", description: "Archive session, clean up tasks and team resources" },
{ label: "Keep Active", description: "Keep session active for follow-up work or inspection" },
{ label: "Export Results", description: "Export deliverables to a specified location, then clean" }
]
}]
})
```
| Choice | Action |
|--------|--------|
| Archive & Clean | Update session status="completed" -> TeamDelete(ultra-analyze) -> output final summary |
| Keep Active | Update session status="paused" -> output resume instructions: `Skill(skill="team-ultra-analyze", args="resume")` |
| Export Results | AskUserQuestion for target path -> copy deliverables -> Archive & Clean |
## Session Resume
Coordinator supports `--resume` / `--continue` for interrupted sessions:

View File

@@ -1,210 +0,0 @@
# Command: analyze
> CLI 多视角深度分析。基于探索结果,通过 CLI 工具执行深度分析并生成结构化洞察。
## When to Use
- Phase 3 of Analyst
- 探索结果已就绪,需要深度分析
- 每个 ANALYZE-* 任务触发一次
**Trigger conditions**:
- Analyst Phase 2 完成后(上下文已加载)
- 方向调整时创建的 ANALYZE-fix 任务
## Strategy
### Delegation Mode
**Mode**: CLI通过 ccw cli 执行分析Bash run_in_background: true
### Decision Logic
```javascript
// 根据 perspective 选择 CLI 工具和分析模板
function buildAnalysisConfig(perspective, isDirectionFix) {
const configs = {
'technical': {
tool: 'gemini',
rule: 'analysis-analyze-code-patterns',
focus: 'Implementation patterns, code quality, technical debt, feasibility',
tasks: [
'Analyze code structure and organization patterns',
'Identify technical debt and anti-patterns',
'Evaluate error handling and edge cases',
'Assess testing coverage and quality'
]
},
'architectural': {
tool: 'claude',
rule: 'analysis-review-architecture',
focus: 'System design, scalability, component coupling, boundaries',
tasks: [
'Evaluate module boundaries and coupling',
'Analyze data flow and component interactions',
'Assess scalability and extensibility',
'Review design pattern usage and consistency'
]
},
'business': {
tool: 'codex',
rule: 'analysis-analyze-code-patterns',
focus: 'Business logic, domain models, value delivery, stakeholder impact',
tasks: [
'Map business logic to code implementation',
'Identify domain model completeness',
'Evaluate business rule enforcement',
'Assess impact on stakeholders and users'
]
},
'domain_expert': {
tool: 'gemini',
rule: 'analysis-analyze-code-patterns',
focus: 'Domain-specific patterns, standards compliance, best practices',
tasks: [
'Compare against domain best practices',
'Check standards and convention compliance',
'Identify domain-specific anti-patterns',
'Evaluate domain model accuracy'
]
}
}
const config = configs[perspective] || configs['technical']
if (isDirectionFix) {
config.rule = 'analysis-diagnose-bug-root-cause'
config.tasks = [
'Re-analyze from adjusted perspective',
'Identify previously missed patterns',
'Generate new insights from fresh angle',
'Update discussion points based on direction change'
]
}
return config
}
```
## Execution Steps
### Step 1: Context Preparation
```javascript
const config = buildAnalysisConfig(perspective, isDirectionFix)
// 构建探索上下文摘要
const explorationSummary = `
PRIOR EXPLORATION CONTEXT:
- Key files: ${(explorationContext.relevant_files || []).slice(0, 8).map(f => f.path || f).join(', ')}
- Patterns found: ${(explorationContext.patterns || []).slice(0, 5).join('; ')}
- Key findings: ${(explorationContext.key_findings || []).slice(0, 5).join('; ')}
- Questions from exploration: ${(explorationContext.questions_for_analysis || []).slice(0, 3).join('; ')}`
```
### Step 2: Execute CLI Analysis
```javascript
const cliPrompt = `PURPOSE: ${isDirectionFix
? `Supplementary analysis with adjusted focus on "${adjustedFocus}" for topic "${topic}"`
: `Deep analysis of "${topic}" from ${perspective} perspective`}
Success: ${isDirectionFix
? 'New insights from adjusted direction with clear evidence'
: 'Actionable insights with confidence levels and evidence references'}
${explorationSummary}
TASK:
${config.tasks.map(t => `${t}`).join('\n')}
• Generate structured findings with confidence levels (high/medium/low)
• Identify discussion points requiring user input
• List open questions needing further exploration
MODE: analysis
CONTEXT: @**/* | Topic: ${topic}
EXPECTED: JSON-structured analysis with sections: key_insights (with confidence), key_findings (with evidence), discussion_points, open_questions, recommendations (with priority)
CONSTRAINTS: Focus on ${perspective} perspective | ${dimensions.join(', ')} dimensions${isDirectionFix ? ` | Adjusted focus: ${adjustedFocus}` : ''}`
Bash({
command: `ccw cli -p "${cliPrompt}" --tool ${config.tool} --mode analysis --rule ${config.rule}`,
run_in_background: true
})
// ⚠️ STOP POINT: Wait for CLI callback before continuing
```
### Step 3: Result Processing
```javascript
// CLI 结果返回后,解析并结构化
const outputPath = `${sessionFolder}/analyses/analysis-${analyzeNum}.json`
// 从 CLI 输出中提取结构化数据
// CLI 输出通常是 markdown需要解析为 JSON
const analysisResult = {
perspective,
dimensions,
is_direction_fix: isDirectionFix,
adjusted_focus: adjustedFocus || null,
key_insights: [
// 从 CLI 输出提取,每个包含 {insight, confidence, evidence}
],
key_findings: [
// 具体发现 {finding, file_ref, impact}
],
discussion_points: [
// 需要用户输入的讨论要点
],
open_questions: [
// 未解决的问题
],
recommendations: [
// {action, rationale, priority}
],
_metadata: {
cli_tool: config.tool,
cli_rule: config.rule,
perspective,
is_direction_fix: isDirectionFix,
timestamp: new Date().toISOString()
}
}
Write(outputPath, JSON.stringify(analysisResult, null, 2))
```
## Output Format
```json
{
"perspective": "technical",
"dimensions": ["architecture", "implementation"],
"is_direction_fix": false,
"key_insights": [
{"insight": "Authentication uses stateless JWT", "confidence": "high", "evidence": "src/auth/jwt.ts:L42"}
],
"key_findings": [
{"finding": "No rate limiting on login endpoint", "file_ref": "src/routes/auth.ts:L15", "impact": "Security risk"}
],
"discussion_points": [
"Should we implement token rotation for refresh tokens?"
],
"open_questions": [
"What is the expected concurrent user load?"
],
"recommendations": [
{"action": "Add rate limiting to auth endpoints", "rationale": "Prevent brute force attacks", "priority": "high"}
],
"_metadata": {"cli_tool": "gemini", "cli_rule": "analysis-analyze-code-patterns", "timestamp": "..."}
}
```
## Error Handling
| Scenario | Resolution |
|----------|------------|
| CLI tool unavailable | Try fallback: gemini → codex → claude |
| CLI timeout | Retry with shorter prompt, or use exploration results directly |
| CLI returns empty | Use exploration findings as-is, note analysis gap |
| Invalid CLI output | Extract what's parseable, fill gaps with defaults |
| Exploration context missing | Analyze with topic keywords only |

View File

@@ -1,251 +0,0 @@
# Analyst Role
深度分析师。基于 explorer 的代码库探索结果,通过 CLI 多视角深度分析,生成结构化洞察和讨论要点。
## Identity
- **Name**: `analyst` | **Tag**: `[analyst]`
- **Task Prefix**: `ANALYZE-*`
- **Responsibility**: Read-only analysis (深度分析)
## Boundaries
### MUST
- Only process `ANALYZE-*` prefixed tasks
- All output (SendMessage, team_msg, logs) must carry `[analyst]` identifier
- Only communicate with coordinator via SendMessage
- Work strictly within deep analysis responsibility scope
- Base analysis on explorer exploration results
- Share analysis results via team_msg(type='state_update')
### MUST NOT
- Execute codebase exploration (belongs to explorer)
- Handle user feedback (belongs to discussant)
- Generate final conclusions (belongs to synthesizer)
- Create tasks for other roles (TaskCreate is coordinator-exclusive)
- Communicate directly with other worker roles
- Modify source code
- Omit `[analyst]` identifier in any output
---
## Toolbox
### Available Commands
| Command | File | Phase | Description |
|---------|------|-------|-------------|
| `analyze` | [commands/analyze.md](commands/analyze.md) | Phase 3 | CLI 多视角深度分析 |
### Tool Capabilities
| Tool | Type | Used By | Purpose |
|------|------|---------|---------|
| `Bash` | CLI | analyze.md | Execute ccw cli for analysis |
| `Read` | File | analyst | Read exploration results and session context |
| `Write` | File | analyst | Write analysis results |
| `Glob` | File | analyst | Find exploration/analysis files |
### CLI Tools
| CLI Tool | Mode | Used By | Purpose |
|----------|------|---------|---------|
| `gemini` | analysis | analyze.md | 技术/领域分析 |
| `codex` | analysis | analyze.md | 业务视角分析 |
| `claude` | analysis | analyze.md | 架构视角分析 |
---
## Message Types
| Type | Direction | Trigger | Description |
|------|-----------|---------|-------------|
| `analysis_ready` | analyst → coordinator | 分析完成 | 包含洞察、讨论要点、开放问题 |
| `error` | analyst → coordinator | 分析失败 | 阻塞性错误 |
## Message Bus
Before every SendMessage, log via `mcp__ccw-tools__team_msg`:
```
mcp__ccw-tools__team_msg({
operation: "log",
session_id: <session-id>,
from: "analyst",
type: "analysis_ready",
ref: "<output-path>"
})
```
> `to` and `summary` are auto-defaulted by the tool.
**CLI fallback** (when MCP unavailable):
```
Bash("ccw team log --session-id <session-id> --from analyst --type analysis_ready --ref <path> --json")
```
---
## Execution (5-Phase)
### Phase 1: Task Discovery
> See SKILL.md Shared Infrastructure -> Worker Phase 1: Task Discovery
Standard task discovery flow: TaskList -> filter by prefix `ANALYZE-*` + owner match + pending + unblocked -> TaskGet -> TaskUpdate in_progress.
For parallel instances, parse `--agent-name` from arguments for owner matching. Falls back to `analyst` for single-instance roles.
### Phase 2: Context Loading
**Loading steps**:
1. Extract session path from task description
2. Extract topic, perspective, dimensions from task metadata
3. Check for direction-fix type (补充分析)
4. Read role states via team_msg(operation="get_state") for existing context
5. Read corresponding exploration results
**Context extraction**:
| Field | Source | Pattern |
|-------|--------|---------|
| sessionFolder | task description | `session:\s*(.+)` |
| topic | task description | `topic:\s*(.+)` |
| perspective | task description | `perspective:\s*(.+)` or default "technical" |
| dimensions | task description | `dimensions:\s*(.+)` or default "general" |
| isDirectionFix | task description | `type:\s*direction-fix` |
| adjustedFocus | task description | `adjusted_focus:\s*(.+)` |
**Exploration context loading**:
| Condition | Source |
|-----------|--------|
| Direction fix | Read ALL exploration files, merge context |
| Normal analysis | Read exploration file matching ANALYZE-N number |
| Fallback | Read first available exploration file |
**CLI tool selection**:
| Perspective | CLI Tool |
|-------------|----------|
| technical | gemini |
| architectural | claude |
| business | codex |
| domain_expert | gemini |
### Phase 3: Deep Analysis via CLI
Delegate to `commands/analyze.md` if available, otherwise execute inline.
**Analysis prompt structure** (Direction Fix):
```
PURPOSE: 补充分析 - 方向调整至 "<adjusted_focus>"
Success: 针对新方向的深入洞察
PRIOR EXPLORATION CONTEXT:
- Key files: <top 5 files from exploration>
- Patterns: <top 3 patterns>
- Previous findings: <top 3 findings>
TASK:
- Focus analysis on: <adjusted_focus>
- Build on previous exploration findings
- Identify new insights from adjusted perspective
- Generate discussion points for user
MODE: analysis
CONTEXT: @**/* | Topic: <topic>
EXPECTED: Structured analysis with adjusted focus, new insights, updated discussion points
CONSTRAINTS: Focus on <adjusted_focus>
```
**Analysis prompt structure** (Normal):
```
PURPOSE: Analyze topic '<topic>' from <perspective> perspective across <dimensions> dimensions
Success: Actionable insights with clear reasoning and evidence
PRIOR EXPLORATION CONTEXT:
- Key files: <top 5 files from exploration>
- Patterns found: <top 3 patterns>
- Key findings: <top 3 findings>
TASK:
- Build on exploration findings above
- Analyze from <perspective> perspective: <dimensions>
- Identify patterns, anti-patterns, and opportunities
- Generate discussion points for user clarification
- Assess confidence level for each insight
MODE: analysis
CONTEXT: @**/* | Topic: <topic>
EXPECTED: Structured analysis with: key insights (with confidence), discussion points, open questions, recommendations with rationale
CONSTRAINTS: Focus on <dimensions> | <perspective> perspective
```
**CLI execution**:
```
Bash({
command: "ccw cli -p \"<analysis-prompt>\" --tool <cli-tool> --mode analysis",
run_in_background: true
})
// STOP POINT: Wait for CLI callback
```
### Phase 4: Result Aggregation
**Analysis output structure**:
| Field | Description |
|-------|-------------|
| perspective | Analysis perspective |
| dimensions | Analysis dimensions |
| is_direction_fix | Boolean for direction fix mode |
| adjusted_focus | Focus area if direction fix |
| key_insights | Main insights with confidence levels |
| key_findings | Specific findings |
| discussion_points | Points for user discussion |
| open_questions | Unresolved questions |
| recommendations | Actionable recommendations |
| evidence | Supporting evidence references |
**Output path**: `<session-folder>/analyses/analysis-<num>.json`
### Phase 5: Report to Coordinator
> See SKILL.md Shared Infrastructure -> Worker Phase 5: Report
Standard report flow: team_msg log -> SendMessage with `[analyst]` prefix -> TaskUpdate completed -> Loop to Phase 1 for next task.
**Shared memory update**:
```
sharedMemory.analyses.push({
id: "analysis-<num>",
perspective: <perspective>,
is_direction_fix: <boolean>,
insight_count: <count>,
finding_count: <count>,
timestamp: <timestamp>
})
```
---
## Error Handling
| Scenario | Resolution |
|----------|------------|
| No ANALYZE-* tasks available | Idle, wait for coordinator assignment |
| CLI tool unavailable | Fallback chain: gemini -> codex -> claude |
| No exploration results found | Analyze with topic keywords only, note limitation |
| CLI timeout | Use partial results, report incomplete |
| Invalid exploration JSON | Skip context, analyze from scratch |
| Command file not found | Fall back to inline execution |

View File

@@ -1,461 +1,324 @@
# Command: monitor
# Command: Monitor
> 阶段驱动的协调循环 + 讨论循环。按 pipeline 阶段顺序等待 worker 完成,驱动讨论循环,执行最终综合触发。
Handle all coordinator monitoring events: worker callbacks, status checks, pipeline advancement, discussion loop control, and completion.
## When to Use
## Constants
- Phase 4 of Coordinator
- 任务链已创建并分发
- 需要持续监控直到所有任务完成
| Key | Value |
|-----|-------|
| SPAWN_MODE | background |
| ONE_STEP_PER_INVOCATION | true |
| WORKER_AGENT | team-worker |
| MAX_DISCUSSION_ROUNDS_QUICK | 0 |
| MAX_DISCUSSION_ROUNDS_STANDARD | 1 |
| MAX_DISCUSSION_ROUNDS_DEEP | 5 |
**Trigger conditions**:
- dispatch 完成后立即启动
- 讨论循环创建新任务后重新进入
## Phase 2: Context Loading
## Strategy
| Input | Source | Required |
|-------|--------|----------|
| Session state | `<session>/session.json` | Yes |
| Task list | `TaskList()` | Yes |
| Trigger event | From Entry Router detection | Yes |
| Pipeline mode | From session.json `pipeline_mode` | Yes |
| Discussion round | From session.json `discussion_round` | Yes |
### Delegation Mode
1. Load session.json for current state, `pipeline_mode`, `discussion_round`
2. Run `TaskList()` to get current task statuses
3. Identify trigger event type from Entry Router
4. Compute max discussion rounds from pipeline mode:
**Mode**: Stage-driven按阶段顺序等待非轮询+ Discussion-loop讨论循环由 coordinator 驱动)
### 设计原则
> **模型执行没有时间概念,禁止任何形式的轮询等待。**
>
> - ❌ 禁止: `while` 循环 + `sleep` + 检查状态(空转浪费 API 轮次)
> - ❌ 禁止: `Bash(sleep N)` / `Bash(timeout /t N)` 作为等待手段
> - ✅ 采用: 同步 `Task()` 调用(`run_in_background: false`call 本身即等待
> - ✅ 采用: Worker 返回 = 阶段完成信号(天然回调)
>
> **原理**: `Task(run_in_background: false)` 是阻塞调用coordinator 自动挂起直到 worker 返回。
> 无需 sleep无需轮询无需消息总线监控。Worker 的返回就是回调。
### Decision Logic
```javascript
// 消息路由表
const routingTable = {
// Explorer 完成
'exploration_ready': { action: 'Mark EXPLORE complete, unblock ANALYZE' },
// Analyst 完成
'analysis_ready': { action: 'Mark ANALYZE complete, unblock DISCUSS or SYNTH' },
// Discussant 完成
'discussion_processed': { action: 'Mark DISCUSS complete, trigger user feedback collection', special: 'discussion_feedback' },
// Synthesizer 完成
'synthesis_ready': { action: 'Mark SYNTH complete, prepare final report', special: 'finalize' },
// 错误
'error': { action: 'Assess severity, retry or escalate', special: 'error_handler' }
}
```
MAX_ROUNDS = pipeline_mode === 'deep' ? 5
: pipeline_mode === 'standard' ? 1
: 0
```
### Stage-Worker 映射表
## Phase 3: Event Handlers
```javascript
const STAGE_WORKER_MAP = {
'EXPLORE': { role: 'explorer', skillArgs: '--role=explorer' },
'ANALYZE': { role: 'analyst', skillArgs: '--role=analyst' },
'DISCUSS': { role: 'discussant', skillArgs: '--role=discussant' },
'SYNTH': { role: 'synthesizer', skillArgs: '--role=synthesizer' }
}
### handleCallback
// ★ 统一 auto mode 检测
const autoYes = /\b(-y|--yes)\b/.test(args)
Triggered when a worker sends completion message (via SendMessage callback).
1. Parse message to identify role and task ID:
| Message Pattern | Role Detection |
|----------------|---------------|
| `[explorer]` or task ID `EXPLORE-*` | explorer |
| `[analyst]` or task ID `ANALYZE-*` | analyst |
| `[discussant]` or task ID `DISCUSS-*` | discussant |
| `[synthesizer]` or task ID `SYNTH-*` | synthesizer |
2. Mark task as completed:
```
TaskUpdate({ taskId: "<task-id>", status: "completed" })
```
## Execution Steps
3. Record completion in session state via team_msg
### Step 1: Context Preparation
4. **Role-specific post-completion logic**:
```javascript
// 从 role state 获取当前状态
const sharedMemory = mcp__ccw-tools__team_msg({ operation: "get_state", session_id: sessionId })
| Completed Role | Pipeline Mode | Post-Completion Action |
|---------------|---------------|------------------------|
| explorer | all | Log: exploration ready. Proceed to handleSpawnNext |
| analyst | all | Log: analysis ready. Proceed to handleSpawnNext |
| discussant | all | **Discussion feedback gate** (see below) |
| synthesizer | all | Proceed to handleComplete |
let discussionRound = 0
const MAX_DISCUSSION_ROUNDS = pipelineMode === 'deep' ? 5 : (pipelineMode === 'standard' ? 1 : 0)
5. **Discussion Feedback Gate** (when discussant completes):
When a DISCUSS-* task completes, the coordinator collects user feedback BEFORE spawning the next task. This replaces any while-loop pattern.
// 获取 pipeline 阶段列表(来自 dispatch 创建的任务链)
const allTasks = TaskList()
const pipelineTasks = allTasks
.filter(t => t.owner && t.owner !== 'coordinator')
.sort((a, b) => Number(a.id) - Number(b.id))
```
// Read current discussion_round from session state
discussion_round = session.discussion_round || 0
discussion_round++
### Step 2: Sequential Stage Execution (Stop-Wait) — Exploration + Analysis
// Update session state
Update session.json: discussion_round = discussion_round
> **核心**: 逐阶段 spawn worker同步阻塞等待返回。
> Worker 返回 = 阶段完成。无 sleep、无轮询、无消息总线监控。
// Check if discussion loop applies
IF pipeline_mode === 'quick':
// No discussion in quick mode -- proceed to handleSpawnNext (SYNTH)
-> handleSpawnNext
```javascript
// 处理 EXPLORE 和 ANALYZE 阶段
const preDiscussionTasks = pipelineTasks.filter(t =>
t.subject.startsWith('EXPLORE-') || t.subject.startsWith('ANALYZE-')
)
ELSE IF discussion_round >= MAX_ROUNDS:
// Reached max rounds -- force proceed to synthesis
Log: "Max discussion rounds reached, proceeding to synthesis"
IF no SYNTH-001 task exists:
Create SYNTH-001 task blocked by last DISCUSS task
-> handleSpawnNext
for (const stageTask of preDiscussionTasks) {
// 1. 提取阶段前缀 → 确定 worker 角色
const stagePrefix = stageTask.subject.match(/^(\w+)-/)?.[1]
const workerConfig = STAGE_WORKER_MAP[stagePrefix]
if (!workerConfig) continue
// 2. 标记任务为执行中
TaskUpdate({ taskId: stageTask.id, status: 'in_progress' })
mcp__ccw-tools__team_msg({
operation: "log", session_id: sessionId, from: "coordinator",
to: workerConfig.role, type: "task_unblocked",
summary: `[coordinator] 启动阶段: ${stageTask.subject}${workerConfig.role}`
})
// 3. 同步 spawn worker — 阻塞直到 worker 返回Stop-Wait 核心)
const workerResult = Task({
subagent_type: "team-worker",
description: `Spawn ${workerConfig.role} worker for ${stageTask.subject}`,
team_name: teamName,
name: workerConfig.role,
prompt: `## Role Assignment
role: ${workerConfig.role}
role_spec: .claude/skills/team-ultra-analyze/role-specs/${workerConfig.role}.md
session: ${sessionFolder}
session_id: ${sessionId}
team_name: ${teamName}
requirement: ${stageTask.description || taskDescription}
inner_loop: false
## Current Task
- Task ID: ${stageTask.id}
- Task: ${stageTask.subject}
Read role_spec file to load Phase 2-4 domain instructions.
Execute built-in Phase 1 -> role-spec Phase 2-4 -> built-in Phase 5.`,
run_in_background: false
})
// 4. Worker 已返回 — 检查结果
const taskState = TaskGet({ taskId: stageTask.id })
if (taskState.status !== 'completed') {
handleStageTimeout(stageTask, 0, autoYes)
} else {
mcp__ccw-tools__team_msg({
operation: "log", session_id: sessionId, from: "coordinator",
to: "user", type: "quality_gate",
summary: `[coordinator] 阶段完成: ${stageTask.subject}`
})
}
}
```
### Step 2.1: Update discussion.md with Round 1
```javascript
// 读取所有探索和分析结果
const explorationFiles = Glob({ pattern: `${sessionFolder}/explorations/*.json` })
const analysisFiles = Glob({ pattern: `${sessionFolder}/analyses/*.json` })
const explorations = explorationFiles.map(f => JSON.parse(Read(f)))
const analyses = analysisFiles.map(f => JSON.parse(Read(f)))
// 更新 discussion.md — Round 1
const round1Content = `
### Round 1 - Initial Exploration & Analysis (${new Date().toISOString()})
#### Exploration Results
${explorations.map(e => `- **${e.perspective || 'general'}**: ${e.key_findings?.slice(0, 3).join('; ') || 'No findings'}`).join('\n')}
#### Analysis Results
${analyses.map(a => `- **${a.perspective || 'general'}**: ${a.key_insights?.slice(0, 3).join('; ') || 'No insights'}`).join('\n')}
#### Key Findings
${analyses.flatMap(a => a.key_findings || []).slice(0, 5).map(f => `- ${f}`).join('\n')}
#### Discussion Points
${analyses.flatMap(a => a.discussion_points || []).slice(0, 5).map(p => `- ${p}`).join('\n')}
#### Decision Log
> **Decision**: Selected ${pipelineMode} pipeline with ${explorations.length} exploration(s) and ${analyses.length} analysis perspective(s)
> - **Context**: Topic analysis and user preference
> - **Chosen**: ${pipelineMode} mode — **Reason**: ${pipelineMode === 'quick' ? 'Fast overview requested' : pipelineMode === 'deep' ? 'Thorough analysis needed' : 'Balanced depth and breadth'}
`
Edit({
file_path: `${sessionFolder}/discussion.md`,
old_string: '## Discussion Timeline\n',
new_string: `## Discussion Timeline\n${round1Content}\n`
})
```
### Step 3: Discussion Loop (Standard/Deep mode)
```javascript
if (MAX_DISCUSSION_ROUNDS === 0) {
// Quick mode: skip discussion, go to synthesis
createSynthesisTask(sessionFolder, [lastAnalyzeTaskId])
} else {
// Wait for initial DISCUSS-001 to complete
// Then enter discussion loop
while (discussionRound < MAX_DISCUSSION_ROUNDS) {
// 等待当前 DISCUSS 任务完成Stop-Wait: spawn discussant worker
const currentDiscussId = `DISCUSS-${String(discussionRound + 1).padStart(3, '0')}`
const discussTask = pipelineTasks.find(t => t.subject.startsWith(currentDiscussId))
if (discussTask) {
TaskUpdate({ taskId: discussTask.id, status: 'in_progress' })
const discussResult = Task({
subagent_type: "team-worker",
description: `Spawn discussant worker for ${discussTask.subject}`,
team_name: teamName,
name: "discussant",
prompt: `## Role Assignment
role: discussant
role_spec: .claude/skills/team-ultra-analyze/role-specs/discussant.md
session: ${sessionFolder}
session_id: ${sessionId}
team_name: ${teamName}
requirement: Discussion round ${discussionRound + 1}
inner_loop: false
## Current Task
- Task ID: ${discussTask.id}
- Task: ${discussTask.subject}
Read role_spec file to load Phase 2-4 domain instructions.
Execute built-in Phase 1 -> role-spec Phase 2-4 -> built-in Phase 5.`,
run_in_background: false
})
}
// 收集用户反馈
const feedbackResult = AskUserQuestion({
ELSE:
// Collect user feedback
AskUserQuestion({
questions: [{
question: `Round ${discussionRound + 1} 分析结果已就绪。请选择下一步:`,
question: "Discussion round <N> complete. What next?",
header: "Discussion Feedback",
multiSelect: false,
options: [
{ label: "同意,继续深入", description: "分析方向正确,继续深入探索" },
{ label: "需要调整方向", description: "有不同理解或关注点" },
{ label: "分析完成", description: "已获得足够信息" },
{ label: "有具体问题", description: "有特定问题需要解答" }
{ label: "Continue deeper", description: "Current direction is good, go deeper" },
{ label: "Adjust direction", description: "Shift analysis focus" },
{ label: "Done", description: "Sufficient depth, proceed to synthesis" }
]
}]
})
const feedback = feedbackResult["Discussion Feedback"]
// 📌 记录用户反馈到 decision_trail
const latestMemory = mcp__ccw-tools__team_msg({ operation: "get_state", session_id: sessionId })
latestMemory.decision_trail = latestMemory.decision_trail || []
latestMemory.decision_trail.push({
round: discussionRound + 1,
decision: feedback,
context: `User feedback at discussion round ${discussionRound + 1}`,
timestamp: new Date().toISOString()
})
mcp__ccw-tools__team_msg({
operation: "log", session_id: sessionId, from: "coordinator",
type: "state_update",
data: { decision_trail: latestMemory.decision_trail }
})
if (feedback === "分析完成") {
// 📌 Record completion decision
appendToDiscussion(sessionFolder, discussionRound + 1, {
user_input: "分析完成",
decision: "Exit discussion loop, proceed to synthesis",
reason: "User satisfied with current analysis depth"
})
break
}
if (feedback === "需要调整方向") {
// 收集调整方向
const directionResult = AskUserQuestion({
questions: [{
question: "请选择新的关注方向:",
header: "Direction Adjustment",
multiSelect: false,
options: [
{ label: "代码细节", description: "深入具体代码实现" },
{ label: "架构层面", description: "关注系统架构设计" },
{ label: "最佳实践", description: "对比行业最佳实践" },
{ label: "自定义", description: "输入自定义方向" }
]
}]
})
const newDirection = directionResult["Direction Adjustment"]
// 📌 Record direction change
appendToDiscussion(sessionFolder, discussionRound + 1, {
user_input: `调整方向: ${newDirection}`,
decision: `Direction adjusted to: ${newDirection}`,
reason: "User requested focus change"
})
// 创建补充分析 + 新讨论任务
const fixId = createAnalysisFix(discussionRound + 1, newDirection, sessionFolder)
discussionRound++
createDiscussionTask(discussionRound + 1, 'direction-adjusted', newDirection, sessionFolder)
continue
}
if (feedback === "有具体问题") {
// 📌 Record question
appendToDiscussion(sessionFolder, discussionRound + 1, {
user_input: "有具体问题(由 discussant 处理)",
decision: "Create discussion task for specific questions"
})
discussionRound++
createDiscussionTask(discussionRound + 1, 'specific-questions', 'User has specific questions', sessionFolder)
continue
}
// 同意,继续深入
appendToDiscussion(sessionFolder, discussionRound + 1, {
user_input: "同意,继续深入",
decision: "Continue deepening in current direction"
})
discussionRound++
if (discussionRound < MAX_DISCUSSION_ROUNDS) {
createDiscussionTask(discussionRound + 1, 'deepen', 'Continue current direction', sessionFolder)
}
}
// 创建最终综合任务
const lastDiscussTaskId = getLastCompletedTaskId('DISCUSS')
createSynthesisTask(sessionFolder, [lastDiscussTaskId])
}
```
### Step 3.1: Discussion Helper Functions
6. **Feedback handling** (still inside handleCallback, after AskUserQuestion returns):
```javascript
function appendToDiscussion(sessionFolder, round, data) {
const roundContent = `
### Round ${round + 1} - Discussion (${new Date().toISOString()})
| Feedback | Action |
|----------|--------|
| "Continue deeper" | Create new DISCUSS-`<N+1>` task (pending, no blockedBy). Record decision in discussion.md. Proceed to handleSpawnNext |
| "Adjust direction" | AskUserQuestion for new focus. Create ANALYZE-fix-`<N>` task (pending). Create DISCUSS-`<N+1>` task (pending, blockedBy ANALYZE-fix-`<N>`). Record direction change in discussion.md. Proceed to handleSpawnNext |
| "Done" | Create SYNTH-001 task (pending, blockedBy last DISCUSS). Record decision in discussion.md. Proceed to handleSpawnNext |
#### User Input
${data.user_input}
**Dynamic task creation templates**:
#### Decision Log
> **Decision**: ${data.decision}
> - **Context**: Discussion round ${round + 1}
> - **Reason**: ${data.reason || 'User-directed'}
#### Updated Understanding
${data.updated_understanding || '(Updated by discussant)'}
`
// Append to discussion.md
const currentContent = Read(`${sessionFolder}/discussion.md`)
Write(`${sessionFolder}/discussion.md`, currentContent + roundContent)
}
function handleStageTimeout(stageTask, _unused, autoYes) {
if (autoYes) {
mcp__ccw-tools__team_msg({
operation: "log", session_id: sessionId, from: "coordinator",
to: "user", type: "error",
summary: `[coordinator] [auto] 阶段 ${stageTask.subject} worker 返回但未完成,自动跳过`
})
TaskUpdate({ taskId: stageTask.id, status: 'deleted' })
return
}
const decision = AskUserQuestion({
questions: [{
question: `阶段 "${stageTask.subject}" worker 返回但未完成。如何处理?`,
header: "Stage Fail",
multiSelect: false,
options: [
{ label: "重试", description: "重新 spawn worker 执行此阶段" },
{ label: "跳过此阶段", description: "标记为跳过,继续后续流水线" },
{ label: "终止流水线", description: "停止整个分析流程" }
]
}]
})
const answer = decision["Stage Fail"]
if (answer === "跳过此阶段") {
TaskUpdate({ taskId: stageTask.id, status: 'deleted' })
} else if (answer === "终止流水线") {
mcp__ccw-tools__team_msg({
operation: "log", session_id: sessionId, from: "coordinator",
to: "user", type: "shutdown",
summary: `[coordinator] 用户终止流水线,当前阶段: ${stageTask.subject}`
})
}
}
DISCUSS-N (subsequent round):
```
TaskCreate({
subject: "DISCUSS-<NNN>",
description: "PURPOSE: Process discussion round <N> | Success: Updated understanding
TASK:
- Process previous round results
- Execute <type> discussion strategy
- Update discussion timeline
CONTEXT:
- Session: <session-folder>
- Topic: <topic>
- Round: <N>
- Type: <deepen|direction-adjusted|specific-questions>
- Shared memory: <session>/wisdom/.msg/meta.json
EXPECTED: <session>/discussions/discussion-round-<NNN>.json
---
InnerLoop: false",
status: "pending"
})
```
### Step 4: Wait for Synthesis + Result Processing
```javascript
// 等待 SYNTH-001 完成Stop-Wait: spawn synthesizer worker
const synthTask = pipelineTasks.find(t => t.subject.startsWith('SYNTH-'))
if (synthTask) {
TaskUpdate({ taskId: synthTask.id, status: 'in_progress' })
const synthResult = Task({
subagent_type: "general-purpose",
description: `Spawn synthesizer worker for ${synthTask.subject}`,
team_name: teamName,
name: "synthesizer",
prompt: `你是 team "${teamName}" 的 SYNTHESIZER。
## Primary Directive
Skill(skill="team-ultra-analyze", args="--role=synthesizer")
## Assignment
- Task ID: ${synthTask.id}
- Task: ${synthTask.subject}
- Session: ${sessionFolder}
## Workflow
1. Skill(skill="team-ultra-analyze", args="--role=synthesizer") to load role definition
2. Execute task per role.md
3. TaskUpdate({ taskId: "${synthTask.id}", status: "completed" })
All outputs carry [synthesizer] tag.`,
run_in_background: false
})
}
// 汇总所有结果
const finalMemory = mcp__ccw-tools__team_msg({ operation: "get_state", session_id: sessionId })
const allFinalTasks = TaskList()
const workerTasks = allFinalTasks.filter(t => t.owner && t.owner !== 'coordinator')
const summary = {
total_tasks: workerTasks.length,
completed_tasks: workerTasks.filter(t => t.status === 'completed').length,
discussion_rounds: discussionRound,
has_synthesis: !!finalMemory.synthesis,
decisions_made: finalMemory.decision_trail?.length || 0
}
ANALYZE-fix-N (direction adjustment):
```
TaskCreate({
subject: "ANALYZE-fix-<N>",
description: "PURPOSE: Supplementary analysis with adjusted focus | Success: New insights from adjusted direction
TASK:
- Re-analyze from adjusted perspective: <adjusted_focus>
- Build on previous exploration findings
- Generate updated discussion points
CONTEXT:
- Session: <session-folder>
- Topic: <topic>
- Type: direction-fix
- Adjusted focus: <adjusted_focus>
- Shared memory: <session>/wisdom/.msg/meta.json
EXPECTED: <session>/analyses/analysis-fix-<N>.json
---
InnerLoop: false",
status: "pending"
})
```
## Output Format
SYNTH-001 (created dynamically in deep mode):
```
TaskCreate({
subject: "SYNTH-001",
description: "PURPOSE: Integrate all analysis into final conclusions | Success: Executive summary with recommendations
TASK:
- Load all exploration, analysis, and discussion artifacts
- Extract themes, consolidate evidence, prioritize recommendations
- Write conclusions and update discussion.md
CONTEXT:
- Session: <session-folder>
- Topic: <topic>
- Upstream artifacts: explorations/*.json, analyses/*.json, discussions/*.json
- Shared memory: <session>/wisdom/.msg/meta.json
EXPECTED: <session>/conclusions.json + discussion.md update
CONSTRAINTS: Pure integration, no new exploration
---
InnerLoop: false",
blockedBy: ["<last-DISCUSS-task-id>"],
status: "pending"
})
```
7. Record user feedback to decision_trail via team_msg:
```
## Coordination Summary
### Pipeline Status: COMPLETE
### Mode: [quick|standard|deep]
### Tasks: [completed]/[total]
### Discussion Rounds: [count]
### Decisions Made: [count]
### Message Log (last 10)
- [timestamp] [from] → [to]: [type] - [summary]
mcp__ccw-tools__team_msg({
operation: "log", session_id: sessionId, from: "coordinator",
type: "state_update",
data: { decision_trail_entry: {
round: discussion_round,
decision: feedback,
context: "User feedback at discussion round N",
timestamp: current ISO timestamp
}}
})
```
8. Proceed to handleSpawnNext
### handleSpawnNext
Find and spawn the next ready tasks.
1. Scan task list for tasks where:
- Status is "pending"
- All blockedBy tasks have status "completed"
2. For each ready task, determine role from task prefix:
| Task Prefix | Role | Role Spec |
|-------------|------|-----------|
| `EXPLORE-*` | explorer | `.claude/skills/team-ultra-analyze/role-specs/explorer.md` |
| `ANALYZE-*` | analyst | `.claude/skills/team-ultra-analyze/role-specs/analyst.md` |
| `DISCUSS-*` | discussant | `.claude/skills/team-ultra-analyze/role-specs/discussant.md` |
| `SYNTH-*` | synthesizer | `.claude/skills/team-ultra-analyze/role-specs/synthesizer.md` |
3. Spawn team-worker for each ready task:
```
Task({
subagent_type: "team-worker",
description: "Spawn <role> worker for <task-subject>",
team_name: "ultra-analyze",
name: "<agent-name>",
run_in_background: true,
prompt: `## Role Assignment
role: <role>
role_spec: .claude/skills/team-ultra-analyze/role-specs/<role>.md
session: <session-folder>
session_id: <session-id>
team_name: ultra-analyze
requirement: <task-description>
agent_name: <agent-name>
inner_loop: false
## Current Task
- Task ID: <task-id>
- Task: <task-subject>
Read role_spec file to load Phase 2-4 domain instructions.
Execute built-in Phase 1 (task discovery, owner=<agent-name>) -> role-spec Phase 2-4 -> built-in Phase 5 (report).`
})
```
4. **Parallel spawn rules**:
| Mode | Stage | Spawn Behavior |
|------|-------|---------------|
| quick | All stages | One worker at a time (serial pipeline) |
| standard/deep | EXPLORE phase | Spawn all EXPLORE-001..N in parallel |
| standard/deep | ANALYZE phase | Spawn all ANALYZE-001..N in parallel |
| all | DISCUSS phase | One discussant at a time |
| all | SYNTH phase | One synthesizer |
5. **STOP** after spawning -- wait for next callback
### handleCheck
Output current pipeline status without advancing.
```
Pipeline Status (<mode> mode):
[DONE] EXPLORE-001 (explorer) -> exploration-001.json
[DONE] EXPLORE-002 (explorer) -> exploration-002.json
[DONE] ANALYZE-001 (analyst) -> analysis-001.json
[RUN] ANALYZE-002 (analyst) -> analyzing...
[WAIT] DISCUSS-001 (discussant) -> blocked by ANALYZE-002
[----] SYNTH-001 (synthesizer) -> blocked by DISCUSS-001
Discussion Rounds: 0/<max>
Pipeline Mode: <mode>
Session: <session-id>
```
Output status -- do NOT advance pipeline.
### handleResume
Resume pipeline after user pause or interruption.
1. Audit task list for inconsistencies:
- Tasks stuck in "in_progress" -> reset to "pending"
- Tasks with completed blockers but still "pending" -> include in spawn list
2. Proceed to handleSpawnNext
### handleComplete
Triggered when all pipeline tasks are completed.
**Completion check**:
| Mode | Completion Condition |
|------|---------------------|
| quick | EXPLORE-001 + ANALYZE-001 + SYNTH-001 all completed |
| standard | All EXPLORE + ANALYZE + DISCUSS-001 + SYNTH-001 completed |
| deep | All EXPLORE + ANALYZE + all DISCUSS-N + SYNTH-001 completed |
1. Verify all tasks completed. If any not completed, return to handleSpawnNext
2. If all completed, transition to coordinator Phase 5
## Phase 4: State Persistence
After every handler execution:
1. Update session.json with current state:
- `discussion_round`: current round count
- `last_event`: event type and timestamp
- `active_tasks`: list of in-progress task IDs
2. Verify task list consistency (no orphan tasks, no broken dependencies)
3. **STOP** and wait for next event
## Error Handling
| Scenario | Resolution |
|----------|------------|
| Worker 返回但未 completed (交互模式) | AskUserQuestion: 重试 / 跳过 / 终止 |
| Worker 返回但未 completed (自动模式) | 自动跳过,记录日志 |
| Worker spawn 失败 | 重试一次,仍失败则上报用户 |
| Discussion loop stuck >5 rounds | Force synthesis, offer continuation |
| Synthesis fails | Report partial results from analyses |
| Worker callback but task not completed | Log warning, reset task to pending, include in next handleSpawnNext |
| Worker spawn fails | Retry once. If still fails, report to user via AskUserQuestion: retry / skip / abort |
| Discussion loop exceeds max rounds | Force create SYNTH-001, proceed to synthesis |
| Synthesis fails | Report partial results from analyses and discussions |
| Pipeline stall (no ready + no running) | Check blockedBy chains, report blockage to user |
| Missing task artifacts | Log warning, continue with available data |

View File

@@ -1,222 +0,0 @@
# Command: deepen
> 深入探索与补充分析。根据讨论类型执行针对性的代码探索或 CLI 分析。
## When to Use
- Phase 3 of Discussant
- 用户反馈已收集,需要深入处理
- 每个 DISCUSS-* 任务触发一次
**Trigger conditions**:
- initial: 首轮讨论,汇总分析结果
- deepen: 继续深入当前方向
- direction-adjusted: 方向调整后重新分析
- specific-questions: 回答用户具体问题
## Strategy
### Delegation Mode
**Mode**: Mixed简单汇总内联深入探索用 subagent/CLI
### Decision Logic
```javascript
function selectDeepenStrategy(discussType, complexity) {
const strategies = {
'initial': {
mode: 'inline',
description: 'Summarize all analysis results into discussion format'
},
'deepen': {
mode: complexity === 'High' ? 'cli' : 'subagent',
description: 'Further exploration in current direction'
},
'direction-adjusted': {
mode: 'cli',
description: 'Re-analyze from new perspective'
},
'specific-questions': {
mode: 'subagent',
description: 'Targeted exploration to answer questions'
}
}
return strategies[discussType] || strategies['initial']
}
```
## Execution Steps
### Step 1: Strategy Selection
```javascript
const strategy = selectDeepenStrategy(discussType, assessComplexity(userFeedback))
```
### Step 2: Execute by Type
#### Initial Discussion
```javascript
function processInitialDiscussion() {
// 汇总所有分析结果
const summary = {
perspectives_analyzed: allAnalyses.map(a => a.perspective),
total_insights: currentInsights.length,
total_findings: currentFindings.length,
convergent_themes: identifyConvergentThemes(allAnalyses),
conflicting_views: identifyConflicts(allAnalyses),
top_discussion_points: discussionPoints.slice(0, 5),
open_questions: openQuestions.slice(0, 5)
}
roundContent.updated_understanding.new_insights = summary.convergent_themes
roundContent.new_findings = currentFindings.slice(0, 10)
roundContent.new_questions = openQuestions.slice(0, 5)
}
function identifyConvergentThemes(analyses) {
// 跨视角找共同主题
const allInsights = analyses.flatMap(a =>
(a.key_insights || []).map(i => typeof i === 'string' ? i : i.insight)
)
// 简单去重 + 聚合
return [...new Set(allInsights)].slice(0, 5)
}
function identifyConflicts(analyses) {
// 识别视角间的矛盾
return [] // 由实际分析结果决定
}
```
#### Deepen Discussion
```javascript
function processDeepenDiscussion() {
// 在当前方向上进一步探索
Task({
subagent_type: "cli-explore-agent",
run_in_background: false,
description: `Deepen exploration: ${topic} (round ${round})`,
prompt: `
## Context
Topic: ${topic}
Round: ${round}
Previous findings: ${currentFindings.slice(0, 5).join('; ')}
Open questions: ${openQuestions.slice(0, 3).join('; ')}
## MANDATORY FIRST STEPS
1. Focus on open questions from previous analysis
2. Search for specific patterns mentioned in findings
3. Look for edge cases and exceptions
## Exploration Focus
- Deepen understanding of confirmed patterns
- Investigate open questions
- Find additional evidence for uncertain insights
## Output
Write to: ${sessionFolder}/discussions/deepen-${discussNum}.json
Schema: {new_findings, answered_questions, remaining_questions, evidence}
`
})
// 读取深入探索结果
let deepenResult = {}
try {
deepenResult = JSON.parse(Read(`${sessionFolder}/discussions/deepen-${discussNum}.json`))
} catch {}
roundContent.updated_understanding.new_insights = deepenResult.new_findings || []
roundContent.new_findings = deepenResult.new_findings || []
roundContent.new_questions = deepenResult.remaining_questions || []
}
```
#### Direction Adjusted
```javascript
function processDirectionAdjusted() {
// 方向调整后,通过 CLI 重新分析
Bash({
command: `ccw cli -p "PURPOSE: Re-analyze '${topic}' with adjusted focus on '${userFeedback}'
Success: New insights from adjusted direction
PREVIOUS ANALYSIS CONTEXT:
- Previous insights: ${currentInsights.slice(0, 5).map(i => typeof i === 'string' ? i : i.insight).join('; ')}
- Direction change reason: User requested focus on '${userFeedback}'
TASK:
• Re-evaluate findings from new perspective
• Identify what changes with adjusted focus
• Find new patterns relevant to adjusted direction
• Note what previous findings remain valid
MODE: analysis
CONTEXT: @**/* | Topic: ${topic}
EXPECTED: Updated analysis with: validated findings, new insights, invalidated assumptions
CONSTRAINTS: Focus on ${userFeedback}
" --tool gemini --mode analysis`,
run_in_background: true
})
// ⚠️ STOP: Wait for CLI callback
roundContent.updated_understanding.corrected = ['Direction adjusted per user request']
roundContent.updated_understanding.new_insights = [] // From CLI result
}
```
#### Specific Questions
```javascript
function processSpecificQuestions() {
// 针对用户问题进行探索
Task({
subagent_type: "cli-explore-agent",
run_in_background: false,
description: `Answer questions: ${topic}`,
prompt: `
## Context
Topic: ${topic}
User questions: ${userFeedback}
Known findings: ${currentFindings.slice(0, 5).join('; ')}
## MANDATORY FIRST STEPS
1. Search for code related to user's questions
2. Trace execution paths relevant to questions
3. Check configuration and environment factors
## Output
Write to: ${sessionFolder}/discussions/questions-${discussNum}.json
Schema: {answers: [{question, answer, evidence, confidence}], follow_up_questions}
`
})
let questionResult = {}
try {
questionResult = JSON.parse(Read(`${sessionFolder}/discussions/questions-${discussNum}.json`))
} catch {}
roundContent.updated_understanding.new_insights =
(questionResult.answers || []).map(a => `Q: ${a.question} → A: ${a.answer}`)
roundContent.new_questions = questionResult.follow_up_questions || []
}
```
### Step 3: Result Processing
```javascript
// 结果已写入 roundContent由 role.md Phase 4 处理
```
## Error Handling
| Scenario | Resolution |
|----------|------------|
| cli-explore-agent fails | Use existing analysis results, note limitation |
| CLI timeout | Report partial results |
| No previous analyses | Process as initial with empty context |
| User feedback unparseable | Treat as 'deepen' type |

View File

@@ -1,225 +0,0 @@
# Discussant Role
讨论处理者。根据 coordinator 传递的用户反馈,执行方向调整、深入探索或补充分析,更新讨论时间线。
## Identity
- **Name**: `discussant` | **Tag**: `[discussant]`
- **Task Prefix**: `DISCUSS-*`
- **Responsibility**: Analysis + Exploration (讨论处理)
## Boundaries
### MUST
- Only process `DISCUSS-*` prefixed tasks
- All output (SendMessage, team_msg, logs) must carry `[discussant]` identifier
- Only communicate with coordinator via SendMessage
- Work strictly within discussion processing responsibility scope
- Execute deep exploration based on user feedback and existing analysis
- Share discussion results via team_msg(type='state_update')
- Update discussion.md discussion timeline
### MUST NOT
- Interact directly with user (AskUserQuestion is coordinator-driven)
- Generate final conclusions (belongs to synthesizer)
- Create tasks for other roles (TaskCreate is coordinator-exclusive)
- Communicate directly with other worker roles
- Modify source code
- Omit `[discussant]` identifier in any output
---
## Toolbox
### Available Commands
| Command | File | Phase | Description |
|---------|------|-------|-------------|
| `deepen` | [commands/deepen.md](commands/deepen.md) | Phase 3 | 深入探索与补充分析 |
### Tool Capabilities
| Tool | Type | Used By | Purpose |
|------|------|---------|---------|
| `Task` | Subagent | deepen.md | Spawn cli-explore-agent for targeted exploration |
| `Bash` | CLI | deepen.md | Execute ccw cli for deep analysis |
| `Read` | File | discussant | Read analysis results and session context |
| `Write` | File | discussant | Write discussion results |
| `Glob` | File | discussant | Find analysis/exploration files |
### CLI Tools
| CLI Tool | Mode | Used By | Purpose |
|----------|------|---------|---------|
| `gemini` | analysis | deepen.md | 深入分析 |
---
## Message Types
| Type | Direction | Trigger | Description |
|------|-----------|---------|-------------|
| `discussion_processed` | discussant → coordinator | 讨论处理完成 | 包含更新的理解和新发现 |
| `error` | discussant → coordinator | 处理失败 | 阻塞性错误 |
## Message Bus
Before every SendMessage, log via `mcp__ccw-tools__team_msg`:
```
mcp__ccw-tools__team_msg({
operation: "log",
session_id: <session-id>,
from: "discussant",
type: "discussion_processed",
ref: "<output-path>"
})
```
> `to` and `summary` are auto-defaulted by the tool.
**CLI fallback** (when MCP unavailable):
```
Bash("ccw team log --session-id <session-id> --from discussant --type discussion_processed --ref <path> --json")
```
---
## Execution (5-Phase)
### Phase 1: Task Discovery
> See SKILL.md Shared Infrastructure -> Worker Phase 1: Task Discovery
Standard task discovery flow: TaskList -> filter by prefix `DISCUSS-*` + owner match + pending + unblocked -> TaskGet -> TaskUpdate in_progress.
Falls back to `discussant` for single-instance role.
### Phase 2: Context Loading
**Loading steps**:
1. Extract session path from task description
2. Extract topic, round number, discussion type, user feedback
3. Read role states via team_msg(operation="get_state") for existing context
4. Read all analysis results
5. Read all exploration results
6. Aggregate current findings, insights, questions
**Context extraction**:
| Field | Source | Pattern |
|-------|--------|---------|
| sessionFolder | task description | `session:\s*(.+)` |
| topic | task description | `topic:\s*(.+)` |
| round | task description | `round:\s*(\d+)` or default 1 |
| discussType | task description | `type:\s*(.+)` or default "initial" |
| userFeedback | task description | `user_feedback:\s*(.+)` or empty |
**Discussion types**:
| Type | Description |
|------|-------------|
| initial | 首轮讨论:汇总所有分析结果,生成讨论摘要 |
| deepen | 继续深入:在当前方向上进一步探索 |
| direction-adjusted | 方向调整:基于新方向重新组织发现 |
| specific-questions | 具体问题:针对用户问题进行分析 |
### Phase 3: Discussion Processing
Delegate to `commands/deepen.md` if available, otherwise execute inline.
**Processing by discussion type**:
| Type | Strategy |
|------|----------|
| initial | Aggregate all analysis results, generate discussion summary with confirmed/corrected/new insights |
| deepen | Focus on current direction, explore deeper with cli-explore-agent |
| direction-adjusted | Re-organize findings around new focus, identify new patterns |
| specific-questions | Targeted analysis addressing user's specific questions |
**Round content structure**:
| Field | Description |
|-------|-------------|
| round | Discussion round number |
| type | Discussion type |
| user_feedback | User input (if any) |
| updated_understanding | confirmed, corrected, new_insights arrays |
| new_findings | New discoveries |
| new_questions | Open questions |
| timestamp | ISO timestamp |
### Phase 4: Update Discussion Timeline
**Output path**: `<session-folder>/discussions/discussion-round-<num>.json`
**discussion.md update template**:
```markdown
### Round <N> - Discussion (<timestamp>)
#### Type
<discussType>
#### User Input
<userFeedback or "(Initial discussion round)">
#### Updated Understanding
**Confirmed**: <list of confirmed assumptions>
**Corrected**: <list of corrected assumptions>
**New Insights**: <list of new insights>
#### New Findings
<list of new findings or "(None)">
#### Open Questions
<list of open questions or "(None)">
```
**Update steps**:
1. Write round content JSON to discussions folder
2. Read current discussion.md
3. Append new round section
4. Write updated discussion.md
### Phase 5: Report to Coordinator
> See SKILL.md Shared Infrastructure -> Worker Phase 5: Report
Standard report flow: team_msg log -> SendMessage with `[discussant]` prefix -> TaskUpdate completed -> Loop to Phase 1 for next task.
**Shared memory update**:
```
sharedMemory.discussions.push({
id: "discussion-round-<num>",
round: <round>,
type: <discussType>,
new_insight_count: <count>,
corrected_count: <count>,
timestamp: <timestamp>
})
// Update current_understanding
sharedMemory.current_understanding.established += confirmed
sharedMemory.current_understanding.clarified += corrected
sharedMemory.current_understanding.key_insights += new_insights
```
---
## Error Handling
| Scenario | Resolution |
|----------|------------|
| No DISCUSS-* tasks available | Idle, wait for coordinator assignment |
| No analysis results found | Report empty discussion, notify coordinator |
| CLI tool unavailable | Use existing analysis results for discussion |
| User feedback unclear | Process as 'deepen' type, note ambiguity |
| Session folder missing | Error to coordinator |
| Command file not found | Fall back to inline execution |

View File

@@ -1,194 +0,0 @@
# Command: explore
> cli-explore-agent 并行代码库探索。根据话题和视角,通过 subagent 收集代码库上下文。
## When to Use
- Phase 3 of Explorer
- 需要收集代码库上下文供后续分析
- 每个 EXPLORE-* 任务触发一次
**Trigger conditions**:
- Explorer Phase 2 完成后
- 任务包含明确的 perspective 和 dimensions
## Strategy
### Delegation Mode
**Mode**: Subagentcli-explore-agent 执行实际探索)
### Decision Logic
```javascript
// 根据 perspective 确定探索策略
function buildExplorationStrategy(perspective, dimensions, topic) {
const strategies = {
'general': {
focus: 'Overall codebase structure and patterns',
searches: [topic, ...dimensions],
depth: 'broad'
},
'technical': {
focus: 'Implementation details, code patterns, technical feasibility',
searches: [`${topic} implementation`, `${topic} pattern`, `${topic} handler`],
depth: 'medium'
},
'architectural': {
focus: 'System design, module boundaries, component interactions',
searches: [`${topic} module`, `${topic} service`, `${topic} interface`],
depth: 'broad'
},
'business': {
focus: 'Business logic, domain models, value flows',
searches: [`${topic} model`, `${topic} domain`, `${topic} workflow`],
depth: 'medium'
},
'domain_expert': {
focus: 'Domain-specific patterns, standards compliance, best practices',
searches: [`${topic} standard`, `${topic} convention`, `${topic} best practice`],
depth: 'deep'
}
}
return strategies[perspective] || strategies['general']
}
```
## Execution Steps
### Step 1: Context Preparation
```javascript
const strategy = buildExplorationStrategy(perspective, dimensions, topic)
const exploreNum = task.subject.match(/EXPLORE-(\d+)/)?.[1] || '001'
const outputPath = `${sessionFolder}/explorations/exploration-${exploreNum}.json`
```
### Step 2: Execute Exploration
```javascript
Task({
subagent_type: "cli-explore-agent",
run_in_background: false,
description: `Explore codebase: ${topic} (${perspective})`,
prompt: `
## Analysis Context
Topic: ${topic}
Perspective: ${perspective}${strategy.focus}
Dimensions: ${dimensions.join(', ')}
Session: ${sessionFolder}
## MANDATORY FIRST STEPS
1. Run: ccw tool exec get_modules_by_depth '{}'
2. Execute searches: ${strategy.searches.map(s => `"${s}"`).join(', ')}
3. Run: ccw spec load --category exploration
## Exploration Focus (${perspective} angle)
- **Depth**: ${strategy.depth}
- **Focus**: ${strategy.focus}
${dimensions.map(d => `- ${d}: Identify relevant code patterns, structures, and relationships`).join('\n')}
## Search Strategy
${strategy.searches.map((s, i) => `${i + 1}. Search for: "${s}" — find related files, functions, types`).join('\n')}
## Additional Exploration
- Identify entry points related to the topic
- Map dependencies between relevant modules
- Note any configuration or environment dependencies
- Look for test files that reveal expected behavior
## Output
Write findings to: ${outputPath}
Schema:
{
"perspective": "${perspective}",
"relevant_files": [
{"path": "string", "relevance": "high|medium|low", "summary": "what this file does"}
],
"patterns": ["pattern descriptions found in codebase"],
"key_findings": ["important discoveries"],
"module_map": {"module_name": ["related_files"]},
"questions_for_analysis": ["questions that need deeper analysis"],
"_metadata": {
"agent": "cli-explore-agent",
"perspective": "${perspective}",
"search_queries": ${JSON.stringify(strategy.searches)},
"timestamp": "ISO string"
}
}
`
})
```
### Step 3: Result Processing
```javascript
// 验证输出文件
let result = {}
try {
result = JSON.parse(Read(outputPath))
} catch {
// Fallback: ACE search
const aceResults = mcp__ace-tool__search_context({
project_root_path: ".",
query: `${topic} ${perspective}`
})
result = {
perspective,
relevant_files: [],
patterns: [],
key_findings: [`ACE fallback: ${aceResults?.summary || 'No results'}`],
questions_for_analysis: [`What is the ${perspective} perspective on ${topic}?`],
_metadata: {
agent: 'ace-fallback',
perspective,
timestamp: new Date().toISOString()
}
}
Write(outputPath, JSON.stringify(result, null, 2))
}
// 质量验证
const quality = {
has_files: (result.relevant_files?.length || 0) > 0,
has_findings: (result.key_findings?.length || 0) > 0,
has_patterns: (result.patterns?.length || 0) > 0
}
if (!quality.has_files && !quality.has_findings) {
// 补充搜索
const supplementary = mcp__ace-tool__search_context({
project_root_path: ".",
query: topic
})
// Merge supplementary results
}
```
## Output Format
```json
{
"perspective": "technical",
"relevant_files": [
{"path": "src/auth/handler.ts", "relevance": "high", "summary": "Authentication request handler"}
],
"patterns": ["Repository pattern used for data access", "Middleware chain for auth"],
"key_findings": ["JWT tokens stored in HTTP-only cookies", "Rate limiting at gateway level"],
"module_map": {"auth": ["src/auth/handler.ts", "src/auth/middleware.ts"]},
"questions_for_analysis": ["Is the token refresh mechanism secure?"],
"_metadata": {"agent": "cli-explore-agent", "perspective": "technical", "timestamp": "..."}
}
```
## Error Handling
| Scenario | Resolution |
|----------|------------|
| cli-explore-agent unavailable | Fall back to ACE search + Grep |
| Agent produces no output file | Create minimal result with ACE fallback |
| Agent timeout | Use partial results if available |
| Invalid JSON output | Attempt repair, fall back to raw text extraction |
| Session folder missing | Create directory, continue |

View File

@@ -1,217 +0,0 @@
# Explorer Role
代码库探索者。通过 cli-explore-agent 多角度并行探索代码库,收集结构化上下文供后续分析使用。
## Identity
- **Name**: `explorer` | **Tag**: `[explorer]`
- **Task Prefix**: `EXPLORE-*`
- **Responsibility**: Orchestration (代码库探索编排)
## Boundaries
### MUST
- Only process `EXPLORE-*` prefixed tasks
- All output (SendMessage, team_msg, logs) must carry `[explorer]` identifier
- Only communicate with coordinator via SendMessage
- Work strictly within codebase exploration responsibility scope
- Share exploration results via team_msg(type='state_update')
### MUST NOT
- Execute deep analysis (belongs to analyst)
- Handle user feedback (belongs to discussant)
- Generate conclusions or recommendations (belongs to synthesizer)
- Create tasks for other roles (TaskCreate is coordinator-exclusive)
- Communicate directly with other worker roles
- Omit `[explorer]` identifier in any output
---
## Toolbox
### Available Commands
| Command | File | Phase | Description |
|---------|------|-------|-------------|
| `explore` | [commands/explore.md](commands/explore.md) | Phase 3 | cli-explore-agent 并行探索 |
### Tool Capabilities
| Tool | Type | Used By | Purpose |
|------|------|---------|---------|
| `Task` | Subagent | explore.md | Spawn cli-explore-agent for codebase exploration |
| `Read` | File | explorer | Read session files and exploration context |
| `Write` | File | explorer | Write exploration results |
| `Glob` | File | explorer | Find relevant files |
| `mcp__ace-tool__search_context` | MCP | explorer | ACE semantic search fallback |
| `Grep` | Search | explorer | Pattern search fallback |
---
## Message Types
| Type | Direction | Trigger | Description |
|------|-----------|---------|-------------|
| `exploration_ready` | explorer → coordinator | 探索完成 | 包含发现的文件、模式、关键发现 |
| `error` | explorer → coordinator | 探索失败 | 阻塞性错误 |
## Message Bus
Before every SendMessage, log via `mcp__ccw-tools__team_msg`:
```
mcp__ccw-tools__team_msg({
operation: "log",
session_id: <session-id>,
from: "explorer",
type: "exploration_ready",
ref: "<output-path>"
})
```
> `to` and `summary` are auto-defaulted by the tool.
**CLI fallback** (when MCP unavailable):
```
Bash("ccw team log --session-id <session-id> --from explorer --type exploration_ready --ref <path> --json")
```
---
## Execution (5-Phase)
### Phase 1: Task Discovery
> See SKILL.md Shared Infrastructure -> Worker Phase 1: Task Discovery
Standard task discovery flow: TaskList -> filter by prefix `EXPLORE-*` + owner match + pending + unblocked -> TaskGet -> TaskUpdate in_progress.
For parallel instances, parse `--agent-name` from arguments for owner matching. Falls back to `explorer` for single-instance roles.
### Phase 2: Context & Scope Assessment
**Loading steps**:
1. Extract session path from task description
2. Extract topic, perspective, dimensions from task metadata
3. Read role states via team_msg(operation="get_state") for existing context
4. Determine exploration number from task subject (EXPLORE-N)
**Context extraction**:
| Field | Source | Pattern |
|-------|--------|---------|
| sessionFolder | task description | `session:\s*(.+)` |
| topic | task description | `topic:\s*(.+)` |
| perspective | task description | `perspective:\s*(.+)` or default "general" |
| dimensions | task description | `dimensions:\s*(.+)` or default "general" |
### Phase 3: Codebase Exploration
Delegate to `commands/explore.md` if available, otherwise execute inline.
**Exploration strategy**:
| Condition | Strategy |
|-----------|----------|
| Single perspective | Direct cli-explore-agent spawn |
| Multi-perspective | Per-perspective exploration with focused prompts |
| Limited context | ACE search + Grep fallback |
**cli-explore-agent spawn**:
```
Task({
subagent_type: "cli-explore-agent",
run_in_background: false,
description: "Explore codebase: <topic> (<perspective>)",
prompt: `
## Analysis Context
Topic: <topic>
Perspective: <perspective>
Dimensions: <dimensions>
Session: <session-folder>
## MANDATORY FIRST STEPS
1. Run: ccw tool exec get_modules_by_depth '{}'
2. Execute relevant searches based on topic keywords
3. Run: ccw spec load --category exploration
## Exploration Focus (<perspective> angle)
<dimensions map to exploration focus areas>
## Output
Write findings to: <session-folder>/explorations/exploration-<num>.json
Schema: {
perspective: "<perspective>",
relevant_files: [{path, relevance, summary}],
patterns: [string],
key_findings: [string],
questions_for_analysis: [string],
_metadata: {agent: "cli-explore-agent", timestamp}
}
`
})
```
### Phase 4: Result Validation
**Validation steps**:
| Check | Method | Action on Failure |
|-------|--------|-------------------|
| Output file exists | Read output path | Create empty result structure |
| Has relevant files | Check array length | Trigger ACE fallback |
| Has findings | Check key_findings | Note partial results |
**ACE fallback** (when exploration produces no output):
```
mcp__ace-tool__search_context({
project_root_path: ".",
query: <topic>
})
```
**Quality validation**:
| Metric | Threshold | Action |
|--------|-----------|--------|
| relevant_files count | > 0 | Proceed |
| key_findings count | > 0 | Proceed |
| Both empty | - | Use ACE fallback, mark partial |
### Phase 5: Report to Coordinator
> See SKILL.md Shared Infrastructure -> Worker Phase 5: Report
Standard report flow: team_msg log -> SendMessage with `[explorer]` prefix -> TaskUpdate completed -> Loop to Phase 1 for next task.
**Shared memory update**:
```
sharedMemory.explorations.push({
id: "exploration-<num>",
perspective: <perspective>,
file_count: <count>,
finding_count: <count>,
timestamp: <timestamp>
})
```
---
## Error Handling
| Scenario | Resolution |
|----------|------------|
| No EXPLORE-* tasks available | Idle, wait for coordinator assignment |
| cli-explore-agent fails | Fall back to ACE search + Grep inline |
| Exploration scope too broad | Narrow to topic keywords, report partial |
| Agent timeout | Use partial results, note incomplete |
| Session folder missing | Create it, warn coordinator |
| Context/Plan file not found | Notify coordinator, request location |

View File

@@ -1,255 +0,0 @@
# Command: synthesize
> 跨视角整合。从所有探索、分析、讨论结果中提取主题、解决冲突、生成最终结论和建议。
## When to Use
- Phase 3 of Synthesizer
- 所有探索、分析、讨论已完成
- 每个 SYNTH-* 任务触发一次
**Trigger conditions**:
- 讨论循环结束后(用户选择"分析完成"或达到最大轮次)
- Quick 模式下分析完成后直接触发
## Strategy
### Delegation Mode
**Mode**: Inline纯整合不调用外部工具
### Decision Logic
```javascript
function buildSynthesisStrategy(explorationCount, analysisCount, discussionCount) {
if (analysisCount <= 1 && discussionCount === 0) {
return 'simple' // Quick mode: 单视角直接总结
}
if (discussionCount > 2) {
return 'deep' // Deep mode: 多轮讨论需要追踪演进
}
return 'standard' // Standard: 多视角交叉整合
}
```
## Execution Steps
### Step 1: Context Preparation
```javascript
const strategy = buildSynthesisStrategy(
allExplorations.length, allAnalyses.length, allDiscussions.length
)
// 提取所有洞察
const allInsights = allAnalyses.flatMap(a =>
(a.key_insights || []).map(i => ({
...(typeof i === 'string' ? { insight: i } : i),
perspective: a.perspective
}))
)
// 提取所有发现
const allFindings = allAnalyses.flatMap(a =>
(a.key_findings || []).map(f => ({
...(typeof f === 'string' ? { finding: f } : f),
perspective: a.perspective
}))
)
// 提取所有建议
const allRecommendations = allAnalyses.flatMap(a =>
(a.recommendations || []).map(r => ({
...(typeof r === 'string' ? { action: r } : r),
perspective: a.perspective
}))
)
// 提取讨论演进
const discussionEvolution = allDiscussions.map(d => ({
round: d.round,
type: d.type,
confirmed: d.updated_understanding?.confirmed || [],
corrected: d.updated_understanding?.corrected || [],
new_insights: d.updated_understanding?.new_insights || []
}))
```
### Step 2: Cross-Perspective Synthesis
```javascript
// 1. Theme Extraction — 跨视角共同主题
const themes = extractThemes(allInsights)
// 2. Conflict Resolution — 视角间矛盾
const conflicts = identifyConflicts(allAnalyses)
// 3. Evidence Consolidation — 证据汇总
const consolidatedEvidence = consolidateEvidence(allFindings)
// 4. Recommendation Prioritization — 建议优先级排序
const prioritizedRecommendations = prioritizeRecommendations(allRecommendations)
// 5. Decision Trail Integration — 决策追踪整合
const decisionSummary = summarizeDecisions(decisionTrail)
function extractThemes(insights) {
// 按关键词聚类,识别跨视角共同主题
const themeMap = {}
for (const insight of insights) {
const text = insight.insight || insight
// 简单聚类:相似洞察归为同一主题
const key = text.slice(0, 30)
if (!themeMap[key]) {
themeMap[key] = { theme: text, perspectives: [], count: 0 }
}
themeMap[key].perspectives.push(insight.perspective)
themeMap[key].count++
}
return Object.values(themeMap)
.sort((a, b) => b.count - a.count)
.slice(0, 10)
}
function identifyConflicts(analyses) {
// 识别不同视角间的矛盾发现
const conflicts = []
for (let i = 0; i < analyses.length; i++) {
for (let j = i + 1; j < analyses.length; j++) {
// 比较两个视角的发现是否矛盾
// 实际实现中需要语义比较
}
}
return conflicts
}
function consolidateEvidence(findings) {
// 去重并按文件引用聚合
const byFile = {}
for (const f of findings) {
const ref = f.file_ref || f.finding
if (!byFile[ref]) byFile[ref] = []
byFile[ref].push(f)
}
return byFile
}
function prioritizeRecommendations(recommendations) {
const priorityOrder = { high: 0, medium: 1, low: 2 }
return recommendations
.sort((a, b) => (priorityOrder[a.priority] || 2) - (priorityOrder[b.priority] || 2))
.slice(0, 10)
}
function summarizeDecisions(trail) {
return trail.map(d => ({
round: d.round,
decision: d.decision,
context: d.context,
impact: d.impact || 'Shaped analysis direction'
}))
}
```
### Step 3: Build Conclusions
```javascript
const conclusions = {
session_id: sessionFolder.split('/').pop(),
topic,
completed: new Date().toISOString(),
total_rounds: allDiscussions.length,
strategy_used: strategy,
summary: generateSummary(themes, allFindings, allDiscussions),
key_conclusions: themes.slice(0, 7).map(t => ({
point: t.theme,
evidence: t.perspectives.join(', ') + ' perspectives',
confidence: t.count >= 3 ? 'high' : t.count >= 2 ? 'medium' : 'low'
})),
recommendations: prioritizedRecommendations.map(r => ({
action: r.action,
rationale: r.rationale || 'Based on analysis findings',
priority: r.priority || 'medium',
source_perspective: r.perspective
})),
open_questions: allAnalyses
.flatMap(a => a.open_questions || [])
.filter((q, i, arr) => arr.indexOf(q) === i)
.slice(0, 5),
follow_up_suggestions: generateFollowUps(conclusions),
decision_trail: decisionSummary,
cross_perspective_synthesis: {
convergent_themes: themes.filter(t => t.perspectives.length > 1),
conflicts_resolved: conflicts,
unique_contributions: allAnalyses.map(a => ({
perspective: a.perspective,
unique_insights: (a.key_insights || []).slice(0, 2)
}))
},
_metadata: {
explorations: allExplorations.length,
analyses: allAnalyses.length,
discussions: allDiscussions.length,
decisions: decisionTrail.length,
synthesis_strategy: strategy
}
}
function generateSummary(themes, findings, discussions) {
const topThemes = themes.slice(0, 3).map(t => t.theme).join('; ')
const roundCount = discussions.length
return `Analysis of "${topic}" identified ${themes.length} key themes across ${allAnalyses.length} perspective(s) and ${roundCount} discussion round(s). Top themes: ${topThemes}`
}
function generateFollowUps(conclusions) {
const suggestions = []
if ((conclusions.open_questions || []).length > 2) {
suggestions.push({ type: 'deeper-analysis', summary: 'Further analysis needed for open questions' })
}
if ((conclusions.recommendations || []).some(r => r.priority === 'high')) {
suggestions.push({ type: 'issue-creation', summary: 'Create issues for high-priority recommendations' })
}
suggestions.push({ type: 'implementation-plan', summary: 'Generate implementation plan from recommendations' })
return suggestions
}
```
## Output Format
```json
{
"session_id": "UAN-auth-analysis-2026-02-18",
"topic": "认证架构优化",
"completed": "2026-02-18T...",
"total_rounds": 2,
"summary": "Analysis identified 5 key themes...",
"key_conclusions": [
{"point": "JWT stateless approach is sound", "evidence": "technical, architectural", "confidence": "high"}
],
"recommendations": [
{"action": "Add rate limiting", "rationale": "Prevent brute force", "priority": "high"}
],
"open_questions": ["Token rotation strategy?"],
"decision_trail": [
{"round": 1, "decision": "Focus on security", "context": "User preference"}
]
}
```
## Error Handling
| Scenario | Resolution |
|----------|------------|
| No analyses available | Synthesize from explorations only |
| Single perspective only | Generate focused synthesis without cross-perspective |
| Irreconcilable conflicts | Present both sides with trade-off analysis |
| Empty discussion rounds | Skip discussion evolution, focus on analysis results |
| Shared memory corrupted | Rebuild from individual JSON files |

View File

@@ -1,249 +0,0 @@
# Synthesizer Role
综合整合者。跨视角整合所有探索、分析、讨论结果,生成最终结论、建议和决策追踪。
## Identity
- **Name**: `synthesizer` | **Tag**: `[synthesizer]`
- **Task Prefix**: `SYNTH-*`
- **Responsibility**: Read-only analysis (综合结论)
## Boundaries
### MUST
- Only process `SYNTH-*` prefixed tasks
- All output (SendMessage, team_msg, logs) must carry `[synthesizer]` identifier
- Only communicate with coordinator via SendMessage
- Work strictly within synthesis responsibility scope
- Integrate all role outputs to generate final conclusions
- Share synthesis results via team_msg(type='state_update')
- Update discussion.md conclusions section
### MUST NOT
- Execute new code exploration or CLI analysis
- Interact directly with user
- Create tasks for other roles (TaskCreate is coordinator-exclusive)
- Communicate directly with other worker roles
- Modify source code
- Omit `[synthesizer]` identifier in any output
---
## Toolbox
### Available Commands
| Command | File | Phase | Description |
|---------|------|-------|-------------|
| `synthesize` | [commands/synthesize.md](commands/synthesize.md) | Phase 3 | 跨视角整合 |
### Tool Capabilities
| Tool | Type | Used By | Purpose |
|------|------|---------|---------|
| `Read` | File | synthesizer | Read all session artifacts |
| `Write` | File | synthesizer | Write conclusions and updates |
| `Glob` | File | synthesizer | Find all exploration/analysis/discussion files |
> Synthesizer does not use subagents or CLI tools (pure integration role).
---
## Message Types
| Type | Direction | Trigger | Description |
|------|-----------|---------|-------------|
| `synthesis_ready` | synthesizer → coordinator | 综合完成 | 包含最终结论和建议 |
| `error` | synthesizer → coordinator | 综合失败 | 阻塞性错误 |
## Message Bus
Before every SendMessage, log via `mcp__ccw-tools__team_msg`:
```
mcp__ccw-tools__team_msg({
operation: "log",
session_id: <session-id>,
from: "synthesizer",
type: "synthesis_ready",
ref: "<output-path>"
})
```
> `to` and `summary` are auto-defaulted by the tool.
**CLI fallback** (when MCP unavailable):
```
Bash("ccw team log --session-id <session-id> --from synthesizer --type synthesis_ready --ref <path> --json")
```
---
## Execution (5-Phase)
### Phase 1: Task Discovery
> See SKILL.md Shared Infrastructure -> Worker Phase 1: Task Discovery
Standard task discovery flow: TaskList -> filter by prefix `SYNTH-*` + owner match + pending + unblocked -> TaskGet -> TaskUpdate in_progress.
Falls back to `synthesizer` for single-instance role.
### Phase 2: Context Loading + Shared Memory Read
**Loading steps**:
1. Extract session path from task description
2. Extract topic
3. Read role states via team_msg(operation="get_state")
4. Read all exploration files
5. Read all analysis files
6. Read all discussion round files
7. Extract decision trail and current understanding
**Context extraction**:
| Field | Source | Pattern |
|-------|--------|---------|
| sessionFolder | task description | `session:\s*(.+)` |
| topic | task description | `topic:\s*(.+)` |
**File loading**:
| Artifact | Path Pattern |
|----------|--------------|
| Explorations | `<session>/explorations/*.json` |
| Analyses | `<session>/analyses/*.json` |
| Discussions | `<session>/discussions/discussion-round-*.json` |
| Decision trail | `sharedMemory.decision_trail` |
| Current understanding | `sharedMemory.current_understanding` |
### Phase 3: Synthesis Execution
Delegate to `commands/synthesize.md` if available, otherwise execute inline.
**Synthesis dimensions**:
| Dimension | Source | Purpose |
|-----------|--------|---------|
| Explorations | All exploration files | Cross-perspective file relevance |
| Analyses | All analysis files | Key insights and discussion points |
| Discussions | All discussion rounds | Understanding evolution |
| Decision trail | sharedMemory | Critical decision history |
**Conclusions structure**:
| Field | Description |
|-------|-------------|
| summary | Executive summary |
| key_conclusions | Array of {point, confidence, evidence} |
| recommendations | Array of {priority, action, rationale} |
| open_questions | Remaining unresolved questions |
| _metadata | Synthesis metadata |
**Confidence levels**:
| Level | Criteria |
|-------|----------|
| High | Multiple sources confirm, strong evidence |
| Medium | Single source or partial evidence |
| Low | Speculative, needs verification |
### Phase 4: Write Conclusions + Update discussion.md
**Output paths**:
| File | Path |
|------|------|
| Conclusions | `<session-folder>/conclusions.json` |
| Discussion update | `<session-folder>/discussion.md` |
**discussion.md conclusions section**:
```markdown
## Conclusions
### Summary
<conclusions.summary>
### Key Conclusions
1. **<point>** (Confidence: <confidence>)
- Evidence: <evidence>
2. ...
### Recommendations
1. **[<priority>]** <action>
- Rationale: <rationale>
2. ...
### Remaining Questions
- <question 1>
- <question 2>
## Decision Trail
### Critical Decisions
- **Round N**: <decision> — <context>
## Current Understanding (Final)
### What We Established
- <established item 1>
- <established item 2>
### What Was Clarified/Corrected
- <clarified item 1>
- <clarified item 2>
### Key Insights
- <insight 1>
- <insight 2>
## Session Statistics
- **Explorations**: <count>
- **Analyses**: <count>
- **Discussion Rounds**: <count>
- **Decisions Made**: <count>
- **Completed**: <timestamp>
```
**Update steps**:
1. Write conclusions.json
2. Read current discussion.md
3. Append conclusions section
4. Write updated discussion.md
### Phase 5: Report to Coordinator + Shared Memory Write
> See SKILL.md Shared Infrastructure -> Worker Phase 5: Report
Standard report flow: team_msg log -> SendMessage with `[synthesizer]` prefix -> TaskUpdate completed -> Loop to Phase 1 for next task.
**Shared memory update**:
```
sharedMemory.synthesis = {
conclusion_count: <count>,
recommendation_count: <count>,
open_question_count: <count>,
timestamp: <timestamp>
}
```
---
## Error Handling
| Scenario | Resolution |
|----------|------------|
| No SYNTH-* tasks | Idle, wait for assignment |
| No analyses/discussions found | Synthesize from explorations only |
| Conflicting analyses | Present both sides, recommend user decision |
| Empty shared memory | Generate minimal conclusions from discussion.md |
| Only one perspective | Create focused single-perspective synthesis |
| Command file not found | Fall back to inline execution |
| Session folder missing | Error to coordinator |