feat: Add coordinator commands and role specifications for UI design team

- Implemented the 'monitor' command for coordinator role to handle monitoring events, task completion, and pipeline management.
- Created role specifications for the coordinator, detailing responsibilities, command execution protocols, and session management.
- Added role specifications for the analyst, discussant, explorer, and synthesizer in the ultra-analyze skill, defining their context loading, analysis, and synthesis processes.
This commit is contained in:
catlog22
2026-03-03 23:35:41 +08:00
parent a7ed0365f7
commit 26bda9c634
188 changed files with 9332 additions and 3512 deletions

View File

@@ -135,10 +135,10 @@ Every worker executes the same task discovery flow on startup:
Standard reporting flow after task completion:
1. **Message Bus**: Call `mcp__ccw-tools__team_msg` to log message
- Parameters: operation="log", team=<session-id>, from=<role>, to="coordinator", type=<message-type>, summary="[<role>] <summary>", ref=<artifact-path>
- **NOTE**: `team` must be **session ID** (e.g., `TQA-project-2026-02-27`), NOT team name. Extract from `Session:` field in task description.
- **CLI fallback**: When MCP unavailable -> `ccw team log --team <session-id> --from <role> --to coordinator --type <type> --summary "[<role>] ..." --json`
2. **SendMessage**: Send result to coordinator (content and summary both prefixed with `[<role>]`)
- Parameters: operation="log", session_id=<session-id>, from=<role>, type=<message-type>, data={ref: "<artifact-path>"}
- `to` and `summary` auto-defaulted -- do NOT specify explicitly
- **CLI fallback**: `ccw team log --session-id <session-id> --from <role> --type <type> --json`
2. **SendMessage**: Send result to coordinator
3. **TaskUpdate**: Mark task completed
4. **Loop**: Return to Phase 1 to check next task
@@ -178,7 +178,7 @@ All outputs must carry `[role_name]` prefix.
| Allowed | Forbidden |
|---------|-----------|
| Process tasks with own prefix | Process tasks with other role prefixes |
| Read/write shared-memory.json (own fields) | Create tasks for other roles |
| Share state via team_msg(type='state_update') | Create tasks for other roles |
| SendMessage to coordinator | Communicate directly with other workers |
| Delegate to commands/ files | Modify resources outside own responsibility |
@@ -193,7 +193,7 @@ All outputs must carry `[role_name]` prefix.
### Shared Memory
Cross-role accumulated knowledge stored in `shared-memory.json`:
Cross-role accumulated knowledge stored via team_msg(type='state_update'):
| Field | Owner | Content |
|-------|-------|---------|
@@ -431,8 +431,9 @@ Skill(skill="team-quality-assurance", args="--role=<role> --agent-name=<role>-<N
```
.workflow/.team/QA-<slug>-<YYYY-MM-DD>/
├── team-session.json # Session state
├── shared-memory.json # Discovered issues / test strategy / defect patterns / coverage history
├── .msg/meta.json # Session state
├── .msg/messages.jsonl # Team message bus
├── .msg/meta.json # Session metadata
├── wisdom/ # Cross-task knowledge
│ ├── learnings.md
│ ├── decisions.md

View File

@@ -0,0 +1,80 @@
---
prefix: QAANA
inner_loop: false
subagents: []
message_types:
success: analysis_ready
report: quality_report
error: error
---
# Quality Analyst
Analyze defect patterns, coverage gaps, test effectiveness, and generate comprehensive quality reports. Maintain defect pattern database and provide quality scoring.
## Phase 2: Context Loading
| Input | Source | Required |
|-------|--------|----------|
| Task description | From task subject/description | Yes |
| Session path | Extracted from task description | Yes |
| .msg/meta.json | <session>/wisdom/.msg/meta.json | Yes |
| Discovered issues | meta.json -> discovered_issues | No |
| Test strategy | meta.json -> test_strategy | No |
| Generated tests | meta.json -> generated_tests | No |
| Execution results | meta.json -> execution_results | No |
| Historical patterns | meta.json -> defect_patterns | No |
1. Extract session path from task description
2. Read .msg/meta.json for all accumulated QA data
3. Read coverage data from `coverage/coverage-summary.json` if available
4. Read layer execution results from `<session>/results/run-*.json`
5. Select analysis mode:
| Data Points | Mode |
|-------------|------|
| <= 5 issues + results | Direct inline analysis |
| > 5 | CLI-assisted deep analysis via gemini |
## Phase 3: Multi-Dimensional Analysis
**Five analysis dimensions**:
1. **Defect Pattern Analysis**: Group issues by type/perspective, identify patterns with >= 2 occurrences, record type/count/files/description
2. **Coverage Gap Analysis**: Compare actual coverage vs layer targets, identify per-file gaps (< 50% coverage), severity: critical (< 20%) / high (< 50%)
3. **Test Effectiveness**: Per layer -- files generated, pass rate, iterations needed, coverage achieved. Effective = pass_rate >= 95% AND iterations <= 2
4. **Quality Trend**: Compare against coverage_history. Trend: improving (delta > 5%), declining (delta < -5%), stable
5. **Quality Score** (0-100 starting from 100):
| Factor | Impact |
|--------|--------|
| Security issues | -10 per issue |
| Bug issues | -5 per issue |
| Coverage gap | -0.5 per gap percentage |
| Test failures | -(100 - pass_rate) * 0.3 per layer |
| Effective test layers | +5 per layer |
| Improving trend | +3 |
For CLI-assisted mode:
```
PURPOSE: Deep quality analysis on QA results to identify defect patterns and improvement opportunities
TASK: Classify defects by root cause, identify high-density files, analyze coverage gaps vs risk, generate recommendations
MODE: analysis
```
## Phase 4: Report Generation & Output
1. Generate quality report markdown with: score, defect patterns, coverage analysis, test effectiveness, quality trend, recommendations
2. Write report to `<session>/analysis/quality-report.md`
3. Update `<session>/wisdom/.msg/meta.json`:
- `defect_patterns`: identified patterns array
- `quality_score`: calculated score
- `coverage_history`: append new data point (date, coverage, quality_score, issues)
**Score-based recommendations**:
| Score | Recommendation |
|-------|----------------|
| >= 80 | Quality is GOOD. Maintain current testing practices. |
| 60-79 | Quality needs IMPROVEMENT. Focus on coverage gaps and recurring patterns. |
| < 60 | Quality is CONCERNING. Recommend comprehensive review and testing effort. |

View File

@@ -0,0 +1,65 @@
---
prefix: QARUN
inner_loop: true
additional_prefixes: [QARUN-gc]
subagents: []
message_types:
success: tests_passed
failure: tests_failed
coverage: coverage_report
error: error
---
# Test Executor
Run test suites, collect coverage data, and perform automatic fix cycles when tests fail. Implements the execution side of the Generator-Executor (GC) loop.
## Phase 2: Environment Detection
| Input | Source | Required |
|-------|--------|----------|
| Task description | From task subject/description | Yes |
| Session path | Extracted from task description | Yes |
| .msg/meta.json | <session>/wisdom/.msg/meta.json | Yes |
| Test strategy | meta.json -> test_strategy | Yes |
| Generated tests | meta.json -> generated_tests | Yes |
| Target layer | task description `layer: L1/L2/L3` | Yes |
1. Extract session path and target layer from task description
2. Read .msg/meta.json for strategy and generated test file list
3. Detect test command by framework:
| Framework | Command |
|-----------|---------|
| vitest | `npx vitest run --coverage --reporter=json --outputFile=test-results.json` |
| jest | `npx jest --coverage --json --outputFile=test-results.json` |
| pytest | `python -m pytest --cov --cov-report=json -v` |
| mocha | `npx mocha --reporter json > test-results.json` |
| unknown | `npm test -- --coverage` |
4. Get test files from `generated_tests[targetLayer].files`
## Phase 3: Iterative Test-Fix Cycle
**Max iterations**: 5. **Pass threshold**: 95% or all tests pass.
Per iteration:
1. Run test command, capture output
2. Parse results: extract passed/failed counts, parse coverage from output or `coverage/coverage-summary.json`
3. If all pass (0 failures) -> exit loop (success)
4. If pass rate >= 95% and iteration >= 2 -> exit loop (good enough)
5. If iteration >= MAX -> exit loop (report current state)
6. Extract failure details (error lines, assertion failures)
7. Delegate fix to code-developer subagent with constraints:
- ONLY modify test files, NEVER modify source code
- Fix: incorrect assertions, missing imports, wrong mocks, setup issues
- Do NOT: skip tests, add `@ts-ignore`, use `as any`
8. Increment iteration, repeat
## Phase 4: Result Analysis & Output
1. Build result data: layer, framework, iterations, pass_rate, coverage, tests_passed, tests_failed, all_passed
2. Save results to `<session>/results/run-<layer>.json`
3. Save last test output to `<session>/results/output-<layer>.txt`
4. Update `<session>/wisdom/.msg/meta.json` under `execution_results[layer]` and top-level `execution_results.pass_rate`, `execution_results.coverage`
5. Message type: `tests_passed` if all_passed, else `tests_failed`

View File

@@ -0,0 +1,68 @@
---
prefix: QAGEN
inner_loop: false
additional_prefixes: [QAGEN-fix]
subagents: []
message_types:
success: tests_generated
revised: tests_revised
error: error
---
# Test Generator
Generate test code according to strategist's strategy and layers. Support L1 unit tests, L2 integration tests, L3 E2E tests. Follow project's existing test patterns and framework conventions.
## Phase 2: Strategy & Pattern Loading
| Input | Source | Required |
|-------|--------|----------|
| Task description | From task subject/description | Yes |
| Session path | Extracted from task description | Yes |
| .msg/meta.json | <session>/wisdom/.msg/meta.json | Yes |
| Test strategy | meta.json -> test_strategy | Yes |
| Target layer | task description `layer: L1/L2/L3` | Yes |
1. Extract session path and target layer from task description
2. Read .msg/meta.json for test strategy (layers, coverage targets)
3. Determine if this is a GC fix task (subject contains "fix")
4. Load layer config from strategy: level, name, target_coverage, focus_files
5. Learn existing test patterns -- find 3 similar test files via Glob(`**/*.{test,spec}.{ts,tsx,js,jsx}`)
6. Detect test conventions: file location (colocated vs __tests__), import style, describe/it nesting, framework (vitest/jest/pytest)
## Phase 3: Test Code Generation
**Mode selection**:
| Condition | Mode |
|-----------|------|
| GC fix task | Read failure info from `<session>/results/run-<layer>.json`, fix failing tests only |
| <= 3 focus files | Direct: inline Read source -> Write test file |
| > 3 focus files | Batch by module, delegate to code-developer subagent |
**Direct generation flow** (per source file):
1. Read source file content, extract exports
2. Determine test file path following project conventions
3. If test exists -> analyze missing cases -> append new tests via Edit
4. If no test -> generate full test file via Write
5. Include: happy path, edge cases, error cases per export
**GC fix flow**:
1. Read execution results and failure output from results directory
2. Read each failing test file
3. Fix assertions, imports, mocks, or test setup
4. Do NOT modify source code, do NOT skip/ignore tests
**General rules**:
- Follow existing test patterns exactly (imports, naming, structure)
- Target coverage per layer config
- Do NOT use `any` type assertions or `@ts-ignore`
## Phase 4: Self-Validation & Output
1. Collect generated/modified test files
2. Run syntax check (TypeScript: `tsc --noEmit`, or framework-specific)
3. Auto-fix syntax errors (max 3 attempts)
4. Write test metadata to `<session>/wisdom/.msg/meta.json` under `generated_tests[layer]`:
- layer, files list, count, syntax_clean, mode, gc_fix flag
5. Message type: `tests_generated` for new, `tests_revised` for GC fix iterations

View File

@@ -0,0 +1,67 @@
---
prefix: SCOUT
inner_loop: false
subagents: []
message_types:
success: scan_ready
error: error
issues: issues_found
---
# Multi-Perspective Scout
Scan codebase from multiple perspectives (bug, security, test-coverage, code-quality, UX) to discover potential issues. Produce structured scan results with severity-ranked findings.
## Phase 2: Context & Scope Assessment
| Input | Source | Required |
|-------|--------|----------|
| Task description | From task subject/description | Yes |
| Session path | Extracted from task description | Yes |
| .msg/meta.json | <session>/wisdom/.msg/meta.json | No |
1. Extract session path and target scope from task description
2. Determine scan scope: explicit scope from task or `**/*` default
3. Get recent changed files: `git diff --name-only HEAD~5 2>/dev/null || echo ""`
4. Read .msg/meta.json for historical defect patterns (`defect_patterns`)
5. Select scan perspectives based on task description:
- Default: `["bug", "security", "test-coverage", "code-quality"]`
- Add `"ux"` if task mentions UX/UI
6. Assess complexity to determine scan strategy:
| Complexity | Condition | Strategy |
|------------|-----------|----------|
| Low | < 5 changed files, no specific keywords | ACE search + Grep inline |
| Medium | 5-15 files or specific perspective requested | CLI fan-out (3 core perspectives) |
| High | > 15 files or full-project scan | CLI fan-out (all perspectives) |
## Phase 3: Multi-Perspective Scan
**Low complexity**: Use `mcp__ace-tool__search_context` for quick pattern-based scan.
**Medium/High complexity**: CLI fan-out -- one `ccw cli --mode analysis` per perspective:
For each active perspective, build prompt:
```
PURPOSE: Scan code from <perspective> perspective to discover potential issues
TASK: Analyze code patterns for <perspective> problems, identify anti-patterns, check for common issues
MODE: analysis
CONTEXT: @<scan-scope>
EXPECTED: List of findings with severity (critical/high/medium/low), file:line references, description
CONSTRAINTS: Focus on actionable findings only
```
Execute via: `ccw cli -p "<prompt>" --tool gemini --mode analysis`
After all perspectives complete:
- Parse CLI outputs into structured findings
- Deduplicate by file:line (merge perspectives for same location)
- Compare against known defect patterns from .msg/meta.json
- Rank by severity: critical > high > medium > low
## Phase 4: Result Aggregation
1. Build `discoveredIssues` array from critical + high findings (with id, severity, perspective, file, line, description)
2. Write scan results to `<session>/scan/scan-results.json`:
- scan_date, perspectives scanned, total findings, by_severity counts, findings detail, issues_created count
3. Update `<session>/wisdom/.msg/meta.json`: merge `discovered_issues` field
4. Contribute to wisdom/issues.md if new patterns found

View File

@@ -0,0 +1,71 @@
---
prefix: QASTRAT
inner_loop: false
subagents: []
message_types:
success: strategy_ready
error: error
---
# Test Strategist
Analyze change scope, determine test layers (L1-L3), define coverage targets, and generate test strategy document. Create targeted test plans based on scout discoveries and code changes.
## Phase 2: Context & Change Analysis
| Input | Source | Required |
|-------|--------|----------|
| Task description | From task subject/description | Yes |
| Session path | Extracted from task description | Yes |
| .msg/meta.json | <session>/wisdom/.msg/meta.json | Yes |
| Discovered issues | meta.json -> discovered_issues | No |
| Defect patterns | meta.json -> defect_patterns | No |
1. Extract session path from task description
2. Read .msg/meta.json for scout discoveries and historical patterns
3. Analyze change scope: `git diff --name-only HEAD~5`
4. Categorize changed files:
| Category | Pattern |
|----------|---------|
| Source | `\.(ts|tsx|js|jsx|py|java|go|rs)$` |
| Test | `\.(test|spec)\.(ts|tsx|js|jsx)$` or `test_` |
| Config | `\.(json|yaml|yml|toml|env)$` |
5. Detect test framework from package.json / project files
6. Check existing coverage baseline from `coverage/coverage-summary.json`
7. Select analysis mode:
| Total Scope | Mode |
|-------------|------|
| <= 5 files + issues | Direct inline analysis |
| 6-15 | Single CLI analysis |
| > 15 | Multi-dimension CLI analysis |
## Phase 3: Strategy Generation
**Layer Selection Logic**:
| Condition | Layer | Target |
|-----------|-------|--------|
| Has source file changes | L1: Unit Tests | 80% |
| >= 3 source files OR critical issues | L2: Integration Tests | 60% |
| >= 3 critical/high severity issues | L3: E2E Tests | 40% |
| No changes but has scout issues | L1 focused on issue files | 80% |
For CLI-assisted analysis, use:
```
PURPOSE: Analyze code changes and scout findings to determine optimal test strategy
TASK: Classify changed files by risk, map issues to test requirements, identify integration points, recommend test layers with coverage targets
MODE: analysis
```
Build strategy document with: scope analysis, layer configs (level, name, target_coverage, focus_files, rationale), priority issues list.
**Validation**: Verify strategy has layers, targets > 0, covers discovered issues, and framework detected.
## Phase 4: Output & Persistence
1. Write strategy to `<session>/strategy/test-strategy.md`
2. Update `<session>/wisdom/.msg/meta.json`: merge `test_strategy` field with scope, layers, coverage_targets, test_framework
3. Contribute to wisdom/decisions.md with layer selection rationale

View File

@@ -82,7 +82,7 @@ if (mode === 'direct') {
Bash(`ccw cli -p "PURPOSE: Perform deep quality analysis on QA results to identify defect patterns, coverage trends, and improvement opportunities
TASK: • Classify defects by root cause pattern (logic errors, integration issues, missing validation, etc.) • Identify files with highest defect density • Analyze coverage gaps vs risk levels • Compare actual coverage to targets • Generate actionable improvement recommendations
MODE: analysis
CONTEXT: @${sessionFolder}/shared-memory.json @${sessionFolder}/results/**/*
CONTEXT: @${sessionFolder}/.msg/meta.json @${sessionFolder}/results/**/*
EXPECTED: Structured analysis with: defect pattern taxonomy, risk-coverage matrix, quality score rationale, top 5 improvement recommendations with expected impact
CONSTRAINTS: Be data-driven, avoid speculation without evidence" --tool gemini --mode analysis --rule analysis-analyze-code-patterns`, {
run_in_background: true
@@ -277,7 +277,7 @@ sharedMemory.coverage_history.push({
quality_score: analysis.quality_score,
issues: analysis.defect_patterns.total
})
Write(`${sessionFolder}/shared-memory.json`, JSON.stringify(sharedMemory, null, 2))
Write(`${sessionFolder}/.msg/meta.json`, JSON.stringify(sharedMemory, null, 2))
function generateReportMarkdown(analysis) {
return `# Quality Assurance Report

View File

@@ -56,24 +56,21 @@ Quality analyst. Analyze defect patterns, coverage gaps, test effectiveness, and
Before every SendMessage, log via `mcp__ccw-tools__team_msg`:
**NOTE**: `team` must be **session ID** (e.g., `TQA-project-2026-02-27`), NOT team name. Extract from `Session:` field in task description.
```
mcp__ccw-tools__team_msg({
operation: "log",
team: <session-id>, // e.g., "TQA-project-2026-02-27", NOT "quality-assurance"
session_id: <session-id>,
from: "analyst",
to: "coordinator",
type: <message-type>,
summary: "[analyst] quality score: <score>/100, defect patterns: <count>, coverage: <coverage>%",
ref: <report-path>
data: { ref: <report-path> }
})
```
**CLI fallback** (when MCP unavailable):
```
Bash("ccw team log --team <session-id> --from analyst --to coordinator --type <message-type> --summary \"[analyst] analysis complete\" --ref <report-path> --json")
Bash("ccw team log --session-id <session-id> --from analyst --type <message-type> --json")
```
---
@@ -95,7 +92,7 @@ Standard task discovery flow: TaskList -> filter by prefix `QAANA-*` + owner mat
| Input | Source | Required |
|-------|--------|----------|
| Shared memory | <session-folder>/shared-memory.json | Yes |
| Shared memory | <session-folder>/.msg/meta.json | Yes |
| Discovered issues | sharedMemory.discovered_issues | No |
| Test strategy | sharedMemory.test_strategy | No |
| Generated tests | sharedMemory.generated_tests | No |

View File

@@ -2,7 +2,6 @@
> 任务链创建与依赖管理。根据 QA 模式创建 pipeline 任务链并分配给 worker 角色。
**NOTE**: `teamName` variable must be **session ID** (e.g., `TQA-project-2026-02-27`), NOT team name. Extract from `Session:` field in task description.
## When to Use
@@ -114,9 +113,8 @@ const chainValid = chainTasks.length === pipeline.length
if (!chainValid) {
mcp__ccw-tools__team_msg({
operation: "log", team: teamName, from: "coordinator",
operation: "log", session_id: teamName, from: "coordinator",
to: "user", type: "error",
summary: `[coordinator] 任务链创建不完整: ${chainTasks.length}/${pipeline.length}`
})
}
```

View File

@@ -2,7 +2,6 @@
> 阶段驱动的协调循环。按 pipeline 阶段顺序等待 worker 完成,路由消息,触发 GC 循环,执行质量门控。
**NOTE**: `teamName` variable must be **session ID** (e.g., `TQA-project-2026-02-27`), NOT team name. Extract from `Session:` field in task description.
## When to Use
@@ -77,7 +76,7 @@ const autoYes = /\b(-y|--yes)\b/.test(args)
```javascript
// 从 shared memory 获取覆盖率目标
const sharedMemory = JSON.parse(Read(`${sessionFolder}/shared-memory.json`))
const sharedMemory = JSON.parse(Read(`${sessionFolder}/.msg/meta.json`))
const strategy = sharedMemory.test_strategy || {}
const coverageTargets = {}
for (const layer of (strategy.layers || [])) {
@@ -108,9 +107,7 @@ for (const stageTask of pipelineTasks) {
if (!workerConfig) {
mcp__ccw-tools__team_msg({
operation: "log", team: teamName, from: "coordinator",
to: "user", type: "error",
summary: `[coordinator] 未知阶段前缀: ${stagePrefix},跳过`
operation: "log", session_id: teamName, from: "coordinator",
})
continue
}
@@ -119,36 +116,31 @@ for (const stageTask of pipelineTasks) {
TaskUpdate({ taskId: stageTask.id, status: 'in_progress' })
mcp__ccw-tools__team_msg({
operation: "log", team: teamName, from: "coordinator",
operation: "log", session_id: teamName, 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: "general-purpose",
subagent_type: "team-worker",
description: `Spawn ${workerConfig.role} worker for ${stageTask.subject}`,
team_name: teamName,
name: workerConfig.role,
prompt: `你是 team "${teamName}" 的 ${workerConfig.role.toUpperCase()}
prompt: `## Role Assignment
role: ${workerConfig.role}
role_spec: .claude/skills/team-quality-assurance/role-specs/${workerConfig.role}.md
session: ${sessionFolder}
session_id: ${sessionId}
team_name: ${teamName}
requirement: ${stageTask.description || taskDescription}
inner_loop: false
## ⚠️ 首要指令MUST
Skill(skill="team-quality-assurance", args="${workerConfig.skillArgs}")
## Current Task
- Task ID: ${stageTask.id}
- Task: ${stageTask.subject}
## 当前任务
- 任务 ID: ${stageTask.id}
- 任务: ${stageTask.subject}
- 描述: ${stageTask.description || taskDescription}
- Session: ${sessionFolder}
## 角色准则(强制)
- 所有输出必须带 [${workerConfig.role}] 标识前缀
- 仅与 coordinator 通信
## 工作流程
1. Skill(skill="team-quality-assurance", args="${workerConfig.skillArgs}") 获取角色定义
2. 执行任务 → 汇报结果
3. TaskUpdate({ taskId: "${stageTask.id}", status: "completed" })`,
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
})
@@ -159,9 +151,8 @@ Skill(skill="team-quality-assurance", args="${workerConfig.skillArgs}")
// Worker 返回但未标记 completed → 异常处理
if (autoYes) {
mcp__ccw-tools__team_msg({
operation: "log", team: teamName, from: "coordinator",
to: "user", type: "error",
summary: `[coordinator] [auto] 阶段 ${stageTask.subject} 未完成,自动跳过`
operation: "log", session_id: teamName, from: "coordinator",
type: "error",
})
TaskUpdate({ taskId: stageTask.id, status: 'deleted' })
continue
@@ -186,24 +177,21 @@ Skill(skill="team-quality-assurance", args="${workerConfig.skillArgs}")
continue
} else if (answer === "终止") {
mcp__ccw-tools__team_msg({
operation: "log", team: teamName, from: "coordinator",
operation: "log", session_id: teamName, from: "coordinator",
to: "user", type: "shutdown",
summary: `[coordinator] 用户终止流水线,当前阶段: ${stageTask.subject}`
})
break
}
// 重试: continue to next iteration will re-process if logic wraps
} else {
mcp__ccw-tools__team_msg({
operation: "log", team: teamName, from: "coordinator",
to: "user", type: "quality_gate",
summary: `[coordinator] 阶段完成: ${stageTask.subject}`
operation: "log", session_id: teamName, from: "coordinator",
})
}
// 5. 阶段间检查QARUN 阶段检查覆盖率,决定 GC 循环)
if (stagePrefix === 'QARUN') {
const latestMemory = JSON.parse(Read(`${sessionFolder}/shared-memory.json`))
const latestMemory = JSON.parse(Read(`${sessionFolder}/.msg/meta.json`))
const coverage = latestMemory.execution_results?.coverage || 0
const targetLayer = stageTask.metadata?.layer || 'L1'
const target = coverageTargets[targetLayer] || 80
@@ -211,9 +199,8 @@ Skill(skill="team-quality-assurance", args="${workerConfig.skillArgs}")
if (coverage < target && gcIteration < MAX_GC_ITERATIONS) {
gcIteration++
mcp__ccw-tools__team_msg({
operation: "log", team: teamName, from: "coordinator",
operation: "log", session_id: teamName, from: "coordinator",
to: "generator", type: "gc_loop_trigger",
summary: `[coordinator] GC循环 #${gcIteration}: 覆盖率 ${coverage}% < ${target}%,请修复`
})
// 创建 GC 修复任务追加到 pipeline
}
@@ -247,16 +234,15 @@ function processMessage(msg, handler) {
case 'quality_gate': {
// 重新读取最新 shared memory
const latestMemory = JSON.parse(Read(`${sessionFolder}/shared-memory.json`))
const latestMemory = JSON.parse(Read(`${sessionFolder}/.msg/meta.json`))
const qualityScore = latestMemory.quality_score || 0
let status = 'PASS'
if (qualityScore < 60) status = 'FAIL'
else if (qualityScore < 80) status = 'CONDITIONAL'
mcp__ccw-tools__team_msg({
operation: "log", team: teamName, from: "coordinator",
operation: "log", session_id: teamName, from: "coordinator",
to: "user", type: "quality_gate",
summary: `[coordinator] 质量门控: ${status} (score: ${qualityScore})`
})
break
}
@@ -266,7 +252,6 @@ function processMessage(msg, handler) {
if (severity === 'critical') {
SendMessage({
content: `## [coordinator] Critical Error from ${msg.from}\n\n${msg.summary}`,
summary: `[coordinator] Critical error: ${msg.summary}`
})
}
break
@@ -278,17 +263,13 @@ function handleGCDecision(coverage, targetLayer) {
if (gcIteration < MAX_GC_ITERATIONS) {
gcIteration++
mcp__ccw-tools__team_msg({
operation: "log", team: teamName, from: "coordinator",
to: "generator", type: "gc_loop_trigger",
summary: `[coordinator] GC循环 #${gcIteration}: 覆盖率 ${coverage}% 未达标,请修复`,
operation: "log", session_id: teamName, from: "coordinator",
data: { iteration: gcIteration, layer: targetLayer, coverage }
})
// 创建 GC 修复任务(参见 dispatch.md createGCLoopTasks
} else {
mcp__ccw-tools__team_msg({
operation: "log", team: teamName, from: "coordinator",
to: "user", type: "quality_gate",
summary: `[coordinator] GC循环已达上限(${MAX_GC_ITERATIONS}),接受当前覆盖率 ${coverage}%`
operation: "log", session_id: teamName, from: "coordinator",
})
}
}
@@ -298,7 +279,7 @@ function handleGCDecision(coverage, targetLayer) {
```javascript
// 汇总所有结果
const finalSharedMemory = JSON.parse(Read(`${sessionFolder}/shared-memory.json`))
const finalSharedMemory = JSON.parse(Read(`${sessionFolder}/.msg/meta.json`))
const allFinalTasks = TaskList()
const workerTasks = allFinalTasks.filter(t => t.owner && t.owner !== 'coordinator')
const summary = {

View File

@@ -26,18 +26,56 @@ Orchestrate the Quality Assurance workflow: requirement clarification, mode sele
---
## Command Execution Protocol
When coordinator needs to execute a command (dispatch, monitor):
1. **Read the command file**: `roles/coordinator/commands/<command-name>.md`
2. **Follow the workflow** defined in the command file (Phase 2-4 structure)
3. **Commands are inline execution guides** -- NOT separate agents or subprocesses
4. **Execute synchronously** -- complete the command workflow before proceeding
Example:
```
Phase 3 needs task dispatch
-> Read roles/coordinator/commands/dispatch.md
-> Execute Phase 2 (Context Loading)
-> Execute Phase 3 (Task Chain Creation)
-> Execute Phase 4 (Validation)
-> Continue to Phase 4
```
---
## Entry Router
When coordinator is invoked, first detect the invocation type:
When coordinator is invoked, detect invocation type:
| Detection | Condition | Handler |
|-----------|-----------|---------|
| Worker callback | Message contains `[role-name]` tag from a known worker role | -> handleCallback: auto-advance pipeline |
| Status check | Arguments contain "check" or "status" | -> handleCheck: output execution graph, no advancement |
| Manual resume | Arguments contain "resume" or "continue" | -> handleResume: check worker states, advance pipeline |
| New session | None of the above | -> Phase 0 (Session Resume Check) |
| Worker callback | Message contains role tag [scout], [strategist], [generator], [executor], [analyst] | -> handleCallback |
| Status check | Arguments contain "check" or "status" | -> handleCheck |
| Manual resume | Arguments contain "resume" or "continue" | -> handleResume |
| Pipeline complete | All tasks have status "completed" | -> handleComplete |
| Interrupted session | Active/paused session exists | -> Phase 0 (Session Resume Check) |
| New session | None of above | -> Phase 1 |
For callback/check/resume: load `commands/monitor.md` and execute the appropriate handler, then STOP.
For callback/check/resume/complete: load `commands/monitor.md` and execute matched handler, then STOP.
### Router Implementation
1. **Load session context** (if exists):
- Scan `.workflow/.team/QA-*/.msg/meta.json` for active/paused sessions
- If found, extract session folder path, status, and pipeline mode
2. **Parse $ARGUMENTS** for detection keywords:
- Check for role name tags in message content
- Check for "check", "status", "resume", "continue" keywords
3. **Route to handler**:
- For monitor handlers: Read `commands/monitor.md`, execute matched handler, STOP
- For Phase 0: Execute Session Resume Check below
- For Phase 1: Execute Requirement Clarification below
---
@@ -101,7 +139,7 @@ For callback/check/resume: load `commands/monitor.md` and execute the appropriat
1. Generate session ID
2. Create session folder
3. Call TeamCreate with team name
4. Initialize shared-memory.json with empty fields
4. Initialize .msg/meta.json with empty fields
5. Initialize wisdom directory (learnings.md, decisions.md, conventions.md, issues.md)
6. Write session file with: session_id, mode, scope, status="active"

View File

@@ -183,7 +183,7 @@ sharedMemory.execution_results = sharedMemory.execution_results || {}
sharedMemory.execution_results[targetLayer] = resultData
sharedMemory.execution_results.pass_rate = passRate
sharedMemory.execution_results.coverage = coverage
Write(`${sessionFolder}/shared-memory.json`, JSON.stringify(sharedMemory, null, 2))
Write(`${sessionFolder}/.msg/meta.json`, JSON.stringify(sharedMemory, null, 2))
```
## Output Format

View File

@@ -57,25 +57,21 @@ Test executor. Run test suites, collect coverage data, and perform automatic fix
Before every SendMessage, log via `mcp__ccw-tools__team_msg`:
**NOTE**: `team` must be **session ID** (e.g., `TQA-project-2026-02-27`), NOT team name. Extract from `Session:` field in task description.
```
mcp__ccw-tools__team_msg({
operation: "log",
team: <session-id>, // e.g., "TQA-project-2026-02-27", NOT "quality-assurance"
session_id: <session-id>,
from: "executor",
to: "coordinator",
type: <message-type>,
summary: "[executor] <layer>: <status-message>",
ref: <results-file>,
data: { pass_rate, coverage, iterations }
data: { ref: <results-file>, pass_rate, coverage, iterations }
})
```
**CLI fallback** (when MCP unavailable):
```
Bash("ccw team log --team <session-id> --from executor --to coordinator --type <message-type> --summary \"[executor] test execution complete\" --ref <results-file> --json")
Bash("ccw team log --session-id <session-id> --from executor --type <message-type> --json")
```
---
@@ -99,7 +95,7 @@ For parallel instances, parse `--agent-name` from arguments for owner matching.
| Input | Source | Required |
|-------|--------|----------|
| Shared memory | <session-folder>/shared-memory.json | Yes |
| Shared memory | <session-folder>/.msg/meta.json | Yes |
| Test strategy | sharedMemory.test_strategy | Yes |
| Generated tests | sharedMemory.generated_tests | Yes |
| Target layer | task description | Yes |

View File

@@ -228,7 +228,7 @@ const testInfo = {
sharedMemory.generated_tests = sharedMemory.generated_tests || {}
sharedMemory.generated_tests[targetLayer] = testInfo
Write(`${sessionFolder}/shared-memory.json`, JSON.stringify(sharedMemory, null, 2))
Write(`${sessionFolder}/.msg/meta.json`, JSON.stringify(sharedMemory, null, 2))
```
## Output Format

View File

@@ -57,24 +57,21 @@ Test case generator. Generate test code according to strategist's strategy and l
Before every SendMessage, log via `mcp__ccw-tools__team_msg`:
**NOTE**: `team` must be **session ID** (e.g., `TQA-project-2026-02-27`), NOT team name. Extract from `Session:` field in task description.
```
mcp__ccw-tools__team_msg({
operation: "log",
team: <session-id>, // e.g., "TQA-project-2026-02-27", NOT "quality-assurance"
session_id: <session-id>,
from: "generator",
to: "coordinator",
type: <message-type>,
summary: "[generator] <layer> test generation complete: <file-count> files",
ref: <first-test-file>
data: { ref: <first-test-file> }
})
```
**CLI fallback** (when MCP unavailable):
```
Bash("ccw team log --team <session-id> --from generator --to coordinator --type <message-type> --summary \"[generator] test generation complete\" --ref <test-file> --json")
Bash("ccw team log --session-id <session-id> --from generator --type <message-type> --json")
```
---
@@ -98,7 +95,7 @@ For parallel instances, parse `--agent-name` from arguments for owner matching.
| Input | Source | Required |
|-------|--------|----------|
| Shared memory | <session-folder>/shared-memory.json | Yes |
| Shared memory | <session-folder>/.msg/meta.json | Yes |
| Test strategy | sharedMemory.test_strategy | Yes |
| Target layer | task description or strategy.layers[0] | Yes |

View File

@@ -86,7 +86,7 @@ const changedFiles = Bash(`git diff --name-only HEAD~5 2>/dev/null || echo ""`)
// 读取 shared memory 获取历史缺陷模式
const sessionFolder = task.description.match(/session:\s*(.+)/)?.[1] || '.'
let sharedMemory = {}
try { sharedMemory = JSON.parse(Read(`${sessionFolder}/shared-memory.json`)) } catch {}
try { sharedMemory = JSON.parse(Read(`${sessionFolder}/.msg/meta.json`)) } catch {}
const knownPatterns = sharedMemory.defect_patterns || []
// 确定扫描视角
@@ -164,7 +164,7 @@ const discoveredIssues = allFindings.critical
// 更新 shared memory
sharedMemory.discovered_issues = discoveredIssues
Write(`${sessionFolder}/shared-memory.json`, JSON.stringify(sharedMemory, null, 2))
Write(`${sessionFolder}/.msg/meta.json`, JSON.stringify(sharedMemory, null, 2))
// 保存扫描结果
Write(`${sessionFolder}/scan/scan-results.json`, JSON.stringify({
@@ -189,12 +189,10 @@ const resultSummary = `发现 ${discoveredIssues.length} 个问题Critical: $
mcp__ccw-tools__team_msg({
operation: "log",
team: teamName,
session_id: teamName,
from: "scout",
to: "coordinator",
type: discoveredIssues.length > 0 ? "issues_found" : "scan_ready",
summary: `[scout] ${resultSummary}`,
ref: `${sessionFolder}/scan/scan-results.json`
data: { ref: `${sessionFolder}/scan/scan-results.json` }
})
SendMessage({

View File

@@ -55,24 +55,21 @@ Test strategist. Analyze change scope, determine test layers (L1-L3), define cov
Before every SendMessage, log via `mcp__ccw-tools__team_msg`:
**NOTE**: `team` must be **session ID** (e.g., `TQA-project-2026-02-27`), NOT team name. Extract from `Session:` field in task description.
```
mcp__ccw-tools__team_msg({
operation: "log",
team: <session-id>, // e.g., "TQA-project-2026-02-27", NOT "quality-assurance"
session_id: <session-id>,
from: "strategist",
to: "coordinator",
type: <message-type>,
summary: "[strategist] QASTRAT complete: <layers-summary>",
ref: <artifact-path>
data: { ref: <artifact-path> }
})
```
**CLI fallback** (when MCP unavailable):
```
Bash("ccw team log --team <session-id> --from strategist --to coordinator --type <message-type> --summary \"[strategist] QASTRAT complete\" --ref <artifact-path> --json")
Bash("ccw team log --session-id <session-id> --from strategist --type <message-type> --json")
```
---
@@ -94,7 +91,7 @@ Standard task discovery flow: TaskList -> filter by prefix `QASTRAT-*` + owner m
| Input | Source | Required |
|-------|--------|----------|
| Shared memory | <session-folder>/shared-memory.json | Yes |
| Shared memory | <session-folder>/.msg/meta.json | Yes |
| Discovered issues | sharedMemory.discovered_issues | No |
| Defect patterns | sharedMemory.defect_patterns | No |